跳到主要内容

数据库规范

命名

建表时统一规范字段索引的命名,能够提高沟通效率和降低维护成本。

见名知意

反例

-- 用户名字段
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。

主要有以下原因:

  1. 在 innodb 中,需要额外的空间存储 null 值,需要占用更多的空间。
  2. null 值可能会导致索引失效。
  3. 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 字符集

字符集长度功能备注
latin11默认字符集容易出现乱码,使用较少
gbk2支持中文,非国际通用字符不支持国际通用字符,使用不多
utf-83支持中英文混合,国际通用字符集相对 utf8mb4 占用存储更少,不支持 emoji
utf8mb44兼容 UTF-84 个字节支持存储更多字符,支持 emoji

排序规则

数据表创建时 COLLATE 参数可以设置排序规则,排序规则与字符集相关。

数据表使用 utf8mb4 时字符排序规则以 utf8mb4_ 开头的,常用排序规则 utf8mb4_general_ci 、utf8mb4_bin 等。

  • utf8mb4_general_ci:不区分字母大小

  • utf8mb4_bin:区分字母大小

建议字符排序规则务必根据实际的业务场景选择,否则容易出现不可预测的问题。

大字段

大字段即占用较多存储空间的字段,建议大字段定义成 varchar 类型

例如用户的评论就属于大字段,但是字段长度不唯一,所以一般会限制总长度。