上数据库遇到了个叫外键的东西,一开始不是很懂,后来懂了,故记录一下。。。
外键,即外部的键 ,用来保证数据一致性,那么什么是数据的一致性呢?
假设某带学有如下两张表,描述,学生和专业的关系。
学生表 student:
姓名name | 学号studentno | 专业号majorno |
---|---|---|
李田所 | 1145141919 | 810 |
姜闸鸣 | 1145147789 | 364 |
特朗普 | 1145142020 | 901 |
专业表 major :
名称majorname | 人数number | 平均分averagescore | 专业号majorno |
---|---|---|---|
计算机科学 | 134 | 70.0 | 810 |
软件工程 | 221 | 76.5 | 364 |
大数据 | 78 | 87.5 | 901 |
学生可以通过专业号找到对应的专业表中的专业。那么如果有一条如下的记录插入:
高凰瑟 | 77881716 | 9331 |
---|
好像没啥问题是吧,你品,你细品。专业表中没有专业号为9331的记录,即没有这个专业,那么此时插入,逻辑上来说是错误的,也就是说出现数据不一致的情况。
这时候就需要外键来约束表中的数据了。外键的使用,可以保证数据的一致性和实现一些级联操作。
如果有了外键的约束,那么插入一条学生表记录时,当学生的专业号在专业表中不存在时,会发生错误,阻止数据的插入。
在外键约束的关系中,如果A表中的某一字段(比如上面例子中的专业号),必须保证在B表中存在对应专业号的记录,那么我们称:
以上述学生 / 专业两张表为例,有:
创建外键很简单,在创建的时候,通过REFEFRENCES,指定绑定的键:
CREATE TABLE IF NOT EXISTS 子表名(
... 字段定义 ...
FOREIGN KEY (子表字段名) REFERENCES 父表名(绑定的父表字段名)
) ENGINE=InnoDB;
食用方法:
注意:使用innoDB为引擎才能支持外键的创建,此外,两个绑定的键必须有相同的数据类型(比如 INT INT),或者是可以相互转换的类型(比如 INTTINYINT)。
还是以上述的学生 / 专业两张表为例,我们通过如下的语句创建表。
因为专业表是学生表的父表,我们先来创建专业表major:
CREATE TABLE IF NOT EXISTS major (
`majorname` VARCHAR(32),
`number` INT,
`averagescore` FLOAT,
`majorno` INT,
PRIMARY KEY (majorno)
) ENGINE=InnoDB;
随后我们创建学生表student,外键 majorno 指向父表(专业表major)的majorno字段:
CREATE TABLE IF NOT EXISTS student (
`name` VARCHAR(32),
`studentno` INT,
`majorno` INT,
PRIMARY KEY (studentno),
FOREIGN KEY (majorno) REFERENCES major(majorno)
) ENGINE=InnoDB;
如图,还是以上述的学生 / 专业两张表为例,我们在专业表中插入一些数据:
那么我们学生表的插入,也要按照基本法 ,也要和专业表保持一致。即学生的专业号字段必须是 364,810,901中的一个。
合法插入测试:我们插入810号专业的学生:
INSERT INTO student
(name, studentno, majorno)
VALUES
("TensorLEe", 1145141919, 810);
非法插入测试:我们试图插入一个在专业表中不存在的专业,即9331号专业,那么会报错:
MariaDB [db1]> INSERT INTO student
(name, studentno, majorno)
VALUES
("NanoNeaYur", 1145147789, 9331);
在子表中执行:
ALTER TABLE 子表名称
DROP FOREIGN KEY 外键约束名称;
即可取消外键关系。
示例:
ALTER TABLE student
DROP FOREIGN KEY student_ibfk_1;
即然外键约束已经解除,那么可以插入任意专业号的学生记录到学生表中了。我们插入9331专业的学生,是合法操作:
使用:
ALTER TABLE 子表名 ADD CONSTRAINT 外键约束名称
FOREIGN KEY (子表字段名) REFERENCES 父表名(绑定的附表外键字段名);
以添加外键约束。示例,我们创建名叫 WaiJianYueShu 的外键约束,将子表的专业号majorno和父表的majorno绑定:
注:如果子表中存在不符合外键约束的字段,那么创建约束将会失败:
外键约束保证了数据一致性,是好特性,但是也要注意
咕了