文章目录
(一)约束的概念引入(二)非空约束:not null
(三)唯一约束:unique
(四)主键约束:primary key
(五)外键约束:foreign key
(一)约束的概念引入
概念:对表中的数据进行限定,保证数据的正确性、有效性和完整性
接下来我们添加一条非法数据试试
最后成功添加了一条没有名字的数据,这显然是不合理的,我们希望可以约束它
(二)非空约束:not null
a:在创建表的时候添加约束
CREATE TABLE student03(
id INT,
NAME VARCHAR(20) NOT NULL
);
b:在创建完表后再添加约束
我们先把之前添加的约束删除掉,如下:
ALTER TABLE student03 MODIFY NAME VARCHAR(20);
右击表单,选择改变表后可以看到勾勾没有了
我们再用b方法重新添加约束,语法跟删除类似:
ALTER TABLE student03 MODIFY NAME VARCHAR(20) NOT NULL;
(三)唯一约束:unique
我们重新创建一张表
唯一约束的意思就是不允许有重复的字段
比如说现在有一条id为1 NAME为zzq的数据
保存就会报错
注意:NULL不算重复
删除唯一约束的语法有点特殊,我们不能像删除非空约束那样去删除,要这样:
ALTER TABLE student05 DROP INDEX NAME;
创建表后添加唯一约束跟上面类似,不做阐述
(四)主键约束:primary key
主键约束综合了以上两种约束,含义为非空且唯一
一张表只能有一个字段为主键
主键就是表中记录的唯一标识,比如说id
我们试着在创建表时添加主键约束,如下:
CREATE TABLE student06(
id INT PRIMARY KEY, -- 给id添加主键约束
NAME VARCHAR(32)
);
效果就不演示了,就是非空且唯一。。
同样我们无法用正常的方法去删除这个主键约束,要用下面的方法:ALTER TABLE student06 DROP PRIMARY KEY;
同样创建完表添加跟之前一样,不做演示
下面说一下主键约束__自动增长
概念:如果某一列是数值类型的,使用auto_increment可以完成值的自动增长
为了方便演示,我们再新建一张表并且增加一条数据:
CREATE TABLE student07(
id INT PRIMARY KEY AUTO_INCREMENT, -- 给id添加主键约束
NAME VARCHAR(32)
);
如图:
我们添加一条语句试试,此时id就可以设为NULL了,因为它会自动增长
INSERT INTO student07 VALUES(NULL,"ZZQ02");
注意:自动增长的结果值只跟上一条记录的数值有关系
删除自动增长的方法:ALTER TABLE student07 MODIFY id INT
添加自动增长的方法:ALTER TABLE student07 MODIFY id INT AUTO_INCREMENT
(五)外键约束:foreign key
我们先建一张表,如下:
CREATE TABLE emp( -- 创建emp表
id INT PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(30),
age INT,
dep_name VARCHAR(30), -- 部门名称
dep_location VARCHAR(30) -- 部门地址
);
-- 添加数据
INSERT INTO emp (NAME,age,dep_name,dep_location)VALUES("张三",20,"研发部","广州");
INSERT INTO emp (NAME,age,dep_name,dep_location)VALUES("李四",21,"研发部","广州");
INSERT INTO emp (NAME,age,dep_name,dep_location)VALUES("王五",20,"研发部","广州");
INSERT INTO emp (NAME,age,dep_name,dep_location)VALUES("老王",20,"销售部","深圳");
INSERT INTO emp (NAME,age,dep_name,dep_location)VALUES("大王",22,"销售部","深圳");
INSERT INTO emp (NAME,age,dep_name,dep_location)VALUES("小王",18,"销售部","深圳");
我们发现数据有冗余,太多重复了
我们应该做表的拆分,如下:
-- 解决方案:分成2张表
-- 创建部门表(id,dep_name,dep_location)
-- 一方,主表
CREATE TABLE department(
id INT PRIMARY KEY AUTO_INCREMENT,
dep_name VARCHAR(20),
dep_location VARCHAR(20)
);
-- 创建员工表(id,name,age,dep_id)
-- 多方,从表
CREATE TABLE employee(
id INT PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(20),
age INT,
dep_id INT -- 外键对应主表的主键
);
-- 添加2个部门
INSERT INTO department VALUES(NULL,"研发部","广州"),(NULL,"销售部","深圳");
SELECT * FROM department;
-- 添加员工,dep_id表示员工所在的部门
INSERT INTO employee (NAME,age,dep_id) VALUES("张三",20,1);
INSERT INTO employee (NAME,age,dep_id) VALUES("李四",21,1);
INSERT INTO employee (NAME,age,dep_id) VALUES("王五",20,1);
INSERT INTO employee (NAME,age,dep_id) VALUES("老王",20,2);
INSERT INTO employee (NAME,age,dep_id) VALUES("大王",22,2);
INSERT INTO employee (NAME,age,dep_id) VALUES("小王",18,2);
SELECT * FROM employee;
效果如下:
分成两个表看起来没有什么问题,但是其中存在着非常严重的安全隐患,比如说我把部门表里面的第一条数据删掉了,如下:
那么另一张表属于这个部门的数据应该怎么办?
如果要删除一个部门是不是要先把部门里面的人全部删除了先
所以为了避免出现这种情况我们加入了外键约束
我们可以在创建表时,添加外键约束
create table 表名(
....
外键列
constraint 外键名称 foreign key 外键列名称 references 主表名称(主表列名称)
);
我们先把刚才创建的三张表删除掉,如下:
DROP TABLE emp;
DROP TABLE employee;
DROP TABLE department;
接下来我们重新创建,这是只需要加多一行代码:
CONSTRAINT emp_dept_fk FOREIGN KEY(dep_id) REFERENCES department(id)
这是如果我们再删除部门的数据,就会报错
注意:
(一) 由于是employee去关联department表,所以必须先创建department表
(二) 要想删除部门表的信息,必须先把相应部门的员工在员工表全部删除才可以
(三) 其实这是把两个表紧密关联起来,如果我在员工表创建一个数据里面的部门没有包含在部门表里面也会报错的
删除外键约束:
ALTER TABLE employee DROP FOREIGN KEY emp_dept_fk;
创建表之后,添加外键:
ALTER TABLE employee ADD CONSTRAINT emp_dept_fk FOREIGN KEY(dep_id) REFERENCES department(id);
最后说一下级联操作
如果我们要把研发部的id从1改成5会怎么样
当然会报错,但是怎么样才能不报错呢?
先把这边的1全部改成NULL
然后再改部门表的id
最后再把员工表的id改了
很麻烦
为了简化操作,级联操作为之而生
首先我们说一个小知识点,架构设计器
有连线证明两个表之间有关联
我们接下来把原本的外键约束给删除掉,再看看架构设计器
可以看到没有任何连线了,证明已经成功删除了外键约束
我们添加外键,并且设置级联更新,如下:
ALTER TABLE employee ADD CONSTRAINT emp_dept_fk FOREIGN KEY(dep_id)
REFERENCES department(id) ON UPDATE CASCADE;
这个时候部门表改了id,员工表会自动改过来
级联操作删除:
第一步,删除外键
ALTER TABLE employee DROP FOREIGN KEY emp_dept_fk;
第二步,添加外键的时候设置级联更新并且设置级联删除
ALTER TABLE employee ADD CONSTRAINT emp_dept_fk FOREIGN KEY(dep_id)
REFERENCES department(id) ON UPDATE CASCADE ON DELETE CASCADE;