“数据库”指南|养成写sql的一些好习惯(MySQL)

大家在项目中都会遇到sql的书写或者sql的分析。或多或少都会感叹到:“这写的什么sql太坑了吧、一点注释都没有字段具体什么意思呢、这大小写也不保持一致,看着也太乱了吧”......
接下来和大家分享一下,我平时写sql的一些好习惯。本文分三个维度来讲解。
01、规范优雅

  • 设计表的时候,所有表和字段都要添加相应的注释。
很多人有会有疑问了,所有都添加注释,那多麻烦,没有必要吧。
大家来看一下没有加注释的表结构:
“数据库”指南|养成写sql的一些好习惯(MySQL)
文章图片

我们是不是只能根据字段表面意思来推测可能是什么,不能清晰明确的知道该表和字段的具体解析呢。
我们再来看一下加了注释的:
“数据库”指南|养成写sql的一些好习惯(MySQL)
文章图片
有了注释之后,我们梳理业务是不是更迅速了呢,表的数据结构是不是更清晰了呢,这个表的业务场景是不是更深入了解了呢。大家一定要让自己养成创建表结构添加对应的注销!
  • 创建时表结构大小写保持一致,书写时关键字大小写保持一致,使用缩进。
大家先看一下创建表时的正例:
“数据库”指南|养成写sql的一些好习惯(MySQL)
文章图片

大家再看一下创建表时的反例:
“数据库”指南|养成写sql的一些好习惯(MySQL)
文章图片

显然,创建表时大小写一致看起来更加美观,清晰!
大家先看一下sql书写时,关键字大小写保持一致的正例:
SELECT students.name, sum(students.score) FROM students WHERE students.class_no = '3班' GROUP BY students.name

大家再看一下sql书写时,关键字大小写保持一致的反例:
SELECT students.name, sum(students.score) from studentsWHERE students.class_no = '3班' group by students.name.

大家是不是很明显可以看到优势,统一关键字大小写一致,使用缩进对齐,会使我们的sql看起来更优雅,清晰!
  • 设计表结构的时候,加上三个字段:主键、created_at、updated_at。
我们先来看一下反例:
CREATE TABLE `account` ( `name` varchar(255) DEFAULT NULL COMMENT '账户名', `balance` int(11) DEFAULT NULL COMMENT '余额', ) ENGINE=InnoDB AUTO_INCREMENT=1570068 DEFAULT CHARSET=utf8 ROW_FORMAT=REDUNDANT COMMENT='账户表';

我们再来看一下正例:
“数据库”指南|养成写sql的一些好习惯(MySQL)
文章图片

我们设计的原因是:主键一般都要加上,没有主键的表结构是没有灵魂的。创建时间和更新时间建议加上,跟踪数据记录,审核数据变更都是有用的。阿里云开发手册也提到这点:
“数据库”指南|养成写sql的一些好习惯(MySQL)
文章图片

  • 尽量把所有列定义为NOT NULL 。
NOT NULL列更节省空间,NULL列需要一个额外字节做完判断是否为NULL的标志位。
NULL列需要注意空指针问题,NULL列在做计算和比较的时候,需要注意空指针的问题。
02、避免出现后悔药
  • 操作delete或者update语句,加上个limit 批量进行。
项目中大家都会有修复数据的场景,我们一定要加个limit,有以下原因:
  • 降低写错的代价。 我们在命令行执行sql的时候,如果不加limit,执行的时候一个不仔细,可能数据全删掉。但如果删错的话!加了limit 30,就不一样了。删错也只是丢失30条数据,可以通过binlog日志快速恢复的。
  • 提高执行效率。你在sql语句中,加了limit 1,如果第一条就命中之间返回目标。 没有limit的话,还会继续扫描表。
  • 数据量大的话,容易把CPU打满。如果数据量很大时,不加 limit限制一下记录数,很容易把cpu打满,导致越来越慢的。
  • 避免了长事务。执行语句时,如果遇到索引,MySQL会将所有相关的行加写锁和间隙锁,所有执行相关行会被锁住。并且数量很大时可能会之间影响其他业务的使用。
  • 修复数据时,养成begin + commit 事务。
我们看一下正例:
begin; update user_balance_histories set balance =333 where user_id =3; commit;

我们再来看一下反例:
update user_balance_histories set balance =333 where user_id =3;

  • 变更sql先在开发和测试环境执行后,并写明详细的操作步骤以及回滚方案,生产环境前review。
先在开发和测试环境测试,避免直接语法错误就放到生产上了。需要写明详细操作步骤,尤. 其有依赖关系的时候,如:先修改表结构再补充对应的数据。要有回滚方案,并在上生产前更要review。
03、性能优化
  • where后面的字段,留意其数据类型的隐式转换。
我们来看一下正例:
select * from user where user_id ='3';

“数据库”指南|养成写sql的一些好习惯(MySQL)
文章图片

我们再来看一下反例:
//user_id 是varchar字符串类型 select * from user where user_id =3;

【“数据库”指南|养成写sql的一些好习惯(MySQL)】“数据库”指南|养成写sql的一些好习惯(MySQL)
文章图片
因为:不加单引号时,是字符串跟数字的比较,它们类型不匹配,MySQL会做隐式的类型转换,把它们转换为浮点数再做比较,最后导致索引失效。
  • 减少不必要的字段返回,如使用select <具体字段> 代替 select *。
我们来看一下正例:
select user_id, name from users;

我们再来看一下反例:
select * from users;

因为:节省资源、减少网络开销。可能用到覆盖索引,减少回表,提高查询效率。
  • 尽量使用varchar代替 char。
  • word varchar (255),

  • 因为变长字段存储空间小,可以节省存储空间。
  • 写完sql先explain查看执行计划。
日常开发写完SQL后,习惯用explain分析一下,尤其注意是否扫描索引还是全表。
每一个好习惯都是一笔不可或缺的财富。希望对大家有所帮助!谢谢支持。

    推荐阅读