-
Notifications
You must be signed in to change notification settings - Fork 0
SQL style guides
雷霹雳的爸爸 edited this page Aug 6, 2018
·
5 revisions
- 阿里巴巴开发手册1.4.0版
- SQL style guide
- SQL style guide misconceptions
- Is there a naming convention for MySQL?
- SQL Antipartterns
以阿里的开发手册1.4版(以下简称手册)中的MySQL部分为蓝本及基础,并结合:
- 业务特点
- 组织级设计风格约定
而最终形成的文本
如果遵循阿里开发手册中的意见(page25-30),这里不再特别列出,以下,仅记录对手册的修改和补充部分
原文:
【强制】表名不使用复数名词。
扩充内容,修改为:
- 【强制】表名不使用复数名词
- 同时【建议】使用集合类名词来作为复数形式
- 一个例子是用staff代替employee
说明:
- 表名单数还是复数是个由来已久的设计抉择
- 这个问题从根源上看,表是关系模式的一个现实表达,严格地说是元组的集合,因此复数名词并不糟糕
- 但通常习惯性禁止复数形式的理由是:工具和面向对象:
- 复数单词形式和程序代码中类的名字习惯是不一致的,不利于持久层框架工具的转换,必然需要额外的注解或配置文件来处理这个问题
- 因此考虑实用性,强制不用复数名词是有现实性基础的,但最好考虑关系模型中的本意,一个好的关系模型不该被面向对象设计干扰
原文:
【强制】表必备三字段:id, gmt_create, gmt_modified。 说明:其中 id 必为主键,类型为 bigint unsigned、单表时自增、步长为 1。gmt_create,gmt_modified 的类型均为 datetime 类型,前者现在时表示主动创建,后者过去分词表示被动更新。
修改为:
- 【建议】表必备三字段:xxx_id或id, created_gmt_at, updated_gmt_at
- 如果确定没有性能问题,【建议】使用自然键做为主键
- 如果基于效率问题考虑设置代理键(或称伪主键,即 surrogate key 或 pseudokey ),应该使用 bigint unsigned,单表时自增、步长为1
- 如果生成类似操作日志表的主键或分片存储数据,【建议】使用类似 snow flake 算法保证全局唯一,导引参考;
- 如果不确定是否有效率问题,使用代理键
- 主键字段命名首选使用_id后缀,和能反映表对应实体(如果有)的类型的名字,比如如果是缺陷表,就叫bug_id,除非遗留系统中,无需修改原名称(具体参考知名产品wordpress的混乱现状)
- 手册中的gmt是提示性的,值得吸纳,表示这里实际上存储的应该是与时区无关的时间戳,所以应当保留,但是两个语态解释太烂了,分明这里应该是时态表达是重点,固化在数据库中值的必然都是过去式,操作主体都该是应用程序,(current_timestamp_似乎不支持datetime,或者支持也有时区设置问题的潜在问题和这里gmt设计相悖)
说明:
- 从性能角度,认为手册对 id 设计的规定虽然是有效的;
- 但从业务上,认为是武断的
- unsigned bigint毫无疑问有着更好的磁盘内存的存储效率;但自然键更符合业务本意,且不一定会造成性能问题
- 命名这里为什么建议使用了蓝精灵命名法,这来自于SQL反模式作者的定义,因为
- 含义更清晰,全局一致
- 可以使用更简洁的using,而不是on,stackoverflow上也有说明using和on的区别的
- 手册中gmt的强调
- 【强制】表名、字段名限定在50个字符以内(通常是30个字符,但考虑鼓励更准确的命名,放宽)
- 【建议】表的列数控制在50个字段以下,特殊场景可放宽;text等大字段要考虑垂直分表
- 【强制】要求每个字段都有注释说明清楚业务含义
- 由于不做数据库范式的强制性要求,因此允许不使用参照表来限定枚举类的值,即可以用整型表示枚举值的情况,这时需要在注释中明确记录0,1,2,...分别都表达的具体含义
- 持久层框架的选择
- 【强制】不要直接使用hibernate
- 【强制】一个project中,只选用一种持久层框架
- 【建议】首选JPA、少用 HQL、次选Mybatis、尽量不用Spring JdbcTemplate、可以使用jooq等DSL风格框架,唯一需要遵从的就是上一条规则,一个project中只选用一种持久层框架
- 【强制】不修改全局缺省的数据库隔离级别
- 【建议】显式的为每个事务声明事务隔离级别
- 【建议】创建表语句显式声明数据库引擎,推荐使用缺省的InnoDB引擎,如有特别的需要其他引擎,注释说明清楚
- 【建议】微服务设计不要使用共享数据库模式,而以Database per Service为主
- 【建议】当使用数据库每服务模式时,出于效率考虑,允许冗余存储其他库的数据,但字段规格应当与业务主库中的定义保持一致,同时注意上述枚举整型值的注释保持一致的更新