一、概念
数据库约束是作用于表中字段上的规则,用于限制存储在表中的数据。使用约束可以保证数据库中数据的正确、有效和完整。我们可以在创建表或修改表的时候在表字段上添加约束。
常见的约束类型如下图所示:
约束类型 | 关键字 | 描述 |
非空约束 | NOT NULL | 限制该字段的数据不能为null |
唯一约束 | UNIQUE | 保证该字段的数据是唯一的、不可重复的 |
主键约束 | PRIMARY KEY | 主键是一行数据的唯一标识,要求非空且唯一 |
默认约束 | DEFAULT | 保存数据时,如果没有指定该字段的值,则采用默认值 |
检查约束 | CHECK | 插入数据值根据指定条件校验数据的合法性 |
外键约束 | FORENGN KEY | 用来让两张表的数据之间建立连接,保证数据的完整性和一致性 |
我们可以把约束分为两类,普通约束和外键约束。普通约束包含主键约束、非空约束、唯一约束、检查约束、默认约束。
二、普通约束
1.建表时添加约束
我们在建表时可以添加主键约束、非空约束、默认约束、检查约束、唯一约束等。
CREATE TABLE t_user (
id BIGINT PRIMARY KEY auto_increment NOT NULL,
name VARCHAR ( 50 ) NOT NULL UNIQUE,
age INT CHECK ( age > 0 && age <= 150 ),
status CHAR ( 1 ) DEFAULT '1'
) ENGINE = INNODB
主键ID使用了主键约束和非空约束、name使用了非空约束和唯一约束、age使用了检查约束、status使用了默认约束。
注意:
- 当我们使用
check约束时,约束条件必须写在()
中。 - 当我们使用
default
约束指定默认值时,默认值必须符合字段数据类型。 - 每个表只能为一个字段指定主键
PRIMARY KEY
约束。 - 在一些正常情况下,可以在一个字段上使用多个约束条件。
2.建表后再添加约束的情况
a.添加主键约束
语法:
alter table 表名 add primary key(表字段名);
SQL语句:
ALTER TABLE t_user ADD PRIMARY KEY ( id );
b.添加唯一约束
语法:
ALTER TABLE 表名 add UNIQUE(表字段名);
SQL语句:
ALTER TABLE t_user ADD UNIQUE (name)
c.添加默认约束
语法:
ALTER TABLE 表名 modify 表字段名 数据类型 default 默认值;
SQL语句:
ALTER TABLE t_user MODIFY status CHAR ( 1 ) DEFAULT '1';
d.添加非空约束
语法:
ALTER TABLE 表名 modify 表字段名 数据类型 not null;
SQL语句:
ALTER TABLE t_user modify name varchar(50) not null;
e.添加检查约束
语法:
ALTER TABLE 表名 add CONSTRAINT 表字段名 check(检查条件);
SQL语句:
ALTER TABLE t_user ADD CONSTRAINT age CHECK (age > 0 & age <= 150)
三、外键约束
如果两张表存在某种联系,比如一张表中的某个字段需要依赖于另外一张表,这两个表就存在关联关系,外键约束用于互相约束彼此的行为,从而保证数据的一致性和完整性。
特别说明:
- 添加外键时必须得确保需要关联的父表已经创建
- 一个表可存在多个外键,且可以关联多个表
我们首先创建一个父表
CREATE TABLE t_department (
id BIGINT PRIMARY KEY auto_increment,
name VARCHAR ( 50 ) NOT NULL COMMENT '部门名称')
1.建表时添加外键约束
语法:
CREATE TABLE 表名(
字段名 数据类型,
...
[CONSTRAINT] [外键名称] FOREIGN KEY (子表字段名) REFERENCES 父表 (父表字段名)
);
SQL语句:
CREATE TABLE t_employee (
id BIGINT PRIMARY KEY auto_increment,
name VARCHAR ( 50 ) NOT NULL UNIQUE COMMENT '职工名称',
dept_id BIGINT COMMENT '所属部门',
CONSTRAINT fk_dept_id FOREIGN KEY ( dept_id ) REFERENCES t_department ( id ))
执行完SQL语句之后我们查看t_staff数据表,发现已经成功添加了外键信息。
2.建表后添加外键约束
语法:
ALTER TABLE 表名 ADD CONSTRAINT 外键名称 FOREIGN KEY (子表字段名) REFERENCES 父表 (父表字段名);
我们先删除之间建表时添加的外键约束。
SQL语句:
ALTER TABLE t_employee ADD CONSTRAINT fk_dept FOREIGN KEY ( dept_id ) REFERENCES t_department ( id );
我们执行SQL语句发现我们的外键约束信息再次被添加成功了。
3.外键测试
我们在测试之前先添加一些测试数据。
子表添加外键约束后,默认情况使用的约束行为是RESTRICT,这种行为下我们无法直接删除父表中的数据,必须先删除所有子表中关联该父表记录的数据才能删除父表的数据。
这种情况,我们需要先删除子表的所有关联数据之后,才能删除父表的数据。
4.外键删除
语法:
ALTER TABLE 表名 DROP FOREIGN KEY 外键名称;
SQL语句:
ALTER TABLE t_employee DROP FOREIGN KEY fk_dept;
5.更新、删除行为
常见的外键约束行为如下图所示:
行为 | 说明 |
NO ACTION | 当在父表中更新、删除数据时,首先检查该数据是否有对应的外键,如果有则不允许更新、删除。 |
RESTRICT | 和NO ACTION的行为一致(默认) |
CASCADE | 当在父表中更新、删除数据时,首先检查该数据是否有对应的外键,如果有则会更新、删除子表中的相关数据 |
SET NULL | 当在父表中更新、删除数据时,首先检查该数据是否有对应的外键,如果有则设置子表中该外键值为null |
SET DEFAULT | 父表有变更时,子表将外键列设置成一个默认的值(InnoDB存储引擎不支持) |
语法:
ALTER TABLE 表名 ADD CONSTRAINT 外键名称 FOREIGN KEY (外键字段) REFERENCES
父表名 (父表字段名) ON UPDATE [更新行为] ON DELETE [删除行为]
SQL语句:
CASCADE测试:
ALTER TABLE t_employee ADD CONSTRAINT fk_dept FOREIGN KEY ( dept_id ) REFERENCES t_department ( id ) ON UPDATE CASCADE ON DELETE CASCADE;
我们知道cascade是删除父表中的记录,如果子表中存在关联的数据那么也会同时删除子表中关联的数据。
测试数据如下所示:
我们执行删除父表中的数据
delete from t_department WHERE id=1;
我们刷新数据,发现子表中对应的父表记录也被删除掉了。
RESTRICT和NO ACTION的测试:
这两个我们前面已经测试过了,要删除父表中的数据,必须是先删除子表中的数据或者子表没有对应的数据才可以。
SET NULL测试:
我们把外键的约束行为修改成set null
alter table t_employee add CONSTRAINT fk_dept foreign key(dept_id) REFERENCES t_department(id) on UPDATE set null on delete set null;
我们的测试数据如下所示:
我们再次执行删除父表的数据
delete from t_department WHERE id=1;
执行SQL语句之后,我们刷新数据发现父表中的数据已经被删除了,子表对应的数据被设置成null