跳到主要内容

数据库规范

一、命名规范

1、总命名规范

1)、不得使用数据库保留关键字,以及java等常用语言的保留关键字,或者可能成为关键字的单词作为完整命名。(对于一些疑似关键字的单词,可以在后面加一个下划线来避免,例如“key_”)。

2)、如无特殊说明,名称必须用英文字母开头,采用有特征含义的单词或缩写,单词中间用“_”分割,且只能由英文字母、数字和下划线组成,不能用双引号包含。

3)、除数据库名称长度为1至8个字符,其余(包括表、字段、索引等)不超过30个字符,Database link名称也不要超过30个字符。(30并不是凭空想象出来的,而是参考了Oracle的限制)

2、库名

1)、【强制】库的名称必须控制在32个字符以内,相关模块的表名与表名之间尽量提现join的关系,如user表和user_login表。 2)、【强制】库的名称格式:业务系统名称_子系统名,同一模块使用的表名尽量使用统一前缀。 3)、【强制】一般分库名称命名格式是库通配名_编号,编号从0开始递增,比如wenda_001以时间进行分库的名称格式是“库通配名_时间” 4)、【强制】创建数据库时必须显式指定字符集,并且字符集只能是utf8或者utf8mb4。创建数据库SQL举例:create database db1 default character set utf8;。

3、表名

【强制】建表必须有comment表说明 例如:dat_address_type
dat是项目名称主数据管理(basedata)的缩写(建议以2-3字项目名称为前缀开头)
address_type 表示当前用户表的具体含义(1-3个单词,用下划线连接)
不同单词用下划线分开, 正例:dat_address_type 反例:dat_addresstype

特别强调:项目名称和模块名用简写(建议长度为2-5个字符),而表含义的名称,可简写、也可以不简写,但是都不能超过3个单词,
例如下面两个反面例子:

  1. ABF_SUPERVISION_USER,问题:模块名称似乎比较长,建议控制在2-5个字符,缩写为 ABF_SUPV_USER;
  2. ABF_SYS_USER_MANAGE_ORG_ROLE,问题:除去前缀ABF_SYS_,表含义(USER_MANAGE_ORG_ROLE)超过了3个单词。

4、字段

【强制】每个字段必须有comment 表结构规范,每个表中都应该包含一下几个字段

字段:id varchar(64) 主键,使用雪花算法生成 字段:create_time datetime 创建时间 字段:update_time datetime 更新时间 字段:tenant_id varchar(64) 租户ID

a) 表的字段数不超过50个。 b) 类型:各表之间相同含义的字段,类型定义要完全相同(包括精度、默认值等); c) 命名: 1). 字段名无单词数的限制,但是名字的字符长度应该符合上面的“总命名规范”。 2). 字段命名及其注释,要做到清楚、无歧义。

举两个实际的例子,

1)有些数据可能会存在多种完全不同类型的状态,例如,例如汽车数据,有启停状态,参保状态,维修状态,年审状态……总之,在有些数据表中,有许多的状态字段。如果没写清楚,例如有个字段 “STATUS tinyint NULL; -- 状态”,这是让人很疑惑的,状态?到底是什么状态?状态的取值有哪些?——如果改成“DELETE_STATUS tinyint default 0; -- 删除状态(1:已删除,默认为0:未删除)”,这样的命名和注释,让人一目了然。

2)再比如“belong_dept -- 所属部门”,这也有歧义,因为部门除了数据唯一ID之外,还有一个部门编码CODE也是唯一的。那到底是存 部门ID,还是 部门编码 CODE?实际情况是,有的人认为存ID,有的却认为存编码。所以,在命名上就应该做到无歧义,如果要存ID,就应该命名为“belong_dept_id -- 所属部门ID”,如果要存部门编码,就应该为“belong_dept_code -- 所属部门编码”。

  1. 同一个字段名在一个数据库中只能代表一个意思。比如phone在一个表中代表“座机号码”的意思,在另外一个表中就不能代表其他意思(比如手机名称、品牌等,否则在A表中phone存的是座机号码,在B表中存的是手机品牌,那就混乱了)

  2. 反之,代表同一个意思的字段,在各个表中都用相同单词表示,例如电话号码字段,在A表中叫telephone,在B表中叫phone,在C表中叫mobile,这样就很混乱。

    特殊情况:如果有多个字段时,可以加前缀或后缀区分,代表复数含义时,单词后可以加s,例如user_ids。比如“电话号码”,在A表字段中名称为tel,在B表中也只能叫做tel(但是如果B表中有多种电话号码,可以加后缀,例如 保卫部 tel_bw,科技部 tel_kj,综合部 tel_zh)。

  3. 对于多个表关联的外键字段,例如 create_user_id,关联的是 user表里面 id 字段,建议的命名规则是 “关联表名(无需前缀)+"_"+关联字段名”,也就是说,单词是根据表和字段名而来的,不是凭空随便想出来的。例如这个 create_user_id,create_是前缀,user_代表 abf_sys_user表,id代表abf_sys_user表的id字段。再比如create_user_dept_code,user_是abf_sys_user表的后缀,dept_是abf_sys_dept表的后缀,code是abf_sys_dept表的code_字段。

    综合第4、5点,再举一例:有一个部门表abf_sys_dept,里面有一个部门编码字段code_,如果有一个表需要保存 "责任部门编号" 和 "创建人所属部门编号",按照规范,这两个字段可以命名为:resp_dept_code 和 create_user_dept_code。

5、主键名

默认主键为ID,varchar(19) 使用雪花算法生成

6、外键名

以 外键表名 + 外键字段名构成。例如sys_user_id。 不建议使用强外键关联

7、普通索引

前缀为IDX_。以IDX_+表名+索引字段名构成。如果复合索引的构成字段较多,则只包含第一个字段,并添加序号。表名可以去掉前缀。例如IDX_SYS_CAR_DIN。

8、主键索引

前缀为IDX_PK_。以IDX_PK_+表名+索引字段名构成。表名可以去掉前缀。例如IDX_PK_SYS_CAR_ID。

9、唯一索引

前缀为IDX_UK_。以IDX_UK_+表名+索引字段名构成。表名可以去掉前缀。例如IDX_UK_SYS_CAR_DIN。

10、外键索引

前缀为IDX_FK_。以IDX_FK_+表名+外键字段名构成。表名可以去掉前缀。例如IDX_FK_SYS_CAR_ID。

二、字段设计规范

1、凡是可能被索引的字段,必须定义为NOT NULL,可以设置default值;

2、非负值的数字统一使用unsigned(无符号)类型存储 ??

为了规范命名,并结合一般命名习惯,指定如下几个字段定义(以Oracle为例):

字段:id varchar(64) 主键,使用雪花算法生成 字段:code varchar(32) 编码 字段:tenant_id varchar(64) 租户ID 字段:create_time datetime 创建时间 字段:update_time datetime 更新时间

字段:sort int 排序序号

字段:status char(1) 状态:默认0-启用,1-不启用 字段:delete_status char(1) 删除标记,默认0-未删除,1-已删除

三、其他

1、主键ID

使用分布式全局唯一递增ID,比如类snowflake算法。 或者自定义自增主键例如根级别(1000),子级别(100001、100002) 为了方便数据库迁移,禁止使用存储过程、视图、事件、触发器、数据库自带的分区表。

四、线上禁止使用的SQL语句

1.【高危】禁用update|delete t1 … where a=XX limit XX; 这种带limit的更新语句。因为会导致主从不一致,导致数据错乱。建议加上order by PK。 2.【高危】禁止使用关联子查询,如update t1 set … where name in(select name from user where…);效率极其低下。 3.【强制】禁用procedure、function、trigger、views、event、外键约束。因为他们消耗数据库资源,降低数据库实例可扩展性。推荐都在程序端实现。 4.【强制】禁用insert into …on duplicate key update…在高并发环境下,会造成主从不一致。 5.【强制】禁止联表更新语句,如update t1,t2 where t1.id=t2.id…。