MySQL规范整理
Posted rhwayfunn
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MySQL规范整理相关的知识,希望对你有一定的参考价值。
基础规范
版本
- mysql 5.7
存储引擎
- InnoDB
字符集
utf8
必要时候使用utf8mb4
(1)utf8通用,无乱码风险,汉字3字节,英文1字节 (2)utf8mb4是utf8的超集,有存储4字节例如表情符号时,使用它
禁用存储过程、触发器、视图、Event
- 能在服务端计算的就不要把压力放在数据库
禁止存储大文件
- 对象存储
禁止在线上压测
各环境数据库源隔离
架构设计
读写分离
- 主从设计,实时同步
- 主服务器负责写
- 读服务器负责读
分库分表
- 分库
- 按业务水平拆分
- 分表
- 大表拆分为小表,维度可以是时间或者其他业务维度
热点数据
- 热点数据放在本地内存或者分布式缓存Redis
雪崩
- 当数据库访问并发达到一定值时,导致大量锁等待
- 使用数据库连接池、优化业务设计
读写优化
- 读优化
- 内存缓存
- 合理设置失效策略
- 并行
- 异步
- 内存缓存
- 写优化
- 主键
- 索引
表设计
控制单实例表个数
- 单实例总容量不要超过500G,表个数不要超过500
控制单表分表个数
- 不要超过1024
控制单表数据量
- 纯INT不超1000W,含CHAR不超500W
- 冷热数据分级存储,归档处理
- 分库、分表、分区
控制单表字段个数
- 字段不要超过50个
必须要有主键
- 自增主键使用unsigned int
SQL规范
DDL规范
- 字段指定not null default x
- 所有字段需要有comment
- 引擎使用InnoDB
DML规范
- where子句包含主键或者唯一索引
- 禁止多表关联更新
- 禁止未决SQL
- insert into select
- insert语句指定字段
- 一个事务包含的SQL少于5个
DQL规范
- in子句参数少于50
- 禁止使用limit深度分页
- 禁止order by rand()
- 查询返回的行数不要超过500,超过使用分页
- 更新频繁的表和大表禁止使用count(*)统计
- 排序尽量放在服务端实现
- 禁止select *
- 会增加cpu/io/带宽的消耗
- 指定字段能有效利用索引
- 指定字段在结构变更对程序无影响
- where子句禁止使用函数或表达式
- 会导致索引失效,全表扫描
编码规范
字段设计
- char vs varchar
- 固定长度或者长度近似使用char
- 字段长度不固定或者动态变化的使用varchar
- datetime/date/timestamp
- 存储日期使用date
- 存储时间使用datetime/timestamp
- 前者占用5个字节,后者占用4个字节
- datetime/timestamp在MySQL5.6.4后支持微妙
- 必须把字段设为NOT NULL并设默认值
- MySQL NULL列会被索引,如果是组合索引NULL列会影响整个索引的效率
- Oracle NULL列不会被索引
- 占用额外的空间
- NULL只能采用IS NULL或者IS NOT NULL进行筛选
- MySQL NULL列会被索引,如果是组合索引NULL列会影响整个索引的效率
- 有小数点的字段或者精度要求高的字段使用decimal,禁用float
- 用tinyint替代enum、set和bit数据类型
- 创建enum会执行ddl
- ip地址使用unsigned int存储
- 电话号码使用varchar(20)存储
索引设计
- 命名
- idx_索引名
- 唯一索引使用uniq_索引名
- 索引字段一般不超过5个
- 很可能是设计问题
- 单表的索引数量不超过5个
- 影响写性能
- 异常复杂的查询使用ES解决
- 使用EXPLAIN判断是否合理使用了索引,避免出现extra
- 对超过50长度的字符串列使用前缀索引而不是整列索引,前缀索引的长度略大于字段平均长度
- 避免创建冗余的联合索引
- 最左前缀匹配
- 避免在频繁更新的字段建立索引
- JOIN查询的两个字段类型如果不一致会导致全表扫描
以上是关于MySQL规范整理的主要内容,如果未能解决你的问题,请参考以下文章