2023年7月27日发(作者:)
数据库设计规范-通⽤版⼀、命名规范1、总命名规范1、不得使⽤数据库保留关键字,以及php/java等常⽤语⾔的保留关键字,或者可能成为关键字的单词作为完整命名。(对于⼀些疑似关键字的单词,可以在后⾯加⼀个下划线来避免,例如“key_”)。【附:MySQL保留关键字列表:】2、如⽆特殊说明,名称必须⽤英⽂字母开头,采⽤有特征含义的单词或缩写,单词中间⽤“_”分割,且只能由英⽂字母、数字和下划线组成,不能⽤双引号包含。3、除数据库名称长度为1⾄8个字符,其余(包括表、字段、索引等)不超过30个字符,Database link名称也不要超过30个字符。(30并不是凭空想象出来的,⽽是参考了Oracle的限制)2、表名(建议以2-3字项⽬名称为前缀开头),紧跟2-5个字符(英⽂字母或数字,但不得全是数字)的模块名(必须),最后跟上当前表的含义的单词(1-3个单词,⽤下划线连接),例如:SQ_SYS_CAR,SQ是项⽬名称的缩写,SYS是模块名称的缩写,CAR表⽰当前表的具体含义。
特别强调:项⽬名称和模块名⽤简写(建议长度为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个单词。3、字段名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 -- 所属部门编码”。3. 同⼀个字段名在⼀个数据库中只能代表⼀个意思。⽐如phone在⼀个表中代表“座机号码”的意思,在另外⼀个表中就不能代表其他意思(⽐如⼿机名称、品牌等,否则在A表中phone存的是座机号码,在B表中存的是⼿机品牌,那就混乱了)4. 反之,代表同⼀个意思的字段,在各个表中都⽤相同单词表⽰,例如电话号码字段,在A表中叫telephone,在B表中叫phone,在C表中叫mobile,这样就很混乱。 特殊情况:如果有多个字段时,可以加前缀或后缀区分,代表复数含义时,单词后可以加s,例如user_ids。⽐如“电话号码”,在A表字段中名称为tel,在B表中也只能叫做tel(但是如果B表中有多种电话号码,可以加后缀,例如 保卫部 tel_bw,科技部 tel_kj,综合部tel_zh)。5. 对于多个表关联的外键字段,例如 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。
4、主键名前缀为PK_。以PK_+表名+主键字段名构成。如果复合主键的构成字段较多,则只包含第⼀个字段。表名可以去掉前缀。例如PK_SYS_CAR_ID。5、外键名前缀为FK_。以FK_+ 外键表名 + 主键表名 + 外键字段名构成。表名可以去掉前缀。例如FK_SYS_USR_SYS_CAR_ID。6、普通索引前缀为IDX_。以IDX_+表名+索引字段名构成。如果复合索引的构成字段较多,则只包含第⼀个字段,并添加序号。表名可以去掉前缀。例如IDX_SYS_CAR_DIN。7、主键索引前缀为IDX_PK_。以IDX_PK_+表名+索引字段名构成。表名可以去掉前缀。例如IDX_PK_SYS_CAR_ID。8、唯⼀索引前缀为IDX_UK_。以IDX_UK_+表名+索引字段名构成。表名可以去掉前缀。例如IDX_UK_SYS_CAR_DIN。9、外键索引前缀为IDX_FK_。以IDX_FK_+表名+外键字段名构成。表名可以去掉前缀。例如IDX_FK_SYS_CAR_ID。10、Oracle序列前缀为SEQ_。以SEQ_+“序列业务名称”构成。如果“序列业务名称”就是某个表名,则使⽤表的全名,不可去掉前缀。例如SEQ_SQ_SYS_CAR。⼆、表设计规范1. 采⽤UTF8字符集。2. 对于数据量可能很⼤的表(超过2000万),采⽤分库/分表/分区表,横向拆分控制单表容量。3. 必须为表、字段等添加注释。4. 遵守数据的设计规范3NF 规定。1. 表内的每⼀个记录都只能被表达⼀次。2. 表内的每⼀个记录都应该被唯⼀的标识(有唯⼀键)。3. 表内不应该存储依赖于其他键的⾮键信息。1. 反范式化冗余字段使⽤规范 考虑具体使⽤场景,当SQL关连查询⽐较频繁,或涉及到4张以上表时可考虑采⽤冗余字段。2. 必须设置唯⼀主键,尽量使⽤⾃增id作为主键。3. 建议主键为数字类型,且为递增顺序,主键不表⽰任何业务含义,严禁数据量⼤的表使⽤UUID/MD5作为主键。4. 不使⽤数据库外键,由程序保证。5. MySQL:1. 使⽤InnoDB存储引擎。2. 数据库和表字符集类型统⼀(utf8mb4 -- UTF-8 Unicode),排序规则统⼀(utf8mb4_unicode_ci);建表语句中强制指定字符集;3. ⾃增字段类型必须是整型,使⽤ BIGINT类型。并且⾃增字段必须是主键或者是主键的⼀部分。三、字段设计规范1、凡是可能被索引的字段,必须定义为NOT NULL,可以设置default值;2、⾮负值的数字统⼀使⽤unsigned(⽆符号)类型存储 ??2、⼤对象字段1. 通常情况下,禁⽌使⽤LOB类型保存⼤⽂本、图⽚和⽂件,建议使⽤其他⽅式存储(例如⽂件系统,数据库只保存其地址信息)。2. MySQL:尽量不要使⽤TEXT数据类型,mysql的varchar类型⽀持65535字节,满⾜⼤多数场景,仅当字符数特别⼤时,才考虑text类型;附——⼤对象字段处理⽅法:1. 将⼤对象字段从主表中拆分出来单独存放,与原表主键单独存储在另外⼀个表⾥;2. 如果是Oracle 12g之前的版本,VARCHAR2最多⽀持4000,如果⽂本内容只是偶尔可能超过4000,但是不会超过8000,那么可以⽤两个VARCHAR2字段来存储,使⽤的时候将这两个字段拼接起来就⾏了。3. 如果有⽅便的⽂件系统,可以将⼤⽂本或附件,保存在⽂件系统中,数据库中只保存其位置和路径信息即可。3、禁⽌使⽤enum,对于boolean类型或者表⽰简单状态的字段,MySQL⽤tinyint,Oracle⽤NUMBER(1)1. 建议字段not null,根据业务要求来设置默认值(例如默认为0)。2. 对于boolean类型,以1代表是(true), 0 代表否(false)。3. 对于状态类型,注释中应该注明每⼀种状态的含义,例如“0:编辑中,1:审核中,2:已完成”。4、数字、⼩数类型1. 对于数字、⼩数类型,不得使⽤VACHAR等字符串类型来保存,应该使⽤相应精度的数字、⼩数类型。2. 尽量确保数值型列都有默认值3. 对于Oracle,确定好Number的精度。4. 对于MySQL,选好数字类型:TINYINT>SMALLINT>MEDIUMINT>INT>BIGINT>DECIMAL(存储空间逐渐变⼤,⽽性能却逐渐变⼩),超过tinyint(256)但不超过65536的使⽤smallint;当该字段超过42亿时,才使⽤bigint;5. 使⽤DECIMAL 代替 FLOAT 和 DOUBLE 存储精确浮点数??why?5、时间类型标准对于Oracle,有两种时间类型:DATE和TIMESTAMP,DATE的精度只保存到秒,例如“2013-11-02 11:16:36”,⽽TIMESTAMP精度更⾼可以保存⼩数秒,例如“2013-11-03 11:16:36.000000” 。有时候,DATE只保存到秒,不⾜够区别出两个事件哪个先发⽣,这时建议使⽤TIMESTAMP类型。MySQL:存储年使⽤year类型,存储⽇期使⽤date类型,使⽤精确时间戳(精确到秒)尽量使⽤timestamp类型,因为timestamp使⽤4字节,datetime使⽤8字节,它们的区别:TIMESTAMP值不能早于1970或晚于2037('1970-01-01 00:00:01' UTC to '2038-01-19 03:14:07' UTC)。5、必须使⽤int unsigned存储IPV4;6、⼀些常见字段的命名统⼀为了规范命名,并结合⼀般命名习惯,指定如下⼏个字段定义(以Oracle为例):ID 编号 NUMBER(22)(Integer)Create_By 创建⼈ NUMBER(22)(Integer)Create_Time 创建时间 TIMESTAMP --默认为系统当前时间Update_By 修改⼈ NUMBER(22)(Integer)Update_Time 修改时间 TIMESTAMP --默认为系统当前时间其他参考命名:Code_ 编码 VARCHAR2(30)Level_ 层级 NUMBER(1或2)Delete_Status 删除标志 NUMBER(1) --1:表⽰已经删除,默认为0:表⽰未删除Description_ 描述或备注 VARCHAR2(200)
四、索引规范复合索引的字段数不能超过5个。单表的索引数量尽量控制在5个以内。联合索引的字段排列顺序以去重后字段的数值的个数⼤⼩排序先后顺序。⽐如表mk_task有id,name,id有50000个独⽴值,name有5000个独⽴值,那么,顺序是id在name前⾯,建⽴的索引是idx_id_name。Order by、distinct、group by后的字段尽量建⽴索引。update、delete的where尽量使⽤有索引的字段或主键。超过20字节的varchar字段建议⽤前缀索引,禁⽌对字符串长度超过50个字符的列创建索引。不建议在低基数列上创建索引,例如“性别”列;合理创建联合索引(避免冗余),(a,b,c) 相当于(a)、(a、b)、(a、b、c)。长⽂本类型字段(例如Text)不能使⽤索引。
五、其他1、主键ID建议使⽤分布式全局唯⼀递增ID,⽐如类snowflake算法,很多⼤公司都在⽤,有许多成熟的案例,⽽且百度、腾讯、美团都把⾃⼰的ID⽣成⼯具开源了。禁⽌使⽤存储过程、视图、事件、触发器、数据库⾃带的分区表。临时库、表名必须以”tmp_⽇期”为后缀,如当⽇创建多个,则在⽇期后增加数字后缀;备份库、表必须以”bak_⽇期”为后缀,如当⽇创建多个,则在⽇期后增加数字后缀;
发布者:admin,转转请注明出处:http://www.yc00.com/news/1690431198a348918.html
评论列表(0条)