10. MySQL 规范

136 阅读3分钟

10. MySQL 规范.png

1. 单机规范

  1. 库名、表名全小写+无中文

    不同操作系统大小写敏感不同,windows 大小写不敏感,Linux 大小写敏感,如果有跨系统迁移,很可能出错,MySQL 中参数 lower_case_table_names=0,表示大小写敏感,建议修改为 1,大小写敏感,并且在 8.0 及后续版本,该值只能在实例初始化时修改,初始化完成后修改,启动会直接报错

  2. 表结构和备注尽量不要用中文字符

    比如建表用的是 GBK,但是表中 varchar 定义的是 utf-8,这样在 mysqldump 时,如果指定 default-charset 为 utf-8 ,可能出现表结构乱码导致出错的情况,因此建议表结构中数据都用英文

  3. 每个字段都要声明为 not null,并有默认值

    首先,如果允许为 null,那这个列需要额外一个字节去存储是否为 null,其次,如果不设置默认值,那在加列的情况下,以前的语句可能由于没有默认值,出现插入失败的情况

  4. 主键规范

    • bigint unsigned auto_increment
    • 业务不依赖
  5. 所有表建议都是用 innodb 引擎

    备份锁表时间短,备份时,如果不是 innodb 的表,需要用 FTWRL 锁表备份后再开启一致性视图备份才行

  6. 使用 super_read_only 代替 read_only

    如果设置为 read_only,普通用户也能执行 optimize table 命令,该命令会重建表

  7. 尽量不要使用视图/禁止使用触发器

    • 更新视图会更新原表,有些复杂视图,优化器处理不友好,可能存在性能下降问题
    • 触发器会导致事务变大(触发器完成后事务才能提交),性能变慢,有莫名其妙的加锁,触发器报错不写表名(排查问题困难)等
  8. 禁用 floatdouble

    floatdouble 有精度损失,改用 decimal

  9. 禁止在数据库中存储图片、文件等二进制数据

    首先有 offpage 问题,其次,备份时数据量会大很多,因此一般将图片、文件等存在外部系统中,数据库中只存连接即可

  10. 尽量不使用 json 类型

  11. 可以用 text 的地方,尽量不使用 blob

    如果不需要存不可见字符,比如二进制什么的,尽量选 text

  12. int unsigned 存 IP

  13. timestampdatetime 选哪个?

    • 表示范围:timestamp 是 1970~2038,datetime 是 1000 到 9999
    • 微秒支持:两者都支持
    • 存储空间:timestamp 4 个字节,datetime 5 个字节
    • 读取性能:两者差别不大

    建议使用 datetime,并且使用偶数位精度位

  14. 禁止给表中每一列都建立单独索引

  15. 超过三个表禁止 join

  16. 禁止直接 drop 生产表

  17. 禁止 grant 'a'@%

    优先考虑使用通配符设置网段

  18. 不允许直接修改 mysql.user 表,统一使用 grant 命令,grant 之后,不需要执行 flush privileges,因为该命令做了两件事:修改内存值和磁盘值,grant 后内存中是已经修改了的,只是还未落盘,flush privileges 更适合用于手动修改 mysql.user 后执行

  19. 手动执行 updatedelete 语句,必须带 limit,防止误操作多删或者多更新数据

  20. 建议总是使用 isnull(a) 代替 a is null,可以避免出错,且两者性能是一致的

2. 集群规范

  1. 总是开 GTID,切换方便
  2. 备库(standby)不接查询,主库或者读库查询
  3. HA 总是设置成可靠性优先,平时多关注备库延迟
  4. 备库修复数据时关掉 binlog
  5. semi-sync 一定要设置退化时间,建议 1 秒,至少设置 3 个节点