建表规范
- 表达是与否概念的字段,必须使用is_xxx的方式命名,数据类型是unsigned tinyint(1表示是,0表示否)。POJO中的Boolean类型的变量,都不要加is前缀,所以需要指定is_xxx和xxx的映射关系。
- 表名、字段名必须使用小写字母或数字、禁止出现数字开头,禁止两个下划线中间只出现数字。数据库字段名的修改代价比较大,因为无法进行预发布,所以字段名称必须慎重考虑。
- 表名不使用复数名词。
- 禁止使用保留字作为表名、字段名。
- 主键索引名为pk_字段名;唯一索引名为uk_字段名;普通索引名则为idx_字段名;
- 如果存储的字符串长度几乎相等,使用char定长字符串类型。
- varchar是可变长字符串,不预先分配存储空间,长度不要超过5000,如果存储长度大于此值,定义字段类型为text,独立出来一张表,用主键来对应,避免影响其它字段索引效率。
- 表(中间表除外)必备三个字段:id, created_time, updated_time。
索引规范
- 业务上具有唯一特性的字段,即使是组合字段,也必须建成唯一索引。
- 超过三个表禁止join。需要join的字段,数据类型保持绝对一致;多表关联查询时,保证被关联的字段需要有索引。
- 在varchar字段上建立索引时,必须指定索引长度,没必要对全字段建立索引,根据实际文本区分度决定索引长度。
SQL语句
- 不要使用count(列名)或count(常量)来替代count(),count()是SQL92定义的标准统计行数的语法,跟数据库无关,跟NULL和非NULL无关。
- count(distinct col) 计算该列除NULL之外的不重复行数,注意count(distinct col1, col2) 如果其中一列全为NULL,那么即使另一列有不同的值,也返回为0。
- 当某一列的值全是NULL时,count(col)的返回结果为0,但sum(col)的返回结果为NULL,因此使用sum()时需注意NPE问题。eg: 可以使用如下方式来避免sum的NPE问题:SELECT IFNULL(SUM(column), 0) FROM table;
- 使用ISNULL()来判断是否为NULL值。
- 代码中写分页查询逻辑时,若count为0应直接返回,避免执行后面的分页语句。
- 不得使用外键与级联,一切外键概念必须在应用层解决。
- 禁止使用存储过程,存储过程难以调试和扩展,更没有移植性。
- 数据订正(特别是删除或修改记录操作)时,要先select,避免出现误删除,确认无误才能执行更新语句。
- 对于数据库中表记录的查询和变更,只要涉及多个表,都需要在列名前加表的别名(或表名)进行限定。
ORM映射
- 在表查询中,一律不要使用* 作为查询的字段列表,需要哪些字段必须明确写明。
- POJO类的布尔属性不能加is,而数据库字段必须加is_,要求在resultMap中进行字段与属性之间的映射。
- 不要用resultClass当返回参数,即使所有类属性名与数据库字段一一对应,也需要定义<resultMap>;反过来,每一个表也必然有一个<resultMap>与之对应。
- sql.xml配置参数使用:#{},#param# 不要使用${} 此种方式容易出现SQL注入。
- 不允许直接拿HashMap与Hashtable作为查询结果集的输出。
- 更新数据表记录时,必须同时更新记录对应的update_time字段值为当前时间。
- 所有的SQL语句不能在代码中体现,必须写在xxxMapper.xml。