1、数据库基本设计规范
(1)所有表必须使用InnoDB存储引擎。
(2)数据库和表的字符编码统一使用UTF-8。
(3)所有表和字段都需要添加注释。
(4)尽量控制单表数据量的大小,建议控制在500万以内。可以用历史数据归档、分库分表等手段来控制数据量大小。
(5)谨慎使用MySQL分区表。分区表在物理上表现为多个文件,在逻辑上表现为一个表,谨慎使用分区表,跨分区查询效率可能会更低。
(6)经常一起使用的列放到一个表中。避免更多的关联操作。
(7)禁止在表中建立预留字段。
(8)禁止在数据库中存储文件(例如图片)这类大的二进制数据。
(9)不要被数据库范式所束缚。三范式,第一范式保证每一列的原子性,第二范式保证一张表只描述一件事情,第三范式保证每一列都和主键直接相关。有时为了提高查询效率,会降低范式的要求,在表中保存一定的冗余信息,也叫做反范式。
(10)禁止在线上做数据库压力测试。
(11)禁止从开发环境,测试环境直接连接生产环境数据库。
2、数据库字段设计规范
(1)优先选择符合存储需要的最小的数据类型。存储字节越小,占用空间越小,性能越好。数字是连续的,占用空间越小,性能越好。例如,将IP地址转换成整型数据来存储,对于非负型的数据来说要优先使用无符号整型来存储,小数值类型优先使用TINYINT类型。
(2)避免使用TEXT、BLOB数据类型。
(3)避免使用ENUM类型。
(4)尽可能把所有列定义为NOTNULL。索引NULL列需要额外的空间来保存,进行比较和计算时要对NULL值做特别的处理。
(5)使用TIMESTAMP或DATETIME类型存储时间。
(6)同财务相关的金额类数据必须使用decimal类型。decimal类型为精准浮点数,在计算时不会丢失精度。
(7)单表不要包含过多字段。
3、索引设计规范
(1)限制每张表上的索引数量,建议单张表索引不超过5个。
(2)禁止使用全文索引。
(3)禁止给表中的每一列都建立单独的索引。
(4)每个InnoDB表必须有个主键。在InnoDB中,表都是根据主键顺序组织存放的,这种存储方式的表成为索引组织表。
(5)常见索引列建议:1)出现在SELECT、UPDATE、DELETE语句的WHERE从句中的列;2)包含在ORDERBY、GROUPBY、DISTINCT中的字段;3)并不需要将符合1)、2)中的字段的列都建立一个索引,通常将1)、2)中的字段建立联合索引效果更好,联合索引是建立在多个字段上的索引;4)多表join的关联列。
(6)如何选择索引列的顺序:1)区分度最高的放在联合索引的最左侧(区分度=列中不同值的数量/列的总行数);2)尽量把字段长度小的列放在联合索引的最左侧(因为字段长度越小,一页能存储的数据量越大,IO性能也就越好);3)使用最频繁的列放到联合索引的左侧(这样可以比较少的建立一些索引)。
(7)避免建立冗余索引和重复索引,例如,重复索引primarykey(id)、index(id)、uniqueindex(id),冗余索引index(a,b,c)、index(a,b)、index(a)。
(8)对于频繁的查询优先考虑使用覆盖索引。覆盖索引即需要查询的字段正好是索引的字段,那么直接根据该索引,就可以查到数据了,而无需回表查询。覆盖索引是一种数据查询方式,不是索引类型。
(8)尽量避免使用外键约束。
4、数据库SQL开发规范
(1)优化对性能影响较大的SQL语句。通过查询MySQL的慢查询日志来发现需要进行优化的SQL语句。
(2)充分利用表上已经存在的索引。避免使用双%号的查询条件。一个SQL只能利用到复合索引中的一列进行范围查询,例如,有a、b、c列的联合索引,在查询条件中有a列的范围查询,则在b、c列上的索引将不会被用到。在定义联合索引时,如果a列要用到范围查找的话,就要把a列放到联合索引的右侧,使用leftjoin或notexists来优化notin操作,因为notin也通常会使用索引失效。
(3)禁止使用SELECT*必须使用SELECT<字段列表>查询。
(4)禁止使用不含字段列表的INSERT语句。
(5)建议使用预编译语句进行数据库操作。一次编译、多次运行,省去了解析优化等过程,此外预编译语句能防止sql注入。
(6)避免数据类型的隐式转换。隐式转换会导致索引失效。
(7)避免使用子查询,可以把子查询优化为join操作。
(8)避免使用JOIN关联太多的表。
(9)减少同数据库的交互次数。
(10)对应同一列进行or判断时,使用in代替or。
(11)禁止使用orderbyrand()进行随机排序。
(12)WHERE从句中禁止对列进行函数转换和计算。
(13)在明显不会有重复值时使用UNIONALL而不是UNION。
(14)拆分复杂的大SQL为多个小SQL。
(15)程序连接不同的数据库使用不同的账号,禁止跨库查询。