Mysql 开发规范
Mysql 开发规范
一 基本规范
- 使用 INNODB 存储引擎
- 表字符集使用 UTF8
- 所有表都需要添加注释
- 单表数据量建议控制在 5000W 以内
- 不在数据库中存储图⽚、文件等大数据
- 禁止在线上做数据库压力测试
二 命名规范
- 库名表名字段名必须有固定的命名长度,12个字符以内
- 库名、表名、字段名禁⽌止超过32个字符。须见名之意
- 库名、表名、字段名禁⽌止使⽤用MySQL保留字
- 临时库、表名必须以tmp为前缀,并以⽇日期为后缀
- 备份库、表必须以bak为前缀,并以日期为后缀
三 库、表、字段开发设计规范
- 尽可能不使用 TEXT 、 BLOB 类型
- 用 DECIMAL 代替 FLOAT 和 DOUBLE 存储精确浮点数
- 越简单越好:将字符转化为数字、使用 TINYINT 来代替 ENUM 类型
- 所有字段均定义为 NOT NULL
- 使用 UNSIGNED [^ UNSIGNED ]存储非负整数
- INT类型固定占用 4 字节存储
- 使用 timestamp 存储时间
- 使用 INT UNSIGNED 存储 IPV4 [^ 存储 IPV4]
- 使用 VARBINARY 存储大小写敏感的变长字符串
- 禁止在数据库中存储明文密码,把密码加密后存储
- 用好数值类型字段
- 不允许使用 ENUM
- 避免使用 NULL 字段, NULL 字段很难查询优化,
NULL
字段的索引需要额外空间,NULL
字段的复合索引无效 - 少用 text/blob , varchar 的性能会比 text 高很多,实在避免不了blob,请拆表
- 数据库中不允许存储大文件,或者照片,可以将大对象放到磁盘上,数据库中存储它的路径
四 索引规范
1、索引的数量要控制:
- 单张表中索引数量不超过5个
- 单个索引中的字段数不超过5个(联合索引)
- 对字符串使⽤用前缀索引,前缀索引长度不超过8个字符
- 建议优先考虑前缀索引,必要时可添加伪列并建立索引
2、主键准则
- 表必须有主键
- 不使用更新频繁的列作为主键
- 尽量不选择字符串列作为主键
- 不使用 UUID MD5 HASH 这些作为主键(数值太离散了)
- 默认使⽤非空的唯一键作为主键
- 建议选择自增或发号器1
3、重要的SQL必须被索引,比如:
- UPDATE 、 DELETE 语句的 WHERE 条件列
- ORDER BY 、 GROUPBY 、 DISTINCT 的字段
4、多表JOIN的字段注意以下
- 区分度最大的字段放在前面
- 核⼼SQL优先考虑覆盖索引
- 避免冗余和重复索引
- 索引要综合评估数据密度和分布以及考虑查询和更新比例
5、索引禁忌
- 不在低基数列上建立索引,例如“性别”
- 不在索引列进行数学运算和函数运算
6、尽量不使用外键
- 外键用来保护参照完整性,可在业务端实现
- 对父表和子表的操作会相互影响,降低可用性
7、索引命名:
- 非唯一索引必须以idx字段1字段2命名,唯一所以必须以 uniq 字段 1 字段 2 命名,索引名称必须全部小写
8、新建的唯一索引必须不能和主键重复
9、索引字段的默认值不能为 NULL ,要改为其他的 default 或者空。 NULL 非常影响索引的查询效率
10、反复查看与表相关的SQL,符合最左前缀的特点建立索引。多条字段重复的语句,要修改语句条件字段的顺序,为其建立一条联合索引,减少索引数量
11、能使用唯一索引就要使用唯一索引,提高查询效率
12、研发要经常使用 explain ,如果发现索引选择性差,必须让他们学会使用hints
五、SQL规范
-
SQL语句尽可能简单,大的SQL想办法拆成小的SQL语句(充分利用QUERYCACHE和充分利用多核CPU)
-
事务要简单,整个事务的时间长度不要太长
-
避免使用触发器、函数、存储过程
- Scale Up和Scale Out的区别 Scale Out是指Application可以在水平方向上扩展。一般对数据中心的应用而言,Scale out指的是当添加更多的机器时,应用仍然可以很好的利用这些机器的资源来提升自己的效率从而达到很好的扩展性。
- Scale Up是指Application可以在垂直方向上扩展。一般对单台机器而言,Scale Up值得是当某个计算节点(机器)添加更多的CPU Cores,存储设备,使用更大的内存时,应用可以很充分的利用这些资源来提升自己的效率从而达到很好的扩展性。
避免在数据库中进⾏数学运算(MySQL不擅长数学运算和逻辑判断)
不要用 SELECT * ,查询哪几个字段就
SELECT这几个字段
SQL中使用到
OR的改写为用
IN()(
OR的效率没有
IN的效率高)
in里面数字的个数建议控制在 1000 以内
LIMIT分页注意效率。
LIMIT越大,效率越低。可以改写 LIMIT ,比如例子改写:
SELECT id FROM t LIMIT 10000, 10; => SELECT id FROM t WHERE id > 10000 LIMIT 10;
使用 UNION ALL 替代 UNION
避免使用大表的 JOIN
使用 GROUP BY 分组、自动排序
对数据的更新要打散后批量更新,不要一次更新太多数据
减少与数据库的交互次数
注意使用性能分析工具
SQL explain / showprofile / mySQLsla
SQL语句要求所有研发,SQL关键字全部是大写,每个词只允许有一个空格
SQL语句不可以出现隐式转换,比如
SELECT id FROM TABLE WHERE id='1'
IN条件里面的数据数量要少,我记得应该是500个以内,要学会使用EXIST代替IN,EXIST在一些场景查询会比IN快
select * from a where a_name in (select b_name from b) 转换成 select * from a where exists (select b_id from b where b.b_name = a.a_name)
能不用 NOT IN 就不用 NOTIN ,坑太多了。。会把空和NULL给查出来
在SQL语句中,禁止使用前缀是%
的LIKE
不使用负向查询,如 NOT IN / LIKE
关于分页查询:程序里建议合理使用分页来提高效率
LIMIT,
OFFSET较大要配合子查询使用
禁止在数据库中跑大查询
使⽤预编译语句,只传参数,比传递SQL语句更高效;一次解析,多次使用;降低SQL注入概率
禁止使 ORDER BY RAND() [^ORDER BY RAND()]
禁⽌单条SQL语句同时更新多个表
六、流程规范
- 所有的建表操作需要提前告知该表涉及的查询SQL;
- 所有的建表需要确定建立哪些索引后才可以建表上线;
- 所有的改表结构、加索引操作都需要将涉及到所改表的查询SQL发出来告知DBA等相关人员;
- 在建新表加字段之前,要求研发至少要提前3天邮件出来,给DBA们评估、优化和审核的时间
- 批量导入、导出数据必须提前通知DBA协助观察
- 禁止在线上从库执行后台管理和统计类查询
- 禁止有超级权限的应用程序账号存在
- 推广活动或上线新功能必须提前通知DBA进⾏行流量评估
- 不在业务高峰期批量更新、查询数据库
七 Mysql 数据类型
1、整型
MySQL数据类型 | 含义(有符号) | 是否常用 |
---|---|---|
tinyint(m) | 1个字节 范围(-128~127) | 是 |
smallint(m) | 2个字节 范围(-32768~32767) | |
mediumint(m) | 3个字节 范围(-8388608~8388607) | |
int(m) | 4个字节 范围(-2147483648~2147483647) | 是 |
bigint(m) | 8个字节 范围(±9.22*10的18次方) | 是 |
取值范围如果加了 unsigned,则最大值翻倍,如 tinyint unsigned 的取值范围为(0~256)。
2、浮点型(float 和 double)
MySQL数据类型 | 含义 | 是否常用 |
---|---|---|
float(m,d) | 单精度浮点型 8位精度(4字节) m总个数,d小数位 | |
double(m,d) | 双精度浮点型 16位精度(8字节) m总个数,d小数位 |
3、定点数
浮点型在数据库中存放的是近似值,而定点类型在数据库中存放的是精确值。
decimal(m,d) 参数 m<65 是总个数,d<30 且 d<m 是小数位。
4、字符串(char,varchar,_text)
MySQL数据类型 | 含义 | 是否常用 |
---|---|---|
char(n) | 固定长度,最多255个字符 | |
varchar(n) | 固定长度,最多65535个字符 | 是 |
tinytext | 可变长度,最多255个字符 | |
text | 可变长度,最多65535个字符 | 是 |
mediumtext | 可变长度,最多2的24次方-1个字符 | |
longtext | 可变长度,最多2的32次方-1个字符 |
char 和 varchar:
- 1.char(n) 若存入字符数小于n,则以空格补于其后,查询之时再将空格去掉。所以 char 类型存储的字符串末尾不能有空格,varchar 不限于此。
- 2.char(n) 固定长度,char(4) 不管是存入几个字符,都将占用 4 个字节,varchar 是存入的实际字符数 +1 个字节(n<=255)或2个字节(n>255),所以 varchar(4),存入 3 个字符将占用 4 个字节。
- 3.char 类型的字符串检索速度要比 varcha 1bb8c r 类型的快。
varchar 和 text:
- 1.varchar 可指定 n,text 不能指定,内部存储 varchar 是存入的实际字符数 +1 个字节(n<=255)或 2 个字节(n>255),text 是实际字符数 +2 个字节。
- 2.text 类型不能有默认值。
- 3.varchar 可直接创建索引,text 创建索引要指定前多少个字符。varchar 查询速度快于 text, 在都创建索引的情况下,text 的索引似乎不起作用。
5.二进制数据(_Blob)
- 1._BLOB和_text存储方式不同,_TEXT以文本方式存储,英文存储区分大小写,而_Blob是以二进制方式存储,不分大小写。
- 2._BLOB存储的数据只能整体读出。
- 3._TEXT可以指定字符集,_BLO不用指定字符集。
6.日期时间类型
MySQL数据类型 | 含义 | 是否常用 |
---|---|---|
date | 日期 ‘2008-12-2’ | |
time | 时间 ‘12:25:36’ | |
datetime | 日期时间 ‘2008-12-2 22:06:44’ | |
timestamp | 自动存储记录修改时间 | 是 |
若定义一个字段为timestamp,这个字段里的时间数据会随其他字段修改的时候自动刷新,所以这个数据类型的字段可以存放这条记录最后被修改的时间。
数据类型的属性
MySQL关键字 | 含义 |
---|---|
NULL | 数据列可包含NULL值 |
NOT NULL | 数据列不允许包含NULL值 |
DEFAULT | 默认值 |
PRIMARY KEY | 主键 |
AUTO_INCREMENT | 自动递增,适用于整数类型 |
UNSIGNED | 无符号 |
CHARACTER SET name | 指定一个字符集 |
MySQL索引类型
MySQL目前主要有以下几种索引类型:
1. 普通索引
是最基本的索引,它没有任何限制。
2. 唯一索引
与前面的普通索引类似,不同的就是:索引列的值必须唯一,但允许有空值。如果是组合索引,则列值的组合必须唯
3. 主键索引
是一种特殊的唯一索引,一个表只能有一个主键,不允许有空值。一般是在建表的时候同时创建主键索引:
4. 组合索引
指多个字段上创建的索引,只有在查询条件中使用了创建索引时的第一个字段,索引才会被使用。使用组合索引时遵循最左前缀集合
5. 全文索引
主要用来查找文本中的关键字,而不是直接与索引中的值相比较。fulltext索引跟其它索引大不相同,它更像是一个搜索引擎,而不是简单的where语句的参数匹配。fulltext索引配合match against操作使用,而不是一般的where语句加like。它可以在create table,alter table ,create index使用,不过目前只有char、varchar,text 列上可以创建全文索引。值得一提的是,在数据量较大时候,现将数据放入一个没有全局索引的表中,然后再用CREATE index创建fulltext索引,要比先为一张表建立fulltext然后再将数据写入的速度快很多。
索引的缺点
1.虽然索引大大提高了查询速度,同时却会降低更新表的速度,如对表进行insert、update和delete。因为更新表时,不仅要保存数据,还要保存一下索引文件。
2.建立索引会占用磁盘空间的索引文件。一般情况这个问题不太严重,但如果你在一个大表上创建了多种组合索引,索引文件的会增长很快。
索引只是提高效率的一个因素,如果有大数据量的表,就需要花时间研究建立最优秀的索引,或优化查询语句。
注意事项
使用索引时,有以下一些技巧和注意事项:
- 索引不会包含有null值的列
只要列中包含有null值都将不会被包含在索引中,复合索引中只要有一列含有null值,那么这一列对于此复合索引就是无效的。所以我们在数据库设计时不要让字段的默认值为null。 - 使用短索引
对串列进行索引,如果可能应该指定一个前缀长度。例如,如果有一个char(255)的列,如果在前10个或20个字符内,多数值是惟一的,那么就不要对整个列进行索引。短索引不仅可以提高查询速度而且可以节省磁盘空间和I/O操作。 - 索引列排序
查询只使用一个索引,因此如果where子句中已经使用了索引的话,那么order by中的列是不会使用索引的。因此数据库默认排序可以符合要求的情况下不要使用排序操作;尽量不要包含多个列的排序,如果需要最好给这些列创建复合索引。 - like语句操作
一般情况下不推荐使用like操作,如果非使用不可,如何使用也是一个问题。like “%aaa%” 不会使用索引而like “aaa%”可以使用索引。 - 不要在列上进行运算
这将导致索引失效而进行全表扫描,例如
SELECT * FROM table_name WHERE YEAR(column_name)<2017;
- 不使用not in和<>操作
[^ UNSIGNED ]: unsigned 既为非负数,用此类型可以增加数据长度!
[^ 存储 IPV4]: 将IP地址转成int类型存储
- MySQL架构设计谈:从开发规范、选型、拆分到减压
- Mysql系列二:Mysql 开发标准规范
- 老鸟带你开发专业规范的MySQL启动脚本
- mysql 开发标准规范
- Mysql开发规范
- MySQL设计与开发规范
- 老叶观点:MySQL开发规范之我见
- mysql数据库开发规范【推荐】
- Mysql学习总结——使用MySql开发的Java开发者规范
- 曾用于内部培训的PPT内容:MySQL开发规范与实用技术交流
- Java开发规范(MySQL开发规范)-《阿里巴巴Java开发手册》
- MySQL开发规范之我见
- [转发] 老叶观点:MySQL开发规范之我见
- mysql 开发标准规范
- 老叶观点:MySQL开发规范之我见(更新版)
- MySQL架构设计谈:从开发规范、选型、拆分到减压(转)
- mysql开发规范文档
- Mysql学习总结(49)——从开发规范、选型、拆分到减压
- MySQL开发规范及实用技术
- MySQL开发规范与使用技巧总结