『十倍程序员』写SQL的好习惯

193 阅读3分钟

「这是我参与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 事务的习惯