数据库规范
命名
建表时统一规范表、字段和索引的命名,能够提高沟通效率和降低维护成本。
见名知意
反例
-- 用户名字段
yong_hu_ming
用户_name
name
user_name_123456789
正例
-- 用户名字段
user_name
字段不宜过长,尽量控制在 30 个字符以内。
大小写
统一采用小写字母;因为从视觉上小写字母更容易让人读懂,所以采用小写字母。
反例:
-- 字段名
PRODUCT_NAME
PRODUCT_name
正例:
-- 字段名
product_name
分隔符
多个单词之间使用半角下划线作为分隔符。
反例
-- 字段名
productname
productName
product name
product@name
正例:
-- 字段名
product_name
表名
对于表名,在见名知意的基础之上带上前缀;以便于归类区分,同时避免出现同名表。
-- 业务表
order_pay
order_pay_detail
-- 商品表
product_spu
product_sku
字段名称
数据表内常用公共字段采用统一命名。
-- 状态字段
status
-- 创建时间、修改时间
create_time
update_time
-- 外键
表名_字段
索引名
在数据库中,索引有主键、普通索引、唯一索引、联合索引等。
表主键:一般使用 id 命名。
普通索引和联合索引: ix_ 前缀。
唯一索引: ux_ 前缀。
字段类型
- 尽可能选择占用存储空间小的字段类型,在满足正常业务需求的情况下,从小到大,往上选。
- 如果字符串长度固定,或者差别不大,可以选择 char 类型;如果字符串长度差别较大,可以选择varchar类型。
- 是否字段:建议选择 bit 类型。
- 枚举字段:建议选择 tinyint 类型。
- 主键字段:建议选择 bigint 类型。
- 金额字段:建议选择 decimal 类型。
- 时间字段:建议选择 timestamp 或 datetime 类型。
字段长度
在 MySQL 中除了 varchar 和 char 是字符长度之外,其余的类型都是字节长度。
例如 bigint(4)实际长度是 8 个字节。
字段个数
数据表的字段尽量不要超过 20 个。
特殊情况可以将一张表拆成多张表形成组合表,其主键相同。
主键
数据表必须拥有主键,因为主键拥有自带索引并且不需要回表,所以相比于其他索引查询效率最高。
数据表主键建议保存跟业务无关的值,减少业务耦合性方便扩展。
单体数据库中,主键可以设置 AUTO_INCREMENT(自动增长)。
分布式数据库中,尤其是分库分表的业务库中,主键最好由外部算法(比如:雪花算法)生成,并且保证生成的 id 是全局唯一的。
存储引擎
建议在使用 MySQL8 以后的版本时,使用默认的 innodb 存储引擎,无需修改存储引擎。
NOT NULL
在定义字段时,应该尽可能明确该字段 NOT NULL。
主要有以下原因:
- 在 innodb 中,需要额外的空间存储 null 值,需要占用更多的空间。
- null 值可能会导致索引失效。
- null 值只能用 is null 或者 is not null 判断,用等于号判断永远返回 False。
外键
外键主要作用是保证数据的一致性和完整性。
create table class (
id int(10) primary key auto_increment,
cname varchar(15)
);
create table student(
id int(10) primary key auto_increment,
name varchar(15) not null,
gender varchar(10) not null,
cid int,
foreign key(cid) references class(id)
);
上述两个数据表 class 和 student 中,如果直接删除 student 表的 行数据,因为存在外键关联,所以就会报异常。必须要先删除 class 表对应的 student 表中 cid 那行数据,再删除 student 表的数据才能够保证数据的一致性和完整性。
只有存储引擎是innodb时,才能使用外键。如果注重性能的场景下,建议不使用外键、存储过程和触发键。
索引
创建数据表时,不仅可以指定主键索引,还可以创建普通索引;建议单个数据表的普通索引不要超过 5 个。
create table product_sku (
id int(10) primary key auto_increment,
spu_id int(10) not null,
brand_id int(10) not null,
name varchar(15) not null,
KEY `ix_spu_id` (`spu_id`) USING BTREE,
KEY `ix_brand_id` (`brand_id`) USING BTREE
);
数据表创建时,添加 ix_spu_id、ix_brand_id 普通索引,可以提高检索数据效率。
时间字段
目前 MySQL 支持 date、datetime、timestamp、varchar 等时间类型,建议使用 datetime。
varchar:存储时间的类型是 String,无法创建索引。
date:适用于保存日期,比如:2020-08-20 12:12:20。
timestamp:4 个字节,取值范围为 1970-01-01 00:00:01 UTC ~ 2038-01-19 03:14:07,受时区影响。
datetime:8个字节,取值范围为 1000-01-01 00:00:00 ~ 9999-12-31 23:59:59,不受时区影响。
金额字段
MySQL 中 float、double、decimal 等支持浮点数。
因为 float 和 double 可能会丢失精度,所以建议使用 decimal 类型保存金额数值。
定义浮点数 decimal(m,n),n 是小数的长度,m 是整数和小数的总长度。
唯一索引
唯一索引支持单个字段、多个字段联合。
如果多个字段联合的唯一索引字段值出现 null,那么唯一性约束可能会失效。
字符集
MySQL 中常用字符集的有 latin1、gbk 、utf-8、utf8mb4 等,建议使用 utf-8 字符集。
字符集 | 长度 | 功能 | 备注 |
---|---|---|---|
latin1 | 1 | 默认字符集 | 容易出现乱码,使用较少 |
gbk | 2 | 支持中文,非国际通用字符 | 不支持国际通用字符,使用不多 |
utf-8 | 3 | 支持中英文混合,国际通用字符集 | 相对 utf8mb4 占用存储更少,不支持 emoji |
utf8mb4 | 4 | 兼容 UTF-8 | 4 个字节支持存储更多字符,支持 emoji |
排序规则
数据表创建时 COLLATE 参数可以设置排序规则,排序规则与字符集相关。
数据表使用 utf8mb4 时字符排序规则以 utf8mb4_ 开头的,常用排序规则 utf8mb4_general_ci 、utf8mb4_bin 等。
utf8mb4_general_ci:不区分字母大小。
utf8mb4_bin:区分字母大小。
建议字符排序规则务必根据实际的业务场景选择,否则容易出现不可预测的问题。
大字段
大字段即占用较多存储空间的字段,建议大字段定义成 varchar 类型。
例如用户的评论就属于大字段,但是字段长度不唯一,所以一般会限制总长度。