mysql核心知识之外键约束剖析

什么是外键?

外键就是作用于两个表数据之间的链接的一列或多列,用来保证表与表之间的数据的完整性和准确性。

添加外键约束:

语法:foreign key (字段名) references 关联的表名(关联表的字段名)
注意:主键跟外键的字段类型一定要相

create table的方法:
mysql> CREATE TABLE `employees` (
  `empno` int(11) NOT NULL COMMENT '雇员编号',
  `ename` varchar(50) DEFAULT NULL COMMENT '雇员姓名',
  `job` varchar(50) DEFAULT NULL COMMENT '雇员职位',
  `mgr` int(11) DEFAULT NULL COMMENT '雇员上级编号',
  `hiredate` date DEFAULT NULL COMMENT '雇佣日期',
  `sal` decimal(7,2) DEFAULT NULL COMMENT '薪资',
  `deptnu` int(11) DEFAULT NULL COMMENT '部门编号',
foreign key (deptnu) references dept (deptnu),
  PRIMARY KEY (`empno`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Query OK, 0 rows affected (0.02 sec)

mysql> show create table employees;
+-----------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table     | Create Table                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
+-----------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| employees | CREATE TABLE `employees` (
  `empno` int(11) NOT NULL COMMENT '雇员编号',
  `ename` varchar(50) DEFAULT NULL COMMENT '雇员姓名',
  `job` varchar(50) DEFAULT NULL COMMENT '雇员职位',
  `mgr` int(11) DEFAULT NULL COMMENT '雇员上级编号',
  `hiredate` date DEFAULT NULL COMMENT '雇佣日期',
  `sal` decimal(7,2) DEFAULT NULL COMMENT '薪资',
  `deptnu` int(11) DEFAULT NULL COMMENT '部门编号',
  PRIMARY KEY (`empno`),
  KEY `deptnu` (`deptnu`),
  CONSTRAINT `employees_ibfk_1` FOREIGN KEY (`deptnu`) REFERENCES `dept` (`deptnu`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
+-----------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.05 sec)

alter table的方法:
mysql> show create table employee;
+----------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table    | Create Table                                                                                                                                                                                                                                                                                                                                                                                                                                           |
+----------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| employee | CREATE TABLE `employee` (
  `empno` int(11) NOT NULL COMMENT '雇员编号',
  `ename` varchar(50) DEFAULT NULL COMMENT '雇员姓名',
  `job` varchar(50) DEFAULT NULL COMMENT '雇员职位',
  `mgr` int(11) DEFAULT NULL COMMENT '雇员上级编号',
  `hiredate` date DEFAULT NULL COMMENT '雇佣日期',
  `sal` decimal(7,2) DEFAULT NULL COMMENT '薪资',
  `deptnu` int(11) DEFAULT NULL COMMENT '部门编号',
  PRIMARY KEY (`empno`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
+----------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.04 sec)

mysql> alter table employee add foreign key (deptnu) references dept (deptnu);
Query OK, 14 rows affected (0.06 sec)
Records: 14  Duplicates: 0  Warnings: 0

mysql> show create table employee;
+----------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table    | Create Table                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
+----------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| employee | CREATE TABLE `employee` (
  `empno` int(11) NOT NULL COMMENT '雇员编号',
  `ename` varchar(50) DEFAULT NULL COMMENT '雇员姓名',
  `job` varchar(50) DEFAULT NULL COMMENT '雇员职位',
  `mgr` int(11) DEFAULT NULL COMMENT '雇员上级编号',
  `hiredate` date DEFAULT NULL COMMENT '雇佣日期',
  `sal` decimal(7,2) DEFAULT NULL COMMENT '薪资',
  `deptnu` int(11) DEFAULT NULL COMMENT '部门编号',
  PRIMARY KEY (`empno`),
  KEY `deptnu` (`deptnu`),
  CONSTRAINT `employee_ibfk_1` FOREIGN KEY (`deptnu`) REFERENCES `dept` (`deptnu`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
+----------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.04 sec)

添加外键约束后效果:

添加约束的表时‘孙子’,指向的表是’大爷‘;
如果添加外键约束的表插入的数据中,添加了外键约束的字段的数据 在指向表中的字段中不存在该数据,则添加失败。

如下图dept表中deptnu字段不存在50的数据,employee表的deptnu字段添加了外键约束,插入数据50,显示失败。

例子:

mysql> insert into employee values('10325','xiaohua','销售员','10010','2022-05-24','6000','50');
1452 - Cannot add or update a child row: a foreign key constraint fails (`test`.`employee`, CONSTRAINT `employee_ibfk_1` FOREIGN KEY (`deptnu`) REFERENCES `dept` (`deptnu`))
mysql> select * from dept;
+--------+--------+------+
| deptnu | dname  | addr |
+--------+--------+------+
|     10 | 研发部 | 北京 |
|     20 | 工程部 | 上海 |
|     30 | 销售部 | 广州 |
|     40 | 财务部 | 深圳 |
+--------+--------+------+
4 rows in set (0.04 sec)

mysql> insert into dept values('50','测试部门','南充');
Query OK, 1 row affected (0.00 sec)

mysql> insert into employee values('10325','xiaohua','销售员','10010','2022-05-24','6000','50');
Query OK, 1 row affected (0.00 sec)

mysql> select * from employee;
+-------+---------+--------+-------+------------+----------+--------+
| empno | ename   | job    | mgr   | hiredate   | sal      | deptnu |
+-------+---------+--------+-------+------------+----------+--------+
|  1001 | 小乔    | 文员   |  1013 | 2018-12-17 | 8000.00  |     20 |
|  1002 | 牛魔王  | 销售员 |  1006 | 2018-02-20 | 16000.00 |     30 |
|  1003 | 程咬金  | 销售员 |  1006 | 2017-02-22 | 12500.00 |     30 |
|  1004 | 猪八戒  | 经理   |  1009 | 2001-04-02 | 29650.00 |     20 |
|  1005 | 后裔    | 销售员 |  1006 | 2011-09-28 | 12500.00 |     30 |
|  1006 | 猴子    | 经理   |  1009 | 2011-05-01 | 28500.00 |     30 |
|  1007 | 张飞    | 经理   |  1009 | 2011-09-01 | 24500.00 |     10 |
|  1008 | 诸葛亮  | 分析师 |  1004 | 2017-04-19 | 30000.00 |     20 |
|  1009 | 唐僧    | 董事长 | NULL  | 2010-11-17 | 50000.00 |     10 |
|  1010 | 韩信    | 销售员 |  1006 | 2018-09-08 | 15000.00 |     30 |
|  1011 | 妲己    | 文员   |  1008 | 2018-05-23 | 11000.00 |     20 |
|  1012 | 安琪拉  | 文员   |  1006 | 2011-12-03 | 9500.00  |     30 |
|  1013 | 林俊杰  | 分析师 |  1004 | 2011-12-03 | 30000.00 |     20 |
|  1014 | 甄姬    | 文员   |  1007 | 2019-01-23 | 7500.00  |     10 |
| 10325 | xiaohua | 销售员 | 10010 | 2022-05-24 | 6000.00  |     50 |
+-------+---------+--------+-------+------------+----------+--------+
15 rows in set (0.06 sec)

删除外键约束:

注意:在干掉外键索引之前必须先把外键约束删除,才能删除索引

mysql> alter table employee drop index deptnu;
1553 - Cannot drop index 'deptnu': needed in a foreign key constraint

mysql> alter table employee drop foreign key employee_ibfk_1;
Query OK, 0 rows affected (0.01 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> alter table employee drop index deptnu;
Query OK, 0 rows affected (0.01 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> show create table employee;
+----------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table    | Create Table                                                                                                                                                                                                                                                                                                                                                                                                                                           |
+----------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| employee | CREATE TABLE `employee` (
  `empno` int(11) NOT NULL COMMENT '雇员编号',
  `ename` varchar(50) DEFAULT NULL COMMENT '雇员姓名',
  `job` varchar(50) DEFAULT NULL COMMENT '雇员职位',
  `mgr` int(11) DEFAULT NULL COMMENT '雇员上级编号',
  `hiredate` date DEFAULT NULL COMMENT '雇佣日期',
  `sal` decimal(7,2) DEFAULT NULL COMMENT '薪资',
  `deptnu` int(11) DEFAULT NULL COMMENT '部门编号',
  PRIMARY KEY (`empno`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
+----------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.05 sec)

注意点总结:

(1)俩个表,主键跟外键的字段类型一定要相同

(2)要使用外键约束表的引擎一定得是InnoDB引擎,MyISAM是不起作用的

mysql> alter table employees engine=myisam;
Query OK, 0 rows affected (0.02 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> show create table employees;
+-----------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table     | Create Table                                                                                                                                                                                                                                                                                                                                                                                                                                            |
+-----------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| employees | CREATE TABLE `employees` (
  `empno` int(11) NOT NULL COMMENT '雇员编号',
  `ename` varchar(50) DEFAULT NULL COMMENT '雇员姓名',
  `job` varchar(50) DEFAULT NULL COMMENT '雇员职位',
  `mgr` int(11) DEFAULT NULL COMMENT '雇员上级编号',
  `hiredate` date DEFAULT NULL COMMENT '雇佣日期',
  `sal` decimal(7,2) DEFAULT NULL COMMENT '薪资',
  `deptnu` int(11) DEFAULT NULL COMMENT '部门编号',
  PRIMARY KEY (`empno`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 |
+-----------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.04 sec)

mysql> alter table employees add foreign key (deptnu) references dept (deptnu);
Query OK, 0 rows affected (0.01 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> insert into employees values ('10020','xiaohuang','测试员','10000','2022-05-24','8000','60');
Query OK, 1 row affected (0.00 sec)

mysql> select * from employees;
+-------+-----------+--------+-------+------------+---------+--------+
| empno | ename     | job    | mgr   | hiredate   | sal     | deptnu |
+-------+-----------+--------+-------+------------+---------+--------+
| 10020 | xiaohuang | 测试员 | 10000 | 2022-05-24 | 8000.00 |     60 |
+-------+-----------+--------+-------+------------+---------+--------+
1 row in set (0.05 sec)

mysql> select * from dept;
+--------+----------+------+
| deptnu | dname    | addr |
+--------+----------+------+
|     10 | 研发部   | 北京 |
|     20 | 工程部   | 上海 |
|     30 | 销售部   | 广州 |
|     40 | 财务部   | 深圳 |
|     50 | 测试部门 | 南充 |
+--------+----------+------+
5 rows in set (0.04 sec)

(3)在干掉外键索引之前必须先把外键约束删除,才能删除索引

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值