MySQL表约束:
在数据库设计中,光靠数据类型限制字段远远不够。MySQL提供了多种表约束,从业务逻辑层面保证数据正确、合法,避免脏数据入库。本文梳理MySQL常用的全部表约束,附带代码示例与实战案例。
一、空属性:null / not null
NULL:字段可以为空,是MySQL的默认行为。NULL不能参与运算,任何值和NULL做计算结果依旧是NULL。NOT NULL:该字段不允许存入空值。实际开发尽量优先使用NOT NULL,防止空值带来统计、运算异常。
示例建表,班级名称和教室都不能为空:
sql
create table myclass(
class_name varchar(20) not null,
class_room varchar(10) not null
);
当插入数据不给class_room赋值,直接报错:Field 'class_room' doesn't have a default value。
二、默认值 default
如果某个字段大部分场景都是同一个值,可以设置default默认值。插入数据时不给该字段传值,就自动使用预设默认值。
sql
create table tt10 (
name varchar(20) not null,
age tinyint unsigned default 0,
sex char(2) default '男'
);
sql
-- 只插入name,age、sex自动使用默认值
insert into tt10(name) values('zhangsan');
注意:只有设置default的列,插入时才可以省略赋值。
三、列注释 comment
comment仅仅是字段说明注释,不会对数据做任何约束 ,方便开发者、DBA看懂字段含义。
desc 表名无法查看注释,需要用show create table 表名\G查看完整建表语句。
sql
create table tt12 (
name varchar(20) not null comment '姓名',
age tinyint unsigned default 0 comment '年龄',
sex char(2) default '男' comment '性别'
);
四、zerofill 零填充
很多人疑惑int(5)括号里面数字代表什么:没有zerofill时,这个数字没有实际作用。
开启zerofill:查询展示的时候,数字不足设置的宽度,前面自动补0;但是数据库底层存储仍然是原始数字,只是格式化显示效果。
sql
alter table tt3 change a a int(5) unsigned zerofill;
例如存入数字1,查询输出显示00001,内部存储依旧是1,可以用hex(a)验证。
注意:zerofill只作用于查询展示,不改变真实存储。
五、主键 primary key
主键两大特性:唯一、非空,一张表最多只能有一个主键。一般选用整型字段充当主键。
1. 单字段主键
sql
create table tt13 (
id int unsigned primary key comment '学号',
name varchar(20) not null
);
主键字段不能重复,重复插入会报Duplicate entry错误。
追加、删除主键语法:
sql
alter table 表名 add primary key(字段列表);
alter table 表名 drop primary key;
2. 复合主键
多个字段联合作为主键,只有全部字段组合重复才会触发冲突。
sql
create table tt14(
id int unsigned,
course char(10) comment '课程代码',
score tinyint unsigned default 60 comment '成绩',
primary key(id, course)
);
六、自增长 auto_increment
auto_increment:字段不传值,自动取表中该字段最大值+1生成新值。
使用限制:
- 字段必须是索引;
- 必须是整数类型;
- 一张表最多只能有一个自增长字段;
- 经常和主键搭配使用。
sql
create table tt21(
id int unsigned primary key auto_increment,
name varchar(10) not null default ''
);
获取上一次自增生成的值:
sql
select last_insert_id();
七、唯一键 unique key
主键一张表只能有一个,如果业务中多个字段需要保证不重复,就使用唯一键。
和主键区别:
- 主键不允许NULL;唯一键允许存NULL,允许多条NULL,NULL之间不做唯一性对比。
- 一张表只能一个主键,但可以设置多个唯一键。
sql
create table student (
id char(10) unique comment '学号,不能重复,可以为空',
name varchar(10)
);
业务场景举例:员工表,主键使用无关业务的id,身份证、工号设置为唯一键,保证业务字段不重复。
八、外键 foreign key
外键用来维护主表(父表)和从表(子表) 的关联关系,写在从表上。
要求:主表被引用的列,必须是主键或者唯一键;从表外键的值,要么在主表中存在,要么为NULL。
语法:foreign key(从表字段) references 主表(主表字段)
示例:班级为主表,学生为从表,学生的class_id关联班级表id。
sql
-- 主表:班级
create table myclass (
id int primary key,
name varchar(30) not null comment'班级名'
);
-- 从表:学生
create table stu (
id int primary key,
name varchar(30) not null comment '学生名',
class_id int,
foreign key (class_id) references myclass(id)
);
此时插入不存在的班级id会直接报错;class_id可以插入null,代表学生暂时没有分配班级。
外键作用:把表与表业务上的依赖关系交给MySQL校验,从数据库层面杜绝非法关联脏数据。
总结
| 约束 | 作用 | 关键点 |
|---|---|---|
| not null | 禁止字段为空 | 开发尽量多用,NULL无法参与运算 |
| default | 设置字段默认值 | 插入省略字段自动填充默认值 |
| comment | 字段注释 | 仅说明,show create table查看 |
| zerofill | 数字零填充 | 只改变展示,存储不变 |
| primary key | 主键,唯一且非空 | 一张表仅一个主键,可复合主键 |
| auto_increment | 自增长 | 整数+索引,一张表最多一个 |
| unique key | 唯一键,值不能重复 | 允许NULL,可设置多个 |
| foreign key | 外键,表关联约束 | 定义在从表,引用主表主键/唯一键 |
数据库约束是数据的第一道防线,在建表阶段合理使用约束,能大幅减少业务层代码校验的压力,避免很多意想不到的数据异常。