- 选择优化的数据类型
- 基本原则:
- 更小的通常更好——一般情况下,应该尽量使用可以正确存储数据的最小数据类型。
- 简单就好——简单数据类型的操作通常需要更少的CPU周期。
- 尽量避免NULL——因为对可为NULL的列做索引优化比较复杂。即使需要存储一个真正的“空值”,也可以使用0、""或其他特殊值代替。但不能走极端,该用NULL的时候坚决用NULL。
- 数据类型(略)
- 基本原则:
- MySQL Schema设计中的陷阱
- 太多的列——MySQL的存储引擎API工作时,需要在服务器层和存储引擎层之间通过行缓冲格式拷贝数据,然后在服务器层将缓冲内容解码成各个列。从行缓冲中将编码过的列转换成行数据结构的操作代价是非常高的。
- 太多的关联——“实体—属性—值”(EAV)设计模式是一个常见的糟糕的设计模式。MySQL限制了每个关联操作最多只能有61张表,而EAV数据库需要很多自关联。经验表明,如果希望查询执行得快且并发性好,单个查询最好在12个表以内做关联。
- 全能的枚举——注意防止过度使用枚举(ENUM)。例如:CREATE TABLE ... ( country enum('', '1', '2', '3', ..., '20'));
- 变相的枚举——枚举(ENUM)列允许在列中存储一组定义值中的单个值,集合(SET)则允许在列中存储存储一组定义值中的一个或多个值。
- 范式化与反范式
- 范式化的优缺点:
- 范式化的更新操作比反范式化要快;
- 当数据较好的范式化时,就只有很少或没有重复数据,所以只需要修改更少的数据;
- 范式化的表通常更小,可以更好的放到内存里,所以操作更快;
- 很少有多余的数据意味着检索列表数据时更少需要DISTINCT或者GROUP BY语句;
- 范式化设计的schema的缺点是通常需要关联。
- 反范式的优缺点:
- 反范式化的schema因为所有数据都在一张表中,可以很好的避免关联。当数据比内存大时,这可能比关联要快得多,因为避免了随机I/O;
- 缺点:可能出现较多的数据冗余。
- 混用范式化和反范式化——完全的范式化和完全的反范式化都只存在于实验室里,在真实场景中很少存在这样极端的使用。
- 常见的反范式化数据——复制或缓存,在不同的表中存储相同的特定列;
- 为了排序的需要,从父表冗余一些数据到子表。例如:在范式化的schema设计中通过author_name对messages排序的代价非常高,此时可以在message表中缓存author_name字段,并建立索引,这样排序会非常高效;
- 缓存衍生值。例如:需要显示每个用户发了多少条消息,你可以每次执行一个昂贵的子查询来统计显示它,也可以在user表中新增一个字段num_messages,每当用户发布消息时更新这个字段。
- 范式化的优缺点:
- 缓存表和汇总表(未完待续)
- 有时候提升性能的最好方式是在同一张表中保存衍生的冗余数据。而有时也需要创建一张独立的汇总表或缓存表。
- 加快ALTER TABLE的速度