unsigned tinyint
( 1 表示是,0 表示否)。说明:任何字段如果为非负数,必须是unsigned。
正例:表达逻辑删除的字段名 is_deleted,1 表示删除,0 表示未删除。
2. 表名、字段名必须使用小写字母或数字,禁止出现数字开头,禁止两个下划线中间只出现数字。
数据库字段名的修改代价很大,因为无法进行预发布,所以字段名称需要慎重考虑。
说明:MySQL 在 Windows 下不区分大小写,但在 Linux 下默认是区分大小写。因此,数据库名、表名、字段名,都不允许出现任何大写字母,避免节外生枝。
正例:aliyun_admin,rdc_config,level3_name
反例:AliyunAdmin,rdcConfig,level_3_name
4. 表名不使用复数名词。
说明:表名应该仅仅表示表里面的实体内容,不应该表示实体数量,对应于 DO 类名也是单数形式,符合表达习惯。
desc、range、match、delayed
等,请参考 MySQL 官方保留字。primary key
;uk_ 即 unique key
;idx_ 即 index 的简称。decimal
,禁止使用 float 和 double。说明:float 和 double 在存储的时候,存在精度损失的问题,很可能在值的比较时,得到不 正确的结果。如果存储的数据范围超过decimal 的范围,建议将数据拆成整数和小数分开存储。
varchar
是可变长字符串,不预先分配存储空间,长度不要超过 5000,如果存储长度大于此值,定义字段类型为 text,独立出来一张表,用主键来对应,避免影响其它字段索引效率。id, gmt_create, gmt_modified
说明:其中 id 必为主键,类型为
unsigned bigint、
单表时自增、步长为 1。gmt_create, gmt_modified
的类型均为 date_time 类型,前者现在时表示主动创建,后者过去分词表示被 动更新
说明:不要以为唯一索引影响了 insert 速度,这个速度损耗可以忽略,但提高查找速度是明显的;另外,即使在应用层做了非常完善的校验控制,只要没有唯一索引,根据墨菲定律,必然有脏数据产生。
说明:即使双表 join 也要注意表索引、SQL 性能。
说明:索引的长度与区分度是一对矛盾体,一般对字符串类型数据,长度为 20 的索引,区分度会高达 90%以上,可以使用
count(distinct left(列名, 索引长度))/count(*)
的区分度来确定。
说明:索引文件具有 B-Tree 的最左前缀匹配特性,如果左边的值未确定,那么无法使用此索引。
order by
的场景,请注意利用索引的有序性。order by 最后的字段是组合索引的一部分,并且放在索引组合顺序的最后,避免出现 file_sort 的情况,影响查询性能。正例:where a=? and b=? order by c; 索引:a_b_c
反例:索引中有范围查找,那么索引有序性无法利用,如:WHERE a>10 ORDER BY b; 索引a_b 无法排序。
ount(列名)或 count(常量)
来替代 count(*),count(*)
是 SQL92 定义的标准统计行数的语法,跟数据库无关,跟 NULL 和非 NULL 无关。说明:count(*)会统计值为 NULL 的行,而 count(列名)不会统计此列为 NULL 值的行。
SELECT IF(ISNULL(SUM(g)),0,SUM(g)) FROM table;
说明:NULL 与任何值的直接比较都为 NULL。
1) NULL<>NULL 的返回结果是 NULL,而不是 false。
2) NULL=NULL 的返回结果是 NULL,而不是 true。
3) NULL<>1 的返回结果是 NULL,而不是 true。
说明:以学生和成绩的关系为例,学生表中的 student_id是主键,那么成绩表中的 student_id则为外键。如果更新学生表中的 student_id,同时触发成绩表中的 student_id 更新,即为级联更新。外键与级联更新适用于单机低并发,不适合分布式、高并发集群;级联更新是强阻塞,存在数据库更新风暴的风险;外键影响数据库的插入速度。
说明:
1)增加查询分析器解析成本。
2)增减字段容易与 resultMap 配置不一致。
resultClass
当返回参数,即使所有类属性名与数据库字段一一对应,也需要定义;反过来,每一个表也必然有一个与之对应。queryForList(String statementName,int start,int size)
不推荐使用。说明:其实现方式是在数据库取到statementName对应的SQL语句的所有记录,再通过subList 取 start,size的子集合。
正例:
Map map = new HashMap();
map.put("start", start);
map.put("size", size);
不允许直接拿 HashMap 与 Hashtable 作为查询结果集的输出。
说明:resultClass=”Hashtable”,会置入字段名和属性值,但是值的类型不可控。
更新数据表记录时,必须同时更新记录对应的 gmt_modified 字段值为当前时间。