1. 表里必须要有create_time(datetime) , update_time (datetime) , expired (tinyint) 字段.
2. 表名、字段名必须使用小写字母,可以使用数字结尾 禁止数显数字开头.
3. 禁用保留字,如 desc、range、match、delayed等,请参考 MySQL官方保留字
4. 唯一索引名为 uk_字段名;普通索引名则为 idx_字段名。
5. 小数类型为 decimal,禁止使用 float和 double。
说明:float和 double在存储的时候,存在精度损失的问题,很可能在值的比较时,得到不正确的结果。如果存储的数据范围超过 decimal的范围,建议将数据拆成整数和小数分开存储。
6. varchar是可变长字符串,不预先分配存储空间,长度不要超过 5000,如果存储长度大于此值,定义字段类型为 text,独立出来一张表,用主键来对应,避免影响其它字段索引效率。
7. 库名与应用名称尽量一致,表名尽量和POJO名字一致或保持某种规范
8. 能分库尽量不要分表,业务表在5千万内尽量不考虑分表
9. 业务上具有唯一特性的字段,即使是组合字段,也必须建成唯一索引。不要以为唯一索引影响了 insert速度,这个速度损耗可以忽略,但提高查找速度是明显的
10. 禁止使用表关联,如果需要尽量采用in的方式或修改表结构完成
11. 禁止在sql的where语句后面使用函数,在select条件里酌情考虑使用
12. update 语句多考虑where语句后面的条件是否走索引,否则容易产生锁表操作
13. like 语句可以使用,但只允许使用想做匹配 如 name like 'd%'
14. 如果有 order by的场景,请注意利用索引的有序性。order by 最后的字段是组合索引的一部分,并且放在索引组合顺序的最后
正例:where a=? and b=? order by c; 索引:a_b_c
反例:索引中有范围查找,那么索引有序性无法利用,如:WHERE a>10 ORDER BY b; 索引a_b无法排序。
15 SQL性能优化的目标:至少要达到 range 级别,要求是 ref级别,如果可以是 consts最好。
说明:
1)consts 单表中最多只有一个匹配行(主键或者唯一索引),在优化阶段即可读取到数据。
2)ref 指的是使用普通的索引(normal index)。
3)range 对索引进行范围检索。
反例:explain表的结果,type=index,索引物理文件全扫描,速度非常慢,这个 index级别比较 range还低,与全表扫描是小巫见大巫。
16 建组合索引的时候,区分度最高的在最左边。
正例:如果 where a=? and b=? ,a列的几乎接近于唯一值,那么只需要单建 idx_a索引即可。
说明:存在非等号和等号混合判断条件时,在建索引时,请把等号条件的列前置。如:where a>?and b=? 那么即使 a的区分度更高,也必须把 b放在索引的最前列。
17. 10.【参考】创建索引时避免有如下极端误解:
1)误认为一个查询就需要建一个索引。
2)误认为索引会消耗空间、严重拖慢更新和新增速度。
3)误认为唯一索引一律需要在应用层通过“先查后插”方式解决。
18. 数据库字段尽量不要出现null
19. 不要使用 count(列名)或 count(常量)来替代 count(*),count(*)就是 SQL92定义的标准统计行数的语法,跟数据库无关,跟 NULL和非 NULL无关。
说明:count(*)会统计值为 NULL的行,而 count(列名)不会统计此列为 NULL值的行。