MySQL DBA必读:万字归总表设计与SQL编写技巧( 四 )


LIST 分区:类似于按RANGE分区,区别在于LIST分区是基于列值匹配一个离散值集合中的某个值来进行选择 。列值分区与范围分区有类似之处,该分区与范围分区类似的是需要指定列的值,但是其分区值必须明确指定 。
HASH分区:基于用户定义的表达式的返回值来进行选择的分区,该表达式使用将要插入到表中的这些行的列值进行计算 。这个函数可以包含MySQL中有效的、产生非负整数值的任何表达式 。此种分区方式最适用于查询条件中,对分区字段进行单值查询的情况(如,col=1) 。但是hash分区,并不适用于对索引字段使用范围查询,如对字段使用大于>,小于<,操作的查询语句中 。
KEY分区:类似于按HASH分区,区别在于KEY分区只支持计算一列或多列,且MySQL服务器提供其自身的哈希函数 。必须有一列或多列包含整数值 。
复合分区:基于RANGE/LIST 类型的分区表中每个分区的再次分割 。子分区可以是 HASH/KEY 等类型 。
5、表字段规范

  • 尽量使用TINYINT、SMALLINT、MEDIUM_INT作为整数类型而非INT,如果非负则加上UNSIGNED;
  • VARCHAR的长度只分配真正需要的空间;
  • 使用枚举或整数代替字符串类型;
  • 尽量使用TIMESTAMP而非DATETIME;
  • 单表不要有太多字段,建议在20以内;
  • 避免使用字段,很难查询优化且占用额外索引空间;
  • 用整型来存IP 。
6、统一字符集
系统、服务端、客户端、库、表、开发程序端需统一字符集,通常中英文环境用utf8 。
表使用建议
根据MySQL的表建立规范,以及在实际维护中的表使用经验相结合,对表使用作出如下的建议 。
1、选择合适的数据类型
InnoDB 存储引擎和数据列 。建议使用 varchar类型:对于InnoDB数据表,内部的行存储格式没有区分固定长度和可变长度列(所有数据行都使用指向数据列值的头指针),因此在本质上,使用固定长度的 char列不一定比使用可变长度varchar列简单 。因而,主要的性能因素是数据行使用的存储总量 。由于CHAR平均占用的空间多于varchar,因此使用varchar来最小化需要处理的数据行的存储总量和磁盘I/O是比较好的 。
2、text和blob
在使用text和blob字段类型时要注意以下几点,以便更好的发挥数据库的性能:
1)text和blob值在执行了大量的删除或更新操作的时候容易影响效率 。
删除该类型值会在数据表中留下很大的"空洞",以后填入这些"空洞"的记录可能长度不同,为了提高性能,建议定期使用 OPTIMIZE TABLE 功能对这类表进行碎片整理 。
2)使用合成的(synthetic)索引 。
合成的索引列在某些时候是有用的 。一种办法是根据其它的列的内容建立一个散列值,并把这个值存储在单独的数据列中 。之后可以通过检索散列值找到数据 。但是,这种索引只能用于精确匹配的查询(散列值对于类似<或>=等范围搜索操作符 是没有用处的) 。可以使用MD5函数生成散列值,也可以使用SHA1或CRC32,或者使用自己的应用程序逻辑来计算散列值 。需注意数值型散列值可以很高效率地存储 。同样,如果散列算法生成的字符串带有尾部空格,此时不要把它们存储在char与varchar列中,它们会受到尾部空格去除的影响 。合成的散列索引对于那些text和blob数据列特别有用 。用散列标识符值查找的速度比搜索blob列本身的速度快很多 。
3)把text或blob列分离到单独的表中 。
通过把这些数据列移动到单独的数据表中,可以让你把原数据表中的数据列转换为固定长度的数据行格式 。这会减少主表中的碎片,使你得到固定长度数据行的性能优势 。此时能避免在主数据表上运行 SELECT *查询的时候通过网络传输大量的text或blob值 。
3、拆分大字段、访问频率低的字段
将大字段、访问频率低的字段拆分到单独的表中存储,分离冷热数据 。有利于有效利用缓存,防止读入无用的冷数据,较少磁盘IO,同时保证热数据常驻内存提高缓存命中率 。
4、数据文件磁盘分离
MySQL表以数据文件形式存储于文件系统,针对不同的表的读写会打开不同的数据文件 。建议对不同的热表进行存储的磁盘分离 。通过将不同的热表建立在不同的lun上,分散I/O,这样就能进一步减少I/O消耗的瓶颈 。
索引建立规范
建立合适的索引,是提高数据库运行效率的一个很好的工具,这种效果是立竿见影的,但这里也不并不是说表上的索引越多越好,过之而不及 。在数据库设计过程中,需要为表选择一些合适的索引 。在数据库中索引的维护代价是表的3倍,宁缺勿滥,这是建立索引时的一个遵循标准 。


推荐阅读