每一个好习惯都是一笔财富,本文分SQL规范优雅、 SQL性能优化和SQL后悔药三个方向,分享写SQL的21个好习惯,谢谢阅读,加油哈~
这个好习惯一定要养成啦,设计数据库表的时候,所有表和字段都添加相应的注释,后面更容易维护。
反例:
CREATE TABLE `account` ( `id` INT ( 11 ) NOT NULL AUTO_INCREMENT, `name` VARCHAR ( 255 ) DEFAULT NULL, `balance` INT ( 11 ) DEFAULT NULL, `create_time` datetime NOT NULL, `update_time` datetime NOT NULL ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY ( `id` ), KEY `idx_name` ( `name` ) USING BTREE ) ENGINE = INNODB AUTO_INCREMENT = 1570068 DEFAULT CHARSET = utf8;
正例:
CREATE TABLE `account` ( `id` INT ( 11 ) NOT NULL AUTO_INCREMENT COMMENT ‘主键Id‘, `name` VARCHAR ( 255 ) DEFAULT NULL COMMENT ‘账户名‘, `balance` INT ( 11 ) DEFAULT NULL COMMENT ‘余额‘, `create_time` datetime NOT NULL COMMENT ‘创建时间‘, `update_time` datetime NOT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT ‘更新时间‘, PRIMARY KEY ( `id` ), KEY `idx_name` ( `name` ) USING BTREE ) ENGINE = INNODB AUTO_INCREMENT = 1570068 DEFAULT CHARSET = utf8 ROW_FORMAT = REDUNDANT COMMENT = ‘账户表‘;
反例:
SELECT stu.name, sum(stu.score) from Student stu WHERE stu.classNo = ‘1班‘ group by stu.name;
正例:
SELECT stu.`name`, sum(stu.`score`) FROM Student stu WHERE stu.`classNo` = ‘1班‘ GROUP BY stu.`name`
显然,统一关键字大小写一致,使用缩进对齐,会使你的SQL看起来更优雅~
反例:
INSERT INTO Student VALUES ( ‘666‘, ‘捡田螺的小男孩‘, ‘100‘ );
正例:
INSERT INTO Student ( `id`, `name`, `score` ) VALUES ( ‘666‘, ‘捡田螺的小男孩‘, ‘100‘ );
反例:
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=‘账户表‘;
正例:
CREATE TABLE `account` ( `id` INT ( 11 ) NOT NULL AUTO_INCREMENT COMMENT ‘主键Id‘, `name` VARCHAR ( 255 ) DEFAULT NULL COMMENT ‘账户名‘, `balance` INT ( 11 ) DEFAULT NULL COMMENT ‘余额‘, `create_time` datetime NOT NULL COMMENT ‘创建时间‘, `update_time` datetime NOT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT ‘更新时间‘, PRIMARY KEY ( `id` ), KEY `idx_name` ( `name` ) USING BTREE ) ENGINE = INNODB AUTO_INCREMENT = 1570068 DEFAULT CHARSET = utf8 ROW_FORMAT = REDUNDANT COMMENT = ‘账户表‘;
理由:
阿里开发手册也提到这个点,如图
Innodb 【支持事务,支持行级锁,更好的恢复性】,高并发下性能更好,所以呢,没有特殊要求(即Innodb无法满足的功能如:列存储,存储空间数据等)的情况下,所有表必须使用Innodb存储引擎
尽量统一使用UTF8编码
如果需要存储表情,那么选择utf8mb4来进行存储,注意它与utf-8编码的区别。
这个点,是阿里开发手册中,Mysql的规约。你的字段,尤其是表示枚举状态时,如果含义被修改了,或者状态追加时,为了后面更好维护,需要即时更新字段的注释。
说明:pk_即primary key;uk_即unique key;idx_即index 的简称。
假设loginTime加了索引
反例:
SELECT userId, loginTime FROM loginuser WHERE Date_ADD( loginTime, INTERVAL 7 DAY ) >= now( );
正例:
EXPLAIN SELECT userId, loginTime FROM loginuser WHERE loginTime >= Date_ADD( NOW( ), INTERVAL - 7 DAY );
理由:
日常开发写SQL的时候,尽量养成这个好习惯呀:写完SQL后,用explain分析一下,尤其注意走不走索引。
EXPLAIN SELECT `id`, `name`, `age` FROM `user` WHERE `id` = 10086OR `age` = 18;
反例:
select * from user where address =‘深圳‘ order by age;
正例:
#添加索引
alter table user add index idx_address_age (address,age)
反例:
# userid 是varchar字符串类型 select * from user where userid =123;
正例:
select * from user where userid =‘123‘;
理由:
因为不加单引号时,是字符串跟数字的比较,它们类型不匹配,MySQL会做隐式的类型转换,把它们转换为浮点数再做比较,最后导致索引失效
反例:
select * from employee;
正例:
select id,name from employee;
理由:
应用:
我们可以用varchar存放不定长的数据,比如人的名字,或者一篇博客的文章。
可以用char存放定长的数据,比如身份证号和手机号,我们把一个列定义为mobile varchar(11)
,中国大陆的手机号最长,达到11位,香港是8位,瑞士是10位,所以定义成11位完全够用,可以存放各国的手机号了。
附加:
除了char和varchar类型,最常用的就是数值类型了,为了方便建表的时候计算列的最大长度,把数值类型占用的字节和值的范围放在这里:
反例:
DELETE FROM account LIMIT 100000;
正例:
FOR EACH ( 200 ) { DELETE FROM account LIMIT 500; }
理由:
在执行删除或者更新语句,尽量加上limit,以下面的这条 SQL 为例吧:
DELETE FROM euser WHERE age > 30 LIMIT 200;
因为加了limit 主要有这些好处:
如果要修改或删除数据,在执行SQL前一定要先备份要修改的数据,万一误操作,还能吃口「后悔药」~
尤其在操作生产的数据时,遇到修改或者删除的SQL,先加个where查询一下,确认OK之后,再执行update或者delete操作
反例:
UPDATE account SET balance = 1000000 WHERE NAME = ‘法哈席基‘;
正例:
BEGIN; UPDATE account SET balance = 1000000 WHERE NAME = ‘法哈席基‘; COMMIT;
来源:捡田螺的小男孩
作者:捡田螺的小男孩
原文:https://www.cnblogs.com/JiHC/p/14138508.html