mysql军规

mysql军规

Date
Oct 20, 2021
Tags
Mysql
Database
适用于 高并发的 互联网服务

基础规范

  • 表存储引擎必须使用InnoDB
  • 表字符集默认使用utf8,必要时使用utf8mb4
可以防止乱码风险; 汉字3字节,英文1字节, 表情符号4字节
  • 库和表都必须有注释
  • 禁止使用存储过程,视图,触发器, Event
对数据库性能影响较大, 能让服务层和web层做的事情不要落到数据库层; 并且扩展性较差
  • 禁止数据库存储大文件(大对象)
可以存储到对象服务中, 然后数据库存路径
  • 禁止对线上环境做压力测试
  • 数据库各个环境(dev, pro, stage)必须隔离

命名规范

  • 库名, 表名, 列名必须使用小写, 采用下划线分隔
mysql不区分大小写,则abc, Abc,ABC可能会混乱
  • 库名,表名,列名必须见名知义, 长度不要超过32字符
  • 备份库需以bak_前缀,日期后缀

表设计规范

  • 单实例表个数必须控制在2000个以内
  • 单表分表个数控制在1024以内
  • 表必须要有主键, 推荐使用UNSIGNED整数做主键
删除无主键的表, row主从模式下,从库会挂掉
  • 禁止使用外键, 关联性由程序来保持
外键影响update/delete的性能,有可能造成死锁。
  • 大字段,访问频次低的字段拆分成单独的表存储;分离冷热数据(垂直拆分)

列设计规范

  • 根据业务区分使用tinyint/int/bigint, 分别占用1/4/8字节
  • 根据业务区分使用char/varchar
字段长度固定或者近似的场景, 适合使用char, 能减少碎片,查询性能提升字段长度相差较大的, 或者更新较少的场景, 适合使用varchar, 能减少空间
  • 根据业务区分使用 DATETIME/TIMESTAMPE
前者占用8个字节,后者占用4个;存储日期使用Date, 存储时间使用datetime
  • 必须把字段设置成NOT NULL, 并有默认值
null字段有索引时,性能不好null存储空间需要的更多null 的判断只有IS NULL等,会与其他判断语句==,!= 有心智负担
  • 使用INT UNSIGNED 存储IPv4, 不用使用char(15)
  • 使用varchar(20)存储手机号, 不要使用整数
当有国家代号时,会出现-/+等符号手机号不会做数学运算varchar可以进行模糊搜索
  • 金额类数据必须使用DECIMAL
精准浮点数,不会丢失精度。 可以存储比bigint更新的整数类型
  • 使用tinyint来代替enum
enum新增值,需要进行DDL
  • 避免使用TEXT,BLOB等数据类型

索引设计规范

  • 唯一索引使用uniq_[字段名]来命名
  • 非唯一索引使用idx_[字段名]来命名
  • 单张表索引数据控制在5个以内
高并发业务下, 索引太多会导致写性能降低生成执行计划时,索引太多,会降低性能,导致mysql选择不到最优索引异常复制的查询方式,可以选择ES等其他存储方式
  • 组合索引字段数不建议超过5
  • 不建议在频繁更新的字段上建立索引
  • 非必要不进行JOIN查询, 若是需要,被JOIN的字段必须类型相同,且建立索引
join字段类型不同,会进行全表扫描
  • order by, group by 等需要加索引
  • 理解组合索引的最左前缀原则, 避免重复建索引
索引(a,b,c) 相当于 (a), (a,b),(a,b,c)三个索引

SQL规范

  • 禁止使用select * ,是获取必要字段
select * 会增加cpu/io/内存/带宽的消耗指定字段可以有效利用索引覆盖指定字段查询
  • insert 必须指明字段列表
对表结构变更时, 不会对程序有影响
  • 禁止在where条件列中使用函数或者表达式, 会导致索引失效;全表扫面
  • 禁止负向查询以及%开头的模糊查询
不能命中索引,全表扫描
  • 禁止大表的JOIN和子查询
  • SQL只能利用复合索引中的一列进行范围查询
(a,b,c)联合索引,若是有 a 的范围查询, b,c上索引不会用到。 所以定义时可以将a放置到最右侧
  • 同一个字段上的OR必须改写成ININ的值必须少于50个
  • NOT IN 通常会使索引失效,可以改成子查询NOT EXISTS或者JOIN
  • 应用程序需要捕获数据库异常,便于排除问题

Loading Comments...