02 表结构优化

Yishto 2018-03-23 18:26:32
Categories: Tags:
  1. 数字类型 : 非万不得已不要使用 DOUBLE , 不仅仅是存储长度的问题 , 同时还会存在精确性的问题 . 同样 , 固定精度的小数 , 也不建议使用 DECIMAL , 乘以固定背书转化成整数存储 , 可以大大节省存储空间 , 且不会带来任何附加维护成本 . 对于整数的存储 , 在数据量较大的情况下 , 建议区分开 TINYINT / INT / BIGINT 的选择 , 因为三者所占得存储空间也有很大的差别 , 能确定不会使用附属的字段 , 建议添加 unsigined 定义 . 当然 , 如果数据量较小的数据库 , 也可以不用严格区分三个整数类型 .
  2. 字符串类型 : 非万不得已不要使用 TEXT 数据类型 , 其处理方式决定了他的性能要低于 char 或者 varchar 数据的处理 . 定长字段 , 建议使用 CHAR 类型 , 不定长字段尽量使用 VARCHAR ,且仅仅设定适当的最大长度 , 而不是非常随意的给一个很大的最大长度限定 , 因为不同的长度范伟 , MySQL 也会有不一样的存储处理 .
  3. 时间类型 : 尽量使用 TIMESTAMP 类型, 因为其存储空间只需要 DTETIME 类型的一半 , 对于只需要精确到某一天的数据类型 , 建议使用DATE类型 , 因为他的存储空间只需要3个字节 , 比 TIMESTAMP 还少 . 不建议通过 INT 类型存储一个 unix timestam 的值 , 因为这不太只管 , 也给维护带来不必要的麻烦 , 同时还不会带来任何好处 .
  4. ENUM & SET :对于状态字段 , 可以尝试使用ENUM 来存放 , 因为可以极大的降低存储空间 , 而且即使需要增加新的类型 , 只要增加于末尾 , 修改结构也不需要重建表数据 . 如果是存放可预先定义的属性数据呢 ? 可以尝试使用 SET 类型 , 即使存在多种属性 , 同样可以游刃有余 , 同时还可以节省不小的存储空间 .
  5. LOB 类型 : 强烈反对在数据库中存放LOB类型数据 , 虽然数据库提供了这样的功能 , 但这不是他擅长的 , 我们更应该让合适的工具做他擅长的事情 , 才能将其发挥到极致 . 在数据库中存储 LOB 数据就像让一个多年前在学校学过一点 Java 的营销专业的人员来写Java 代码一样 .
    字符编码
  1. 纯拉丁字符能表示的内容 , 没有必要选择 latin1 之外的其他字符编码 , 因为这回节约大量的存储空间 .
  2. 如果我们可以确定不需要存放多种语言 , 就没必要非得使用UTF8或者其他UNICODE 字符类型 , 这会造成大量的  
    的存储空间浪费 .
  3. MySQL的数据类型可以精确到字段 , 所以当我们需要大型数据库中存放多字节数据的时候 , 可以通过不同表不同字段使用不同的数据类型来较大程度减小数据存储量 , 进而降低 IO 操作次数并提高缓存的命中率 .
    适当拆分
    有些时候 , 我们可能会希望将一个完整的对象对应于一张数据库表 , 这对于应用程序开发来说是很好的 , 但是有些时候可能会在性能上带来较大的问题 .
    当我们的表中存在类似于 TEXT 或者是很大的 VARCHA 类型的大字段的时候 , 如果我们大部分访问的这张表的时候都不需要这个字段 , 我们该义无反顾的将其拆分到另外的独立表中 , 以减少常用数据所占用的存储空间 . 这样做的一个明显的好处就是每个数据块中可以存储的数据条数可以大大增加 , 既减少物理 IO 次数 , 也能大大提高内存中的缓存命中率 .
  1. 被频繁引用且只能通过 Join 2张(或者更多) 大表的方式才能得到的独立小字段 .
  2. 这样的场景由于每次 Join 仅仅只是为了取得某个小字段值 , Join 到的记录又大 , 会造成大量不必要的 IO , 完全可以通过空间换取时间的方式来优化 . 不过 , 冗余的同时需要确保数据的一致性不会遭到破坏 , 确保更新的同时冗余字段也被更新 .
    尽量使用 NOT NULL
    NULL 类型比较特殊 , SQL 难优化. 虽然 MySQL NULL 类型和 Oracle 的 NULL 有差异 , 会进入索引中 , 但如果是一个组合索引 , name这个 NULL 类型的字段会极大影响整个索引的效率 . 此外 , NULL 在索引中的处理也是特殊的 ,也会占用额外的存放空间 .
    很多人觉得 NULL 会节省一些空间 , 所以尽量让NULL 来达到节省 IO 的目的 , 但是大部分时候这会适得其反 , 虽然空间上可能确实有一定节省 , 到时带来了很多其他的优化问题 ,不但没有将 IO 量节省下来 , 反而加大了 SQL 的 IO 量 . 所以尽量确保 DEFAULT 值不是 NULL 也是一个很好的表结构设计优化习惯 .