编码规范对于程序员而言尤为重要,一个软件的生命周期中,80%的花费在于维护,并且几乎没有任何一个软件,在其整个生命周期中,均由最初的开发人员来维护。
遵循一套编码规范可以改善软件的可读性,可以让程序员尽快而彻底地理解新的代码,如果你将源码作为产品发布,就需要确任它是否被很好的打包并且清晰无误,一如你已构建的其它任何产品。
同样的, MySQL 开发也需要一套规范,所以本文记录一下适用于大众的 MySQL 开发规范,我也确信这套开发规范不会适用于所有的开发团队,所以根据过去的经验、周围的技术栈、个人价值观做出有意义的偏差是可取的。
命名规范
-
库名、表名、字段名必须使用小写字母,并采⽤下划线分割。
-
库名、表名、字段名禁止超过 32 个字符,表名应该有意义,并且易于理解,最好使用可以表达功能的英文单词或缩写,如果用英文单词表示,建议使用完整的英文单词。
-
库名、表名、字段名禁止使用 MySQL 保留字。MySQL 保留字官方文档
-
临时库、表名必须以
tmp
为前缀,并以日期为后缀。 -
备份库、表必须以
bak
为前缀,并以日期为后缀。
关于表名有一个有趣的问题:表名应该使用单数还是复数,例如一个用户表,表名是用 user 还是 users 更合适呢?
这是一个很古老的问题,并且在 Stackoverflow 上有很大的争议,比较高票的回答是建议使用单数。
而 PHP 的 Laravel 框架推荐是使用复数形式,若没有特别指定,laravel 会默认自动对应名称为「Eloquent 类名称的小写复数形式」的数据库表。
虽然我也使用 Laravel 框架,但是我还是喜欢单数形式,Stackoverflow 上的大佬建议使用单数的理由是:
(1)概念直观。
你有一个袋子,里面有好多个苹果,你会说这是个苹果袋。但无论里面有0,1,百万个苹果,它依然是个袋子。表也是如此,表明需要描述清楚,表里面包含的对象,而非有多少个数据。(2)便利性
单数形式更简单。有一些单词,它的复数形式可能是非常规的,或者就没有复数形式,但是单数不一样,单数形式则没那么多讲究。有些单词的复数,可能会想到你头大,可能得好好google才出来(3)优雅
特别是一些master-detail形式的资源名称,统一用单数,读起来更方便,对齐更整齐,从顺序上更有逻辑性。
对比下
单数:
Order
OrderDetail
复数:
OrderDetails
Orders(4)简单朴素
设想下,不管是表名,主键,关系,实例Classes,你都可以统一用单数,所有看上去那么统一,也不用费心地各种复数单数中转换你的思维
Customer
Customer.CustomerID
CustomerAddress
public Class Customer {…}
SELECT FROM Customer WHERE CustomerID = 100
一旦你确定,要处理的这个对象,名字定为Customer,那么所有和数据库相关的交互、编程就都将使用这个单词(5)全球化
假设你身处一个全球化的团队,成员中有些人,母语不是英文,对他们来说,辨认、书写一个单词的复数形式,要更困难,会给他们带来麻烦,也给团队合作带来麻烦。(6)为什么不
这可以节省你的拼写时间,硬盘空间,甚至让你的键盘更“长寿”
看完我都惊了,真是让人无力反驳,所以我也建议大家都使用单数就好了嗷~
基础规范
-
使用
INNODB
存储引擎 -
表字符集使用
UTF8
,如果支持UTF8MB4
,使用UTF8MB4
(MySQL 从 5.7 版本开始支持UTF8MB4
,我目前的项目都是MySQL 8+
) -
所有表都需要添加注释
-
单表数据量建议控制在 5000 万以内
-
不在数据库中存储图片、文件等大数据
-
禁止在线上做数据库压⼒测试
-
禁止从测试、开发环境直连数据库
表库设计
-
禁止使用分区表
-
拆分⼤字段和访问频率低的字段,分离冷热数据
-
用 HASH 进⾏散表,表名后缀使用十进制数,下标从
0
开始 -
按日期时间分表需符合
YYYY[MM][DD][HH]
格式 -
采用合适的分库分表策略。例如千库十表、十库百表等
字段设计
-
尽可能不使⽤
TEXT
、BLOB
类型 -
⽤
DECIMAL
代替FLOAT
和DOUBLE
存储精确浮点数 -
将字符转化为数字
-
使⽤
TINYINT
来代替ENUM
类型 -
所有字段均定义为
NOT NULL
-
使⽤
UNSIGNED
存储非负整数 -
使⽤
timestamp
存储时间 -
使⽤
INT UNSIGNED
存储IPV4
-
禁⽌在数据库中存储明文密码
索引规范
MySQL 查询优化说起来非常复杂,不是一句两句能讲清的,这里只提供一些规范建议,不做过多说明。
索引的用途
-
去重
-
加速定位
-
避免排序
-
覆盖索引
索引数量控制
-
单张表中索引数量不超过 5 个
-
单个索引中的字段数不超过 5 个
-
对字符串使用前缀索引,前缀索引⻓度不超过8个字符
-
建议优先考虑前缀索引,必要时可添加伪列并建⽴索引
主键准则
-
表必须有主键
-
不使用更新频繁的列
-
尽量不选择字符串列
-
不使⽤UUID MD5 HASH
-
默认使用非空的唯⼀键
-
建议选择自增或发号器
重要的 SQL 必须被索引
- 重要的SQL必须被索引
UPDATE、DELETE 语句的 WHERE 条件列
ORDER BY、GROUP BY、DISTINCT 的字段
多表 JOIN 的字段
-
区分度最大的字段放在前面
-
核心 SQL 优先考虑覆盖索引
-
避免冗余和重复索引
-
索引不是越多越好
索引禁忌
-
不在低基数列上建立索引,例如 “性别”
-
不在索引列进行数学运算和函数运算
-
尽量不使用外键
外键⽤来保护参照完整性,可在业务端实现
对父表和子表的操作会相互影响,降低可用性
INNODB 本身对 online DDL 的限制
-
不使用
%
前导的查询,如like "%ab"
-
不使用负向查询,如
not in/like
⽆法使⽤索引,导致全表扫描,全表扫描导致bufer pool利⽤率降低
