一、基础规范
(1)创建数据库时,请提供数据库名,字符集并以邮件形式向DBA发起建库申请。库名与应用名称尽量一致,默认使用UTF8字符集(对表情有要求的用 utf8mb4)。
(2)数据表、数据字段必须加入中文注释
(3)禁止使用存储过程、视图、触发器、Event ;禁止存储大文件或者大图片 。
(4)库名、表名、字段名:小写,下划线风格,不超过32个字符,必须见名知意,禁止拼音英文混用。
(5)表名t_xxx,主键索引名为 pk_字段名;唯一索引名为 uk_字段名;普通索引名则为 idx_字段名。
二、表设计规范
(6) 程序中的数据删除必须使用逻辑删除,使用 is_delete的方式命名,数据类型是unsigned tinyint; 【直接物理删除,在发生用户误操作时,恢复比较困难】
(7) 表必须有主键, 建议类型为 unsigned bigint、单表时自增; 如有特殊需求,请在建表时反馈。【注意uuid 作为主键在做onlineddl 时容易阻塞主线程】
(8) 禁止使用外键,如果有外键完整性约束,需要应用程序控制【外键与级联更新不适合高并发场景,降低插入性能,大并发下容易产生死锁】
三、字段设计规范
(9) 新表必须把字段定义为NOT NULL并且提供默认值。【1.NULL浪费存储空间,因为InnoDB需要有额外一个字节存储 2.表内默认值Null过多会影响优化器选择执行计划】
(10) varchar是可变长字符串,不预先分配存储空间,长度不要超过5000,如果存储长度大于此值,定义字段类型为 text,独立出来一张表,用主键来对应,避免影响其它字段索引效率。 同时,尽量避免据库中使用 text/blob 来存储大段文本。
(11)字段类型为时间的,建议使用datetime,不要使用timestamp;如果存储的字符串长度几乎相等,使用 char定长字符串类型。
(12)小数类型为decimal,尽可能避免使用 float 和 double类型,防止精度失准。小数类型的推荐使用顺序: decimal,float,double
(13) 字段类型在满足需求条件下越小越好, 字段如果为非负数,必须是 unsigned;
四、索引设计规范
(14)单表的索引数建议不超过 15个,单个索引中的字段数建议不超过 5个,索引设计遵循B+ Tree索引最左前缀匹配原则。
(15)避免冗余索引,两个索引(a,b) (a)同时存在,则(a)属于冗余索引;但业务上具有唯一特性的字段,即使是多个字段的组合,也必须建成唯一索引。
(16)建复合索引的时候,区分度最高的列放索引的在最左边, 例如select xxx where a = x and b = x; a 和 b 一起建组合索引,a 的区分度更高,则建idx_ab(a,b)
(17)禁止在更新十分频繁、区分度不高的属性上建立索引;记录更新会变更 B+树,更新频繁的字段建立索引会大大降低数据库性能。
(18)合理利用覆盖索引来降低 io 开销,在 InnoDB中二级索引的叶子节点保存的只保存本身的键值和主键值,若一个 SQL 查询的不是索引列或者主键,走这个索引就会先找到对应主键然后根据主键去找需要找的列,这就是回表,这样会带来额外的 io开销。
(19)在 varchar长度超过50的字段上建立索引时,必须指定索引长度,没必要对全字段建立索引,根据实际文本区分度决定索引长度即可。
【说明:索引的长度与区分度是一对矛盾体,一般对字符串类型数据,长度为 20的索引,区分度会高达90%以上,可以使用count(distinct left(列名, 索引长度))/count(*)的区分度】
(20)如果有 order by的场景,请注意利用索引的有序性。order by最后的字段是组合索引的一部分,并且放在索引组合顺序的最后,避免出现 file_sort的情况,影响查询性能。正例:where a=? and b=? order by c;索引:a_b_c?
五、SQL使用规范
(21)按需索取,拒绝使用SELECT *,只获取必要的字段,需要显示说明列属性。
(22)禁止使用属性隐式转换,如索引 a 的类型是 varchar,SQL 语句写成 where a = 1;varchar 变成了int。
(23)尽量避免在WHERE条件的符号左边使用函数或者数学计算。
(24)禁止负向查询(NOT、!=、<>、!<、!>、NOT IN、NOT LIKE),以及%开头的模糊查询
(25)少用多表 join,大表禁止 join,两张表 join 必须让小表做驱动表,join列必须字符集一致并且都建有索引。
(26)尽量避免使用大事务,建议大事务拆小事务,规避主从延迟;业务代码中事务及时提交,避免产生没必要的锁等待。
(27) 禁止使用INSERT INTO t_xxx VALUES(xxx),必须显示指定插入的列属性,避免表结构变动导致数据出错
(28) in操作能避免则避免,若实在避免不了,需要仔细评估 in后边的集合元素数量,控制在 1000个之内。