1. 存储引擎的选择
MySQL支持数个存储引擎作为对不同表的类型的处理器,MySQL中的插件式存储引擎架构是非常有特色的亮点。如无特殊要求,默认使用innodb存储引擎,该引擎为5.6版本中的默认存储引擎。
MySQL引擎 | 说明 |
InnoDB | 索引和数据都可以缓存到内存中; 支持事务; 支持行级锁,可实现更高的并发度; 支持故障恢复; 支持外键约束; 支持4种不同的事务隔离级别; |
2. 字符集的选择
Utf8MB4作为字符集的惟一选择。
如使用导出工具,须显式选择utf8mb4作为导出格式。
在开发环境中编写的建库建表脚本及使用工具导出的数据脚本文件,如在进库前需要编辑,必须使用纯文本方式打开,编辑和保存,防止隐含控制字符(如^M)添加进脚本。在Linux环境,可以通过 “cat -A脚本文件名”方式确认和检查是否携带了隐含控制字符。
3. 数据库设计规范
控制单库表个数,建议单库不超过4096个表。
创建数据库的语句必须包含字符集子句和校对规则子句。如:
create database [if not exists]
default character set UTF8MB4 default collate utf8mb4_bin;
4. 表设计规范
表必须要有PK。
一个字段只表示一个含义。
总是包含四个字段:created_time(创建日期),updated_time(修改日期),created_by(创建人),updated_by(修改人) 且这四个字段不应该包含有额外的业务逻辑,在创建或修改记录的时候,必须创建这四个字段。
示例:
创建时间 created_time timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间' ;
修改时间 updated_time timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改日期';
创建人 created_by VARCHAR2(50) COMMENT '创建人';
修改人 updated_by VARCHAR2(50) COMMENT '修改人';
禁止使用复杂数据类型(数组,自定义等)。
需要join的字段(连接键),数据类型必须保持绝对一致,避免隐式转换。
设计应至少满足第三范式,尽量减少数据冗余。一些特殊场景允许反范式化设计,但在项目评审时需要对冗余字段的设计给出解释。
不建议使用TEXT、BLOB字段。如有需求,建议将TEXT字段放在独立的表中,用PK与主表关联。
单表字段数不要太多,建议最多不要大于50个。
MySQL在处理大表时,性能就开始明显降低,所以建议单表物理大小限制在10GB。
如果数据量或数据增长在前期规划时就较大,那么在设计评审时就应加入分表策略。
无特殊需求,严禁使用分区表。
5. 字段设计规范
INT:如无特殊需要,存放整型数字使用UNSIGNED INT型。整型字段后的数字代表显示长度。整型类型如下表:
数据类型 | 最大存储长度(有符号) | 最大存储长度(无符号) |
tinyint(m) | 1个字节 范围(-128~127) | 1个字节 范围(0~256) |
smallint(m) | 2个字节 范围(-32768~32767) | 2个字节 范围(0~65535) |
mediumint(m) | 3个字节 范围(-8388608~8388607) | 3个字节 范围(0~16777215) |
int(m) | 4个字节 范围(-2147483648~2147483647) | 4个字节 范围(0~4294967294) |
bigint(m) | 8个字节 范围(+-9.22*10的18次方) | 8个字节 范围(0~1.84*10的20次方) |
DECIMAL(M,D):定点小数使用此DECIMAL类型,且明确标识出为无符号型(UNSIGNED),除非确实会出现负数。
DATE:所有只需要精确到天的字段全部使用DATE类型,而不应该使用TIMESTAMP或者DATETIME类型。
DATETIME:所有需要精确到时间(时分秒)的字段均使用DATETIME,不要使用TIMESTAMP类型。
VARCHAR:所有动态长度字符串 全部使用VARCHAR类型,类似于状态等有限类别的字段,也使用可以比较明显表示出实际意义的字符串,而不应该使用INT之类的数字来代替;VARCHAR(N),N表示的是字符数而不是字节数。比如VARCHAR(255),可以最大可存储255个字符(字符包括英文字母,汉字,特殊字符等)。但N应尽可能小,因为MySQL一个表中所有的VARCHAR字段最大长度是65535个字节,且存储字符个数由所选字符集决定。如UTF8存储一个字符最大要3个字节,那么varchar在存放占用3个字节长度的字符时不应超过21845个字符。同时,在进行排序和创建临时表一类的内存操作时,会使用N的长度申请内存。
如无特殊需要,原则上单个varchar型字段不允许超过255个字符。
CHAR:仅仅只有单个字符的字段使用CHAR(1)类型,例如性别字段。
TEXT:仅仅当字符数量可能超过20000个的时候,才可以使用TEXT类型来存放字符类数据,因为所有MySQL数据库都会使用UTF8字符集。所有使用TEXT类型的字段必须和原表进行分拆,与原表主键单独组成另外一个表进行存放。如无特殊需要,严禁开发人员使用MEDIUMTEXT、TEXT、LONGTEXT类型。
使用INT UNSIGNED型存储IPV4。PHP程序推荐使用long型存储IPV4(非强制)。
对于精确浮点型数据存储,需要使用DECIMAL,严禁使用FLOAT和DOUBLE。
如无特殊需要,严禁开发人员使用BLOB类型。
如无特殊需要,字段必须使用NOT NULL属性,可用默认值代替NULL。MySQL NULL类型和Oracle的NULL有差异,会进入索引中。此外,NULL在索引中的处理也是特殊的,也会占用额外的存放空间。
不建议使用ENUM、SET类型,使用TINYINT来代替。
每个列定义的时候必须加上COMMENTS。
自增字段类型必须是整型且必须为UNSIGNED,推荐类型为INT或BIGINT,并且自增字段必须是主键或者主键的一部分。
日期类型的字段不能使用VARCHAR或者CHAR类型,只能使用DATE、DATETIME字段类型存放。
6. 索引设计规范
索引必须创建在索引选择性选择性较高的列上。
索引选择性:索引列中不同值的数目与表中记录数的比值。如SEX字段共100条记录,只存放男、女两个值,则在SEX列上创建的索引idx_sex的索引选择性为2/100=0.02
组合索引的首字段,必须在where条件中。
对于确定需要组成组合索引的多个字段,建议将选择性高的字段靠前放。
禁止使用外键,容易产生死锁,应由程序保证参照完成性。
Text类型字段必须使用前缀索引。
单张表的索引数量理论上应控制在5个以内。经常有大批量插入、更新操作表,应尽量少建索引。
组合索引中的字段数建议不超过5个。
禁止对过长(MySQL的varchar索引只支持不超过768个字节,UTF8是三字节,即:768/3=256,所以字段最长为255)的VARCHAR类型字段建立索引,除前缀索引外超过32字节的varchar列加索引需要DBA评估。如果需要对超过32字节的varchar列整列进行完全匹配,需要新增一个字段,该字段是varchar列的md5值,使用md5来进行完全匹配;这种情况下,就无法进行范围查询。
7. 约束设计规范
PK应该是有序并且无意义的,尽量由开发人员自定义,且尽可能短,使用自增序列。建议ID BIGINT
表中除PK以外,还存在唯一性约束的,可以在数据库中创建以“uk_”作为前缀的唯一约束索引。
PK字段不允许更新。
禁止创建外键约束,外键约束由应用控制。
如无特殊需要,所有字段必须添加非空约束。
如无特殊需要,所有字段必须有默认值。