概述
概念
约束是作用于表中字段上的规则,用于限制存储在表中的数据。
目的
保证数据库中数据的正确、有效性和完整性。
分类
【注意】约束是作用于表中字段上的,可以在创建表/修改表的时候添加约束。
约束演示
根据需求,完成表结构的创建。需求如下:
建表
create table user(id int primary key auto_increment comment '主键',name varchar(10) not null unique comment '姓名',age int check ( age > 0 && age <= 120 ) comment '年龄',status char(1) default '1' comment '状态',gender char(1) comment '性别'
)comment '用户表';
测试
insert into user(name,age,status,gender) values ('Tom1',19,'1','男'),('Tom2',25,'0','男');
insert into user(name,age,status,gender) values ('Tom3',19,'1','男');insert into user(name,age,status,gender) values (null,19,'1','男'); --报错 name不能为null
insert into user(name,age,status,gender) values ('Tom3',19,'1','男'); --报错 name不能重复insert into user(name,age,status,gender) values ('Tom4',80,'1','男');
insert into user(name,age,status,gender) values ('Tom5',-1,'1','男'); --报错 age为无效值
insert into user(name,age,status,gender) values ('Tom5',121,'1','男'); --报错 age为无效值insert into user(name,age,gender) values ('Tom5',120,'男'); --stadus为1
外键约束
介绍
外键:用来让两张表的数据之间建立连接,从而保证数据的一致性和完整性。
左侧的emp表是员工表,里面存储员工的基本信息,包含员工的ID、姓名、年龄、职位、薪资、入职日期、上级主管ID、部门ID,在员工的信息中存储的是部门的ID dept_id,而这个部门的ID是关联的部门表dept的主键id,那emp表的dept_id就是外键,关联的是另一张表的主键。
【注意】目前上述两张表,只是在逻辑上存在这样一层关系;在数据库层面,并未建立外键关联,所以是无法保证数据的一致性和完整性的。
测试
准备数据
create table dept(id int auto_increment comment 'ID' primary key,name varchar(50) not null comment '部门名称'
)comment '部门表';
INSERT INTO dept (id, name) VALUES (1, '研发部'), (2, '市场部'),(3, '财务部'), (4,'销售部'), (5, '总经办');create table emp(id int auto_increment comment 'ID' primary key,name varchar(50) not null comment '姓名',age int comment '年龄',job varchar(20) comment '职位',salary int comment '薪资',entrydate date comment '入职时间',managerid int comment '直属领导ID',dept_id int comment '部门ID'
)comment '员工表';
INSERT INTO emp (id, name, age, job,salary, entrydate, managerid, dept_id)
VALUES(1, '金庸', 66, '总裁',20000, '2000-01-01', null,5),(2, '张无忌', 20,'项目经理',12500, '2005-12-05', 1,1),(3, '杨逍', 33, '开发', 8400,'2000-11-03', 2,1),(4, '韦一笑', 48, '开发',11000, '2002-02-05', 2,1),(5, '常遇春', 43, '开发',10500, '2004-09-07', 3,1),(6, '小昭', 19, '程序员鼓励师',6600, '2004-10-12', 2,1);
删除id为1的部门信息
结果,删除成功之后,部门表不存在id为1的部门,而在emp表中还有很多的员
工,关联的为id为1的部门,此时就出现了数据的不完整性。 而要想解决这个问题就得通过数据库的外键约束。
语法总览
添加外键
create table 表名(字段名 数据类型,...[constraint] [外键名称] foreign key (外键字段名) references 主表 (主表列名)
);
alter table 表名 add constraint 外键名称 foreign key (外键字段名)
references 主表 (主表列名) ;
[ 案例 ]
为emp表的dept_id字段添加外键约束,关联dept表的主键id。
alter table emp add constraint fk_emp_dept_id foreign key (dept_id) references dept(id);
添加了外键约束之后,再到dept表(父表)删除id为1的记录, 此时将会报错,不能删除或更新父表记录,因为存在外键约束。
删除外键
alter table 表名 drop foreign key 外键名称;
[ 案例 ]
删除emp表的外键fk_emp_dept_id。
alter table emp drop foreign key fk_emp_dept_id;
删除/更新行为
分类
添加了外键之后,再删除父表数据时产生的约束行为,我们就称为删除/更新行为。具体的删除/更新行为有以下几种:
具体语法
alter table 表名 add constraint 外键名称 foreign key (外键字段) references 主表名(主表字段名)on update cascade on delete cascade;
演示
- CASCADE
alter table emp add constraint fk_emp_dept_id foreign key (dept_id) references dept(id) on update cascade on delete cascade ;
A. 修改父表id为1的记录,将id修改为6
原来在子表中dept_id值为1的记录,现在也变为6了,这就是cascade级联的效果。
在一般的业务系统中,不会修改一张表的主键值。
B. 删除父表id为6的记录
父表的数据删除成功了,但是子表中关联的记录也被级联删除了。
- SET NULL
在进行测试之前,先需要删除上面建立的外键 fk_emp_dept_id。然后再通过数据脚本,将emp、dept表的数据恢复了。
alter table emp add constraint fk_emp_dept_id foreign key (dept_id) references dept(id) on update set null on delete set null ;
删除id为1的数据:
发现父表的记录是可以正常的删除的,父表的数据删除之后,再打开子表 emp,发现子表emp的dept_id字段,原来dept_id为1的数据,现在都被置为NULL了。
这就是SET NULL这种删除/更新行为的效果。