(一)建表规约
1、表达是与否概念的字段,必须使用is_xxx的方式命名,数据类型是unsigned tinyint( 1表示是,0表示否)。
说明:任何字段如果为非负数,必须是unsigned
。
2、表名、字段名必须使用小写字母或数字,禁止出现数字开头,禁止两个下划线中间只出现数字。数据库字段名的修改代价很大,因为无法进行预发布,所以字段名称需要慎重考虑。
3、表名不使用复数名词。
4、禁用保留字,如desc
、range
、match
、delayed
等,请参考MySQL官方保留字。
5、主键索引名为pk字段名;唯一索引名为uk字段名;普通索引名则为idx字段名。
6、小数类型为decimal,禁止使用float和double。
7、如果存储的字符串长度几乎相等,使用char定长字符串类型。
8、varchar是可变长字符串,不预先分配存储空间,长度不要超过5000,如果存储长度大于此值,定义字段类型为text,独立出来一张表,用主键来对应,避免影响其它字段索引效率。
9、表必备三字段:id, gmt_create, gmt_modified。
说明:其中id必为主键,类型为unsigned bigint、单表时自增、步长为1。gmt_create, gmt_modified的类型均为datetime类型,前者现在时表示主动创建,后者过去分词表示被动更新。
10、表的命名最好是加上“业务名称_表的作用”。
11、库名与应用名称尽量一致。
12、如果修改字段含义或对字段表示的状态追加时,需要及时更新字段注释。
(二)索引规约
1、业务上具有唯一特性的字段,即使是多个字段的组合,也必须建成唯一索引。
说明:不要以为唯一索引影响了insert速度,这个速度损耗可以忽略,但提高查找速度是明显的;另外,即使在应用层做了非常完善的校验控制,只要没有唯一索引,根据墨菲定律,必然有脏数据产生。
2、超过三个表禁止join。需要join的字段,数据类型必须绝对一致;多表关联查询时,保证被关联的字段需要有索引。
3、在varchar字段上建立索引时,必须指定索引长度,没必要对全字段建立索引,根据实际文本区分度决定索引长度即可。
4、页面搜索严禁左模糊或者全模糊,如果需要请走搜索引擎来解决。
5、如果有order by的场景,请注意利用索引的有序性。order by 最后的字段是组合索引的一部分,并且放在索引组合顺序的最后,避免出现file_sort的情况,影响查询性能。
正例:where a=? and b=? order by c; 索引:a_b_c
反例:索引中有范围查找,那么索引有序性无法利用,如:WHERE a>10 ORDER BY b; 索引a_b无法排序。
(三)SQL语句
1、不要使用count(列名)或count(常量)来替代count(),count()是SQL92定义的标准统计行数的语法,跟数据库无关,跟NULL和非NULL无关。
2、count(distinct col) 计算该列除NULL之外的不重复行数,注意 count(distinct col1, col2) 如果其中一列全为NULL,那么即使另一列有不同的值,也返回为0。
3、当某一列的值全是NULL时,count(col)的返回结果为0,但sum(col)的返回结果为NULL,因此使用sum()时需注意NPE问题。
4、使用ISNULL()
来判断是否为NULL值。 说明:NULL与任何值的直接比较都为NULL。
1) NULL<>NULL
的返回结果是NULL,而不是false
。
2) NULL=NULL
的返回结果是NULL,而不是true
。
3) NULL<>1
的返回结果是NULL,而不是true
。
5、在代码中写分页查询逻辑时,若count为0应直接返回,避免执行后面的分页语句。
6、不得使用外键与级联,一切外键概念必须在应用层解决。
7、禁止使用存储过程,存储过程难以调试和扩展,更没有移植性。
8、数据订正(特别是删除、修改记录操作)时,要先select,避免出现误删除,确认无误才能执行更新语句。
9、in操作能避免则避免,若实在避免不了,需要仔细评估in后边的集合元素数量,控制在1000个之内。