解读阿里巴巴开发规范之MySQL

devopsec 等级 707 0 0

前言

从7月份毕业开始算起,也是将近有5个月的工作经验了吧。在工作上,经历了一段时间的适应,现在接触到不同大神写出来的代码,发现各有优劣,于是就在思考一个问题,什么样的代码才是最正常最规范的呢?我的同事甩给我了一本《阿里巴巴Java开发手册》,从头到尾也算是过了一遍。今天趁着双休的假期,我就来讲一下这本书里面的MySQL规范制约吧~

阿里巴巴开发规范之MySQL

建表规约

1、【强制】每张表必须设置一个主键ID,并且这个主键ID要自增(在满足需要的情况下尽量短),除非是分库分表

理解:由于InnoDB存储引擎决定了需要有一个主键,而且这个主键ID是自增的话可以有效提高插入的性能,避免过多的页分裂,减少表碎片提高空间的利用率。

但是在分库分表下,会有分片规则,这个时候需要统一分配各个表中的主键值,从而避免整个逻辑表中主键重复,一般我们会使用雪花ID来实现。

2、【强制】必须使用utf8mb4字符集

理解:在MySQL中的UTF-8并非是真正的"UTF-8",而utf8mb4才是真正的"UTF-8"。

3、【强制】数据库表、表字段必须加入中文注释

理解:程序员都不要给我懒,这样可以让后来者更好的上手和理解。

4、【强制】库名、表名、字段名必须小写,下划线风格,不超过32个字符,必须见名知意,禁止拼音英文混用

理解:在linux环境下MySQL是区分大小写的,而在windows是不区分大小写的,所以统一使用小写+下划线可以避免不必要的混淆。

5、【强制】单表列数目必须小于30,若超过则应该考虑将表拆分

理解:单表列数太多会使得MySQL处理InnoDB返回数据之间的映射成本太高。

6、【强制】禁止使用外键,如果有外键完整性约束,需要应用程序控制

理解:外键会导致表与表之间耦合,UPDATE与DELETE操作都会涉及相关联的表,十分影响SQL的性能,甚至会造成死锁。

7、【强制】必须把字段定义为NOT NULL并且提供默认值

理解:NULL需要更多的存储空,无论是表还是索引中每行中的NULL的列都需要额外的空间来标识。NULL这种类型需要MySQL内部进行特殊处理,增加了数据库处理记录的复杂性,同等条件下,表中较多NULL字段会导致数据库处理性能下降。

8、【强制】禁止使用保留字,如DESC、RANGE、MAX等

理解:请参考MySQL官方保留字。

9、【强制】如果存储的字符串长度几乎相等,使用CHAR定长字符串类型

理解:能够减少空间碎片,节省存储空间。

10、【强制】小数类型为 decimal,禁止使用 float 和 double

理解:float 和 double 在存储的时候,存在精度损失的问题,很可能在值的比较时,得到正确的结果。如果存储的数据范围超过 decimal 的范围,建议将数据拆成整数和小数分开存储。

11、【强制】表必备三字段:id, gmt_create, gmt_modified。

理解:其中 id 必为主键,类型为 bigint unsigned、单表时自增、步长为 1。gmt_create,gmt_modified 的类型均为 datetime 类型,前者现在时表示主动创建,后者过去分词表示被动更新。

12、【推荐】在一些场景下,考虑使用TIMESTAMP代替DATETIME

理解:TIMESTAMP可以表达1970-2038年,而且TIMESTAMP需要4字节存储空间,而DATETIME需要8字节,存储1001-9999年

13、【推荐】对于自动生成的schema不要太过信任,最好自己手动写

理解:对于一些数据库客户端不要过分信任。

索引规约

1、【强制】业务上具有唯一特性的字段,即使是多个字段的组合,也必须建成唯一索引

理解:不要以为唯一索引影响了 insert 速度,这个速度损耗可以忽略,但提高查找速度是明显的;另外,即使在应用层做了非常完善的校验控制,只要没有唯一索引,根据墨菲定律,必然有脏数据产生。

2、【强制】超过三个表禁止 join。需要 join 的字段,数据类型必须绝对一致;多表关联查询时,保证被关联的字段需要有索引

理解:多表的join操作会影响SQL的性能

3、【强制】在 varchar 字段上建立索引时,必须指定索引长度,没必要对全字段建立索引,根据实际文本区分度决定索引长度即可

理解:索引的长度与区分度是一对矛盾体,一般对字符串类型数据,长度为 20 的索引,区分度会高达 90%以上,可以使用 count(distinct left(列名, 索引长度))/count(*)的区分度来确定。

4、【强制】页面搜索严禁左模糊或者全模糊,如果需要请走搜索引擎来解决

理解:索引文件具有 B-Tree 的最左前缀匹配特性,如果左边的值未确定,那么无法使用此索引。

5、【推荐】如果有 order by 的场景,请注意利用索引的有序性。order by 最后的字段是组合索引的一部分,并且放在索引组合顺序的最后,避免出现 file_sort 的情况,影响查询性能

理解:组合索引的顺序会影响到SQL的查询性能

6、【推荐】利用覆盖索引来进行查询操作,避免回表

理解:覆盖索引只需要通过索引即可拿到所需的数据,而不再需要再次回表查询,提高了SQL的查询效率。

7、【推荐】利用延迟关联或者子查询优化超多分页场景

理解:MySQL 并不是跳过 offset 行,而是取 offset+N 行,然后返回放弃前 offset 行,返回N 行,那当 offset 特别大的时候,效率就非常的低下,要么控制返回的总页数,要么对超过特定阈值的页数进行 SQL 改写。

8、【推荐】建组合索引的时候,区分度最高的在最左边

理解:区分度最高的放左边,能够在一开始过滤掉很多无用数据,提高索引的效率。需要注意的是各个条件的顺序尽量和索引的顺序一致。

9、【推荐】防止因字段类型不同造成的隐式转换,导致索引失效

理解:详细细节可以参考这篇文章哦~MySQL索引(三)索引不生效的情况

SQL规约

1、【强制】不要使用 count(列名)或 count(常量)来替代 count(*),count(*)是 SQL92 定义的标准统计行数的语法,跟数据库无关,跟 NULL 和非 NULL 无关

理解:count(*)会统计值为 NULL 的行,而 count(列名)不会统计此列为 NULL 值的行。

2、【强制】使用 ISNULL()来判断是否为 NULL 值

理解:NULL与任何值直接比较都为NULL。

  1. NULL<>NULL返回结果是NULL,而不是false。
  2. NULL=NULL返回结果是NULL,而不是false。
  3. NULL&1返回结果是NULL,而不是true。

3、【强制】在代码中写分页查询逻辑时,若 count 为 0 应直接返回,避免执行后面的分页语句

理解:提高SQL的效率,避免不必要的无用查询。

4、【强制】不得使用外键与级联,一切外键概念必须在应用层解决

理解:外键会导致表与表之间耦合,UPDATE与DELETE操作都会涉及相关联的表,十分影响SQL的性能,甚至会造成死锁。

5、【强制】禁止使用存储过程,存储过程难以调试和扩展,更没有移植性

理解:避免不必要的维护。

6、【推荐】TRUNCATE TABLE 比 DELETE 速度快,且使用的系统和事务日志资源少,但 TRUNCATE无事务且不触发 trigger,有可能造成事故,故不建议在开发代码中使用此语句。

理解:TRUNCATE TABLE 在功能上与不带 WHERE 子句的 DELETE 语句相同。

参考

  • 《阿里巴巴Java开发手册》
  • 实际工作结合《阿里巴巴Java开发手册》得出的理解

本文转自 https://blog.csdn.net/weixin_37686415/article/details/110276789?utm_medium=distribute.pc_relevant.none-task-blog-OPENSEARCH-6.control&dist_request_id=&depth_1-utm_source=distribute.pc_relevant.none-task-blog-OPENSEARCH-6.control,如有侵权,请联系删除。

收藏
评论区

相关推荐

解读阿里巴巴开发规范之MySQL
(https://blog.csdn.net/weixin_37686415/article/details/110276789?utm_mediumdistribute.pc_relevant.nonetaskblogOPENSEARCH6.control&dist_request_id&depth_1utm_sourcedistrib
MySQL 8.0.23新特性
> 作者:lefred > > 译者:孟维克 > 原文链接: > > * https://lefred.be/content/mysql-invisible-column-part-i/ > > * https://lefred.be/content/mysql-invisible-column-part-ii/ >
MySQL数据库优化技巧
MySQL优化三大方向 ① 优化MySQL所在服务器内核(此优化一般由运维人员完成)。 ② 对MySQL配置参数进行优化(my.cnf)此优化需要进行压力测试来进行参数调整。 ③ 对SQL语句以及表优化。 MySQL参数优化 1:MySQL 默认的最大连接数为 100,可以在 mysql 客户端使用以下命令查看 mysql>
MySQL运维之
**1、mysqldump备份一个数据库** mysqldump命令备份一个数据库的基本语法: mysqldump -u user -p pwd dbname > Backup.sql 我们来讲解一下备份的文件都包含了什么?\-- MySQL dump 10.13 Distrib 5.5.20, for Win32 (x86)\--
MySQL高级
1mysql的架构介绍 Mysql简介 概述 高级MySQL mysql内核 sql优化工程师 mysql服务器的优化 查询语句优化 主重复制 软硬件升级 容灾备份 sql编程 MysqlLinux版本的安装--mysql5.5 查看MySQL的安装位置:which mysqld 参考网址:https://ww
Mysql免安装版的配置
使用mysql-5.5.20版本。 转载:http://supportopensource.iteye.com/blog/1415527 1、下载mysql-5.5.20-win32.zip,解压到D:\\dev,D盘的dev文件夹下就会出现mysql-5.5.20-win32目录,将其重命名为mysql。 2、配置MYSQL的环境变量 新增
Ubuntu18.04下安装MySQL
**提示:以下操作均在root权限下进行。** \# 查看有没有安装MySQL: dpkg -l | grep mysql \# 安装MySQL: apt install mysql-server ![](https://img2018.cnblogs.com/blog/1404518/201905/1404518-2019050815303467
Ubuntu下忘记MySQL密码重设方法
1、结束当前正在运行的mysql进程。 \# /etc/init.d/mysql stop 2、用mysql安全模式运行并跳过权限验证。 \# /usr/bin/mysqld\_safe --skip-grant-tables 3、重开一个终端以root身份登录mysql。 \# mysql -u root 4、修改
mysql,基础命令
一  配置文件 \[mysqld\] \# 设置mysql的安装目录 \*\*后面的路径一定是安装sql的目录(自己电脑的)\*\* basedir=C:\\mysql-5.7.22-winx64\\mysql-5.7.22-winx64 \# 设置mysql数据库的数据的存放目录,必须是data datadir=C:\\mysql-5.7
mysql开启分析定位慢查询
捕捉mysql性能问题最常用的就是打开慢查询,定位查询效率低下的sql语句. 编辑/etc/my.ini ![](https://images2018.cnblogs.com/blog/1074948/201805/1074948-20180531172754193-1899883540.png) slow_query_log 慢查询开启状态
mysql数据库的导出与导入
**1、首先linux 下查看mysql相关目录**       \[root@op-workorder bin\]# **whereis mysql**       mysql: /usr/bin/mysql /usr/lib64/mysql /usr/include/mysql **2、导出数据库用mysqldump命令**     cd /
C++操作mysql__通过mysql的c api连接mysql服务器
C++通过mysql的c api连接mysql服务器 -------------------------- 1、在连接之前,不要忘记打开mysql服务器哇(Navicat打开或者不打开都可以) ![](https://img2018.cnblogs.com/blog/1404463/201906/1404463-20190624105319714-798
CentOS_7下安装MySQL
### 卸载旧版本MySQl: ![](https://oscimg.oschina.net/oscnet/96d8e2ecea96d08f5693a3998f5797fe1f6.png) ### 下载MySQ: MySQl官网:https://dev.mysql.com/downloads/mysql/ ![](https://img2018.cn
Centos7上安装启动 tars
先在Centos的虚拟机上操作: 首先[安装 JDK 和 Mysql](https://my.oschina.net/Kxvz/blog/420244) 可以参照之前的文章: [https://my.oschina.net/Kxvz/blog/420244](https://my.oschina.net/Kxvz/blog/420244) [SQL脚本
Linux中Mysql主从配置
**安装步骤:** ========= #**[1.安装MySql](http://my.oschina.net/java2010/blog/356371)** **2.修改MySql配置文件** ================= **主Mysql配置文件:** \[client\] port=3306 default-character-set=u