MySQL设计规范

Posted by xiezg247 on January 5, 2018

业务需求

需求讨论

  • 尽可能的考虑各种情况,并且与产品以及即将使用该系统的人沟通。
  • 确定系统中有哪些角色,动作,包括了解,哪些人能做哪些动作、一个角色作出某个动作后,需要对考虑任意角色作出任意动作的影响。

    Design Review

  • 在编写代码前,需要进行该流程。
  • 该流程需要该项目的主要开发者对住这儿平台组的所有成员介绍该项目的设计。大约耗费0.5天~1天的时间。主要开发者需要准备如下内容:
    • 尽可能简短的语言描述清楚 需求。
    • 项目的 model 设计
    • 该流程可能会迭代 2 次以上。

规范

基础规范

  • 使用 INNODB 存储引擎
  • 数据库应使用 utf8 作为默认编码,utf8_unicode_ci 作为默认排序方式(collatiion)
  • 对于存储用户输入的列,为了保证用户使用 Emoji 时仍能够正常保存数据, 应使用 utf8mb4 作为编码,utf8mb4_unicode_ci 作为排序方式

数据库命名规范

  • 采用26个英文字母(区分大小写)和0-9的自然数(经常不需要)加上下划线’_‘组成
  • 长度不超过30个字符
  • 备份数据库后缀一般加0-9的自然数

数据库表名命名规范

  • 采用26个英文字母(区分大小写)和0-9的自然数(经常不需要)加上下划线’_‘组成
  • 长度不超过64个字符,过长的单词考虑缩写,多个单词用下划线’_‘分隔
  • 适当的表前缀,比如’user_’
  • 不需要过多的后缀

数据库表字段名命名规范

  • 采用26个英文字母(区分大小写)和0-9的自然数(经常不需要)加上下划线’_‘组成
  • 命名多个单词用下划线’_‘分隔
  • 每个表中必须有自增主键,创建时间默认系统时间,任意表均需包含 created_at , updated_at , deleted_at ,这三个字段,并且不可为空
  • 表与表之间的相关联字段名称要求尽可能的相同

数据库表字段类型规范

  • IP地址最好使用int类型
  • 用尽量少的存储空间来存数一个字段的数据,正确使用tinyint/smallint/int,
  • 固定长度的类型最好使用char,未知长度的类型最好使用varchar,且尽可能多给点长度
  • 每个字段都应该有一个默认值,最好不能为null

数据库表索引规范

  • 为每个表创建一个主键索引
  • 非唯一索引命名应为 idx_{column_1}_{column_2}_…,唯一索引应命名为 uniq_{column_1}_{column_2}_…
  • 慎重建立复合索引

简单熟悉数据库范式

  • 第一范式:要求有主键,并且要求每一个字段原子性不可再分
  • 第二范式:要求所有非主键字段完全依赖主键,不能产生部分依赖
  • 第三范式:所有非主键字段和主键字段之间不能产生传递依赖

反范式

数据库设计文档规范

  • 表的定义,表中各个字段的定义等
  • 扩展设计,如某些字段的缺省值、Check约束、外键约束等,表的索引、触发器、物理存储等
  • 对快捷方式、命名规范、限制和函数等
  • 给表、列、触发器等加注释
  • 由数据库内容来维护设计文档,没有进行维护工作的设计文档很可能就是一份形式主义报告

设计原则

核心原则

  • 尽量不在数据库做运算
  • cpu计算务必移至业务层
  • 控制列数量(字段少而精,字段数建议在20以内)
  • 平衡范式与冗余(效率优先,往往牺牲范式)
  • 拒绝3B,拒绝大sql语句()big sql)、拒绝大事务(big transaction)、拒绝大批量(big batch)

字段类原则

  • 用好数值类型(用合适的字段类型节约空间)
  • 字符转化为数字(能转化的最好转化,同样节约空间,提高查询性能)
  • 避免使用NULL字段(NULL字段很难查询优化/NULL字段的索引需要额外空间/NULL字段的复合索引无效)
  • 少用text类型(尽量使用varchar代替text字段)

索引类原则

  • 合理使用索引(改善查询,减慢更新,索引不是越多越好)
  • 字符字段必须建前缀索引
  • 不在索引做列运算
  • innodb主键推荐使用自增列(主键建立聚簇索引,主键不应该被修改,字符串不应该做主键)
  • 不用外键(由程序保证约束)
  • 单表索引个数尽量限制在5个以内
  • 重要的SQL必须被索引
  • 不在低基数列上建立索引
  • 如果是索引字段,一定要定义为not null

sql类原则

  • sql语句尽可能简单(一条sql只能在一个cpu运算,大语句拆小语句,减少锁时间,一条大sql可以堵死整个库)
  • 简单的事务
  • 避免使用trig/func(触发器、函数不用客户端程序取而代之)
  • 不用select *(消耗cpu,io,内存,带宽,这种程序不具有扩展性)
  • OR改写为IN(or的效率是n级别)
  • OR改写为UNION(mysql的索引合并很弱智)
  • 避免负向%
  • 慎用count(*)
  • limit高效分页(limit越大,效率越低)
  • 使用union all替代union(union有去重开销)
  • 少用连接join,特别是避免使大表的join
  • 使用group by
  • 请使用同类型比较
  • 打散批量更新

性能分析工具

  • show profile
  • mysqlsla
  • mysqldumpslow
  • explain
  • show slow log
  • show processlist

其他优化

  • 对于复杂的查询,执行 explain,查看索引使用情况
  • 一般避免使用触发器,如果确实要使用,请文档化
  • 使用常用英语命名,尽量避免拼音或者编程上的术语
  • 保存常用信息,创建一个表专门存放数据库当前版本、最近检查/修复(对Access)、关联设计文档的名称等信息

参考