前言
设计表结构时,你会遇到一些固定选项值的字段。例如,性别字段(Sex),只有男或女;又或者状态字段(State),有效的值为运行、停止、重启等有限状态。大多数开发人员喜欢用 INT 的数字类型去存储性别字段,这种做法有一些弊端:
- 表达不清:在具体存储时,0 表示女,还是 1 表示女呢?每个业务可能有不同的潜规则;
- 脏数据:因为是 tinyint,因此除了 0 和 1,用户完全可以插入 2、3、4 这样的数值,最终表中存在无效数据的可能,后期再进行清理,代价就非常大了。
使用 check 约束功能
自MySQL 8.0.16
版本开始,数据库原生提供check
约束功能,可以方便地进行有限状态列类型的设计。
新建一个 user 表,使用check (sex = 'M' OR sex = 'F')
对sex
字段进行约束,只允许插入M
和F
:drop table if exists user;
create table user (
id bigint unsigned auto_increment primary key,
name varchar(10) not null default '' comment '用户名',
sex char(1) not null default '' comment '性别',
check (sex = 'M' OR sex = 'F')
) comment '用户表';
测试插入数据
如果 sex 字段插入合法的值: ```sql mysql> insert into user(name, sex) VALUES (‘username1’, ‘M’); Query OK, 1 row affected (0.02 sec)
mysql> select * from user; +——+—————-+——-+ | id | name | sex | +——+—————-+——-+ | 1 | username1 | M | +——+—————-+——-+ 1 row in set (0.00 sec)
如果 sex 字段插入非法的值,报错:
```sql
mysql> insert into user(name, sex) VALUES ('username2', 'G');
ERROR 3819 (HY000): Check constraint 'sex_check' is violated.