「这是我参与11月更文挑战的第8天,活动详情查看:2021最后一次更文挑战」。
前言
数据是一个项目的重中之重,好的SQL开发习惯能帮助我们在日常开发工作中达到事半功倍的效果,增加执行器效率,减少慢SQL,因此我们应当不懈的追求代码精进,培养好的开发习惯。
SQL规范
- 设计表的时候,所有表和字段都添加相应的
注释
- SQL书写格式,关键字大小保持一致,使用缩进
- INSERT语句标明对应的字段名称
- 设计数据库表的时候,加上以下个字段(字段名可自定义):主键,create_time,update_time,delete_flag
- 尽量把所有列定义为
NOT NULL
并提供默认值 - 所有表必须使用
Innodb
存储引擎 - 数据库和表的字符集尽量统一使用utf8/
utf8mb4
- 如果修改字段含义或对字段表示的状态追加时,需要及时更新字段注释
- 索引命名要规范,主键索引名为 pk_字段名;唯一索引名为 uk_字段名;普通索引为 idx_字段名
禁止使用外键
,如果有外键完整性约束,由应用程序控制
索引规范
- 避免在更新比较频繁、区分度不高的列上单独建立索引
- 需要JOIN的字段,数据类型必须绝对一致; 多表关联查询时,保证被关联的字段需要有索引
- 建立联合索引时,必须将区分度更高的字段放在左边
- 在一个联合索引中,若第一列索引区分度等于1,那么则不需要建立联合索引
- 利用
覆盖索引
来进行查询操作,避免回表
SQL性能优化
- 写完SQL先
explain
查看执行计划 - 写完SQL语句,检查where,order by,group by后面的列,多表关联的列是否已加索引,优先考虑联合索引
- where后面的字段,留意其数据类型的隐式转换
- 尽量使用varchar代替char,如果存储的字符串长度几乎相等,则使用char定长字符串类型
- 减少不必要的字段返回,如使用select <具体字段> 代替 select *
- where从句中不对列进行函数转换和表达式计算
- 如果修改/更新数据过多,考虑批量进行
- 在一些场景下,考虑使用
timestamp
代替datetime - 不使用%开头的模糊查询
- 尽量避免在WHERE子句中使用or作为连接条件
- JOIN的表不允许超过五个(阿里开发手册规定不允许超过三个)
- 不分页的集合查询应规定查询数量的上限,避免全量查询导致OOM
SQL后悔药
- 操作delete或者update语句,加个
limit
- 变更SQL操作先在测试环境执行,写明详细的操作步骤以及回滚方案,并在上生产前review
- 修改或删除重要数据前,要先备份,先备份,先备份
- 修改或者删除SQL,先写WHERE查一下,确认后再补充 delete 或 update
- SQL命令行修改数据,养成
begin + commit
事务的习惯