MySQL 数据库规约

记录一下数据库使用过程中需要注意的一些规范以及我对这些规约的理解。

在我的理解中,表的基础是ER模型,这是业务数据模型的映射,后续的各种规约都是在这个基础上出于各种技术考量进行的迭代。

未特意指出,默认使用innoDB引擎。

原则

  1. 见名知意,减少理解成本。

  2. 硬盘IO越少越快、数据量越少越快,二次处理越少越快(如排序,分组,函数,表达式)

  3. 没有银弹

建表规约

  1. 表名/字段名不区分大小写。(减少因大小写带来的歧义。)

  2. 存储的字符串若长度相等,则使用char定长类型。(减少用于记录长度的空间)

  3. 若长度过大,若超过5000,应转为text类型,另起一张表,主键关联过去。(一个叶子为一页,固定16KB,长度过大意味空间更大。会导致两种情况,每一页存储更少记录,或者每条记录索引到一个额外的空间用于存储过大字段。第一种情况,会导致每次索引到的数据更少,增加IO次数;第二种情况,会导致需单独去读取这个字段,也会增加IO次数。)

  4. 表必备三字段:id, create_time, update_time。id字段为自增id,步长为1.(自增id用于防止裂页)

  5. 表命名遵循"业务名称_表"(通过名字就能知道该表是属于什么模块或服务)

  6. 表与字段都应有注释(减少理解歧义)

  7. 字段允许适当冗余,以提高性能,部分过于复杂或耗时长,且不是频繁修改的字段的查询,可以用单独一张表承载,通过定时任务,将执行查询,更新该表。此处应考虑到数据一致性问题。

  8. 命名不要使用非公认的缩写。

  9. 时间字段类型 timestamp,只存储时间,时间显示格式不应数据库考虑。

索引规约

  1. 业务上具备唯一性的字段/组合字段,应创建唯一索引,避免脏数据的产生。

  2. 不应为可为null的字段建立唯一索引(在MySQL的设计中,null不是一个值,也因此会让唯一索引失效。比如 a、b、c字段值为1、2、null可以重复插入,而不会受到唯一索引的限制)

  3. 禁止过多jion(阿里的规约中限制超过三个)。(过多的join,在笛卡尔积的作用,不需要大量的数据也可能将硬盘空间耗光。而且由于临时表存在硬盘中,相对纯粹使用缓存区的查询,性能要差很多。)

  4. 对于字符串字段,如果需要创建索引,则因使用前缀索引。(这即引入的一定的区分度,每一页可索引记录更多,减少了IO次数,也避免了对硬盘带来太大的负担)

  5. 基数过少的字段没必要创建索引,徒增维护成本(基数为字段值去重后的数量)

  6. 优先为查询频繁的条件创建索引,优先创建覆盖索引,能不回表则不回表。

  7. 组合索引遵循最左匹配查询,创建索引应综合考虑字段的查询频率,区分度,有序性

  8. 有order by场景,注意使用索引的有序性。

  9. 避免滥用索引,当出现增删改操作时,索引是需要维护的。

SQL语句规范

应综合考虑索引,IO次数,字段类型,数据量各方面。

  1. select 应只查询需要的字段(能减少硬盘与网络IO传输的数据量。)

  2. 禁止使用外键和级联。(使用外键和级联减少了应用层的灵活性,而且当后续需要分库分表时会产生严重的阻碍。)

  3. 禁止使用存储过程。(存储过程难以应用现代软件工程的各种手段(封装,抽象,隔离,分层,结构化),会导致后续难以维护,可拓展性和可读性也不足。)

  4. 在join联表中,因尽量使用索引字段进行作为条件。

  5. where 语句

  6. 当使用or时,若两端字段非同索引字段,则索引会失效,导致遍历。

  7. 索引遵循最左匹配原则,则字符串左模糊匹配和全模糊匹配会另索引失效。

  8. 条件中使用函数会使索引失效。

  9. 避免使用表达式查询,这会让引擎直接全表扫描。

  10. 当使用不等、不在、不是这些语义的条件逻辑符号时,很可能引擎会直接开始全表扫描,慎用。

  11. 使用order by语句,如可能则尽量沿用索引的顺序,减少排序的性能开销。更甚者,由于数据库排序性能开销很大,可将排序置于应用层进行。

  12. 数据库中敏感信息,如密码,不应明文存储,避免不幸被脱库带来的影响。

  13. 由于MySQL limit n,m 的使用原理是先将前页的数据一并查出再舍弃前页数据。这带来了大量的性能浪费,这时建议基于上一页末尾记录主键id进行定位,再查询所需数量记录(where id = x limit m)。这也是现在app使用下拉刷新进行分页的原因。

  14. 尽量在应用层执行单表查询,再对执行结果二次处理。数据库的资源是宝贵的,而数据库提供的是有状态服务,扩容不易。

  15. 若多个sql语句中混入增删改操作时,务必使用事务,很可能避免了你提桶跑路。

  16. SQL也应注重可读性。

Last Updated: