MySQL 数据库设计规范

规范背景与目的MySQL 数据库与 Oracle、 SQL Server 等数据库相比,有其内核上的优势与劣势 。我们在使用 MySQL 数据库的时候需要遵循一定规范,扬长避短 。本规范旨在帮助或指导 RD、QA、OP 等技术人员做出适合线上业务的数据库设计 。在数据库变更和处理流程、数据库表设计、SQL 编写等方面予以规范,从而为公司业务系统稳定、健康地运行提供保障 。
数据库设计以下所有规范会按照【高危】、【强制】、【建议】三个级别进行标注,遵守优先级从高到低 。
对于不满足【高危】和【强制】两个级别的设计,DBA 会强制打回要求修改 。
一般命名规则

  1. 【强制】使用小写,有助于提高打字速度,避免因大小写敏感而导致的错误 。
  2. 【强制】没有空格,使用下划线代替 。
  3. 【强制】名称中没有数字,只有英文字母 。
  4. 【强制】有效的可理解的名称 。
  5. 【强制】名称应该是自我解释的 。
  6. 【强制】名称不应超过 32 个字符 。
  7. 【强制】避免使用前缀 。
  1. 【强制】遵守以上全部一般命名规则 。
  2. 【强制】使用单数 。
  3. 【强制】库的名称格式:业务系统名称_子系统名 。
  4. 【强制】一般分库名称命名格式是库通配名_编号,编号从 0 开始递增,比如 northwind_001,以时间进行分库的名称格式是库通配名_时间 。
  5. 【强制】创建数据库时必须显式指定字符集,并且字符集只能是 utf8 或者 utf8mb4 。创建数据库 SQL 举例:
create database db_name default character set utf8;
  1. 【强制】遵守以上全部一般命名规则 。
  2. 【强制】使用单数 。
  3. 【强制】相关模块的表名与表名之间尽量体现 join 的关系,如 user 表和 user_login 表 。
  4. 【强制】创建表时必须显式指定字符集为 utf8 或 utf8mb4 。
  5. 【强制】创建表时必须显式指定表存储引擎类型,如无特殊需求,一律为 InnoDB 。当需要使用除 InnoDB/MyISAM/Memory 以外的存储引擎时,必须通过 DBA 审核才能在生产环境中使用 。因为 InnoDB 表支持事务、行锁、宕机恢复、MVCC 等关系型数据库重要特性,为业界使用最多的 MySQL 存储引擎 。而这是其它大多数存储引擎不具备的,因此首推 InnoDB 。
  6. 【强制】建表必须有 comment 。
  7. 【强制】关于主键:(1) 命名为 id,类型为 int 或 bigint,且为 auto_increment;(2) 标识表里每一行主体的字段不要设为主键,建议设为其它字段如 user_id,order_id等,并建立 unique key 索引 。因为如果设为主键且主键值为随机插入,则会导致 InnoDB 内部 page 分裂和大量随机 I/O,性能下降 。
  8. 【建议】核心表(如用户表,金钱相关的表)必须有行数据的创建时间字段 create_time 和最后更新时间字段 update_time,便于排查问题 。
  9. 【建议】表中所有字段必须都是 NOT NULL 属性,业务可以根据需要定义 DEFAULT 值 。因为使用 NULL 值会存在每一行都会占用额外存储空间、数据迁移容易出错、聚合函数计算结果偏差等问题 。
  10. 【建议】建议对表里的 blob、text 等大字段,垂直拆分到其它表里,仅在需要读这些对象的时候才去 select 。
  11. 【建议】反范式设计:把经常需要 join 查询的字段,在其它表里冗余一份 。如 username 属性在 user_account,user_login_log 等表里冗余一份,减少 join 查询 。
  12. 【强制】中间表用于保留中间结果集,名称必须以 tmp_ 开头 。备份表用于备份或抓取源表快照,名称必须以 bak_ 开头 。中间表和备份表定期清理 。
  13. 【强制】对于超过 100W 行的大表进行 alter table,必须经过 DBA 审核,并在业务低峰期执行 。因为 alter table 会产生表锁,期间阻塞对于该表的所有写入,对于业务可能会产生极大影响 。
字段
  1. 【强制】遵守以上全部一般命名规则 。
  2. 【建议】尽可能选择短的或一两个单词 。
  3. 【强制】避免使用保留字作为字段名称:order,date,name 是数据库的保留字,避免使用它 。可以为这些名称添加前缀使其易于理解,如 user_name,signup_date 等 。


    推荐阅读