0
点赞
收藏
分享

微信扫一扫

MySQL设计和开发规范

读思意行 2022-04-19 阅读 66

说明:此设计规范考虑了业务规范和数据处理的规范,其中的主键ID和etl_update_time字段的规范是为了方便数据平台分析处理数据。

Common

  1. 不要使用MySQL保留关键字

    • 建议级别:强制
    • 说明:不论是库名,表名,字段名,索引名等都不要使用MySQL保留的关键字。5.6版本的完整关键词参考MySQL官方文档:https://dev.mysql.com/doc/refman/5.6/en/keywords.html#keywords-5-6-detailed-A
    • 反例:from,time,key,like
  2. 所有对象的名字只能是小写字母或数字或下划线组合,只能以小写字母开头,禁止连续多个下划线

    • 建议级别:强制
    • 说明:Linux下默认区分大小写;数据库字段名和后端代码映射的时候,后端语言都不允许数字开头的变量出现;连续两个下划线会产生歧义,让人不知道有几个下划线;
    • 反例:category__id, spuId, 1vip
    • 正例:category_id, spu_id, vip1
  3. 所有对象的名字必须要见名识意,使用英文单词释意,多个单词使用下划线拼接,不要使用非公认的缩写,不要使用拼音

    • 建议级别:强制
    • 说明:所有对象的名字要让人看到名字就能知道它大致所表达的意思,不能模糊不清;非公认的缩写和拼音会让人很难读懂
    • 反例:product_id, act_id, pingtuan
    • 正例:spu_id,activity_id,group_buy

Table

  1. 临时表的表名以temp_开头;已经弃用的表以dropped_开头;备份表以bak_开头,日期为后缀

    • 建议级别:强制
    • 说明:为了快速理解和整理,并且在同步数据的时候会自动忽略掉这些表
    • 正例:temp_user,dropped_user,bak_user_20210615
  2. 每个表必须有主键,并且字段名为id,字段类型为int(11) unsigned,自增,步长为1

    • 建议级别:强制
    • 说明:自增主键ID能有序标识数据唯一性,unsigned标识存储非负数,能提升存储范围;也方便之后的数仓同步,去重等
    • 参考SQL如下:
    `id` int(11) unsigned NOT NULL AUTO_INCREMENT PRIMARY KEY COMMENT '主键-自增ID'
    
  3. 每个表必须有etl_create_time和etl_update_time字段,并设置值为记录的写入或更新时间

    • 建议级别:强制
    • 说明:这样做方便后面数据的同步,统计,去重等。该字段不具备业务意义,不要在业务逻辑里面使用。代码里面也不需要维护;
    • 参考SQL如下:
    `etl_create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间-etl专用',
    `etl_update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间-etl专用'
    
  4. 不允许使用联合主键,主键只能是自增ID,联合主键改成联合唯一索引

    • 建议级别:强制
    • 说明:由主键ID标识每一条唯一记录,业务上的联合唯一不要用主键来解决,用联合唯一索引,这样保留了主键ID的连续性和唯一性也可以替代联合主键的作用
    • 反例:PRIMARY KEY (column_a,column_b)
    • 正例:PRIMARY KEY (id), UNIQUE KEY uk_a_b (column_a,column_b)
  5. 非负数的数字类型,必须使用unsigned

    • 建议级别:强制
    • 说明:unsigned相对于signed可以多出一倍的存储空间,如 signed int -2147483648~2147483647 , unsigned int 0~4294967295
  6. 所有表中存储相同数据的列类型必须一致

    • 建议级别:强制
    • 说明:如果查询时关联列类型不一致会自动进行隐式转换,从而导致列上的索引失效
    • 反例:a表中 user_id为int ,b表中user_id为string
    • 正例:所有表中表示user_id的字段类型相同,都为int或都为string
  7. 所有的表和字段都需要加注释

    • 建议级别:强制
    • 说明:为了减少沟通成本,增加可读性,建议给每个表和字段都加上注释
  8. 不要使用外键

    • 建议级别:强制
    • 说明:外键与级联的更新操作对性能会有一定影响,并发场景容易产生死锁。外键的逻辑请在服务端实现
  9. boolean 类型的数据,设置成 tinyint(1)

    • 建议级别:建议
    • 说明:1为true,0为false
  10. 优先选择符合存储需要的最小的数据类型和长度

    • 建议级别:建议
    • 说明:列的字段越大,建立索引时所需要的空间也就越大,这样一页中所能存储的索引节点的数量也就越少也越少,在遍历时所需要的IO次数也就越多,索引的性能也就越差
  11. 所有字段定义为 not null,业务中允许null的字符字段可以设置默认值为空

    • 建议级别:建议
    • 说明:索引对null的列需要额外的空间来保存,会占用更多的空间;SQL查询的时候对null进行比较和计算需要做特殊处理,容易踩坑
    • 参考SQL:NOT NULL DEFAULT ''
  12. 不要使用自增ID作为业务主键

    • 建议级别:建议
    • 说明:自增ID在测试,生产环境都是不一样的,而且不好控制。建议业务自己维护自己的业务主键,如订单号
  13. 枚举字段注释格式 字段的注释 @枚举值1:枚举1意思;@枚举值2:枚举2意思;

    • 建议级别:建议
    • 说明:枚举注释格式统一,有助于减少理解成本;有助于注释和文档生成
    • 正例:gender comment ‘性别 @M:男; @F:女; @N:未知’

Index

  1. 索引命名规范,唯一索引以 uk_ 开头,普通索引以 idx_ 开头

    • 建议级别:强制
    • 说明:uk 是唯一索引 unique key 的缩写,idx 是普通索引index的缩写
  2. 确保多表join查询的时候,所关联的字段必须要有索引

    • 建议级别:强制
    • 说明:不仅要保证关联字段要有索引,还有确保关联字段类型必须一致,否则会导致索引失效
  3. 业务上具有唯一特性的字段,即使是组合字段,也需要建唯一索引

    • 建议级别:推荐
    • 说明:唯一索引在insert时候的速度损耗可以忽略,但极大的提高了查询的效率;而且唯一索引能够完全确保业务的唯一性。
  4. 尽量使用覆盖索引来查询,避免回表

    • 建议级别:推荐
    • 说明:覆盖索引可以在一棵树上就找到需要的列的数据,无需回表,速度更快。
    • 正例:explain的输出结果中Extra字段为Using index时,能够触发覆盖索引

SQL

  1. 禁止使用不含字段列表的insert语句

    • 建议级别:强制
    • 说明:当表结构变更的时候,会带来不可用的影响
    • 反例:insert into values (‘a’,‘b’,‘c’);
    • 正例:insert into t(c1,c2,c3) values (‘a’,‘b’,‘c’);
  2. 禁止使用SELECT * ,必须显式SELECT 字段列表

    • 建议级别:强制
    • 说明:select * 会消耗更多的资源;select * 无法使用覆盖索引;列出详细字段也可减少表结构变更带来的风险
  3. where语句中禁止对列进行函数操作或计算

    • 建议级别:强制
    • 说明:对列进行函数操作或计算会导致索引失效
    • 反例:age / 10 = 3; substring(name,1,3)=‘abc’; date_format(create_date, ‘%Y-%m-%d’) = ‘2022-01-03’
    • 正例:age = 10 * 3; name like ‘abc%’; create_date between ‘2022-01-03 00:00:00’ and ‘2022-01-03 23:59:59’
  4. 在确认没有重复值的情况下使用union all 代替 union

    • 建议级别:强制
    • 说明:union会把两个结果集放到临时表,然后再进行去重,union all 则不会
  5. 使用join代替子查询

    • 建议级别:强制
    • 说明:子查询的效率通常较低,子查询的结果集会被存放到临时表中,而临时表是没有索引的。
  6. 查询语句中有别名的, as 不要省略

    • 建议级别:建议
    • 说明:有as隔开字段和别名,SQL语句更容易理解。

附录1 常用字段

id int(11) unsigned NOT NULL AUTO_INCREMENT PRIMARY KEY COMMENT '主键-自增ID'
etl_create_time datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间-etl专用'
etl_update_time datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间-etl专用'
is_deleted tinyint(1) unsigned DEFAULT '0' COMMENT '是否删除 @1:是; @0:否'

举报

相关推荐

0 条评论