表和表之间可存在引用关系,这在抽象数据到表时,是很常见的。这种联系是通过在表中创建外键(foreign key)来实现的。

比如一个订单,可能关联用户表和产品表,以此来记录买了什么产品

约定两个概念:

父表:被引用的表。

从表:表中有相应的外键引用父表中的字段。

示例:

CREATE TABLE parent (
id INT NOT NULL,
PRIMARY KEY (id)
) ENGINE=INNODB; CREATE TABLE child (

id INT,

parent_id INT,

INDEX par_ind (parent_id),

FOREIGN KEY (parent_id)

REFERENCES parent(id)

ON DELETE CASCADE

) ENGINE=INNODB;

这里 parent 为父表,child 为从表。

外键关联表的同步操作

当表和表之间建立起合适的关联后, INSERTUPDATE 操作会自动检查所插入的记录中指定的外键在相应表中是否存在;

建立外键时,可指定 ON UPDATE <action>ON DELETE <action> 子语句来指定发生 UPDATEDELETE 操作时,外键关联表中数据该如何处理。MySQL 中支持五种处理(action):

  • CASCADE:更新或删除父表记录时,自动更新或删除从表中匹配的记录。实际使用时注意不要在父表或从表中对同一列重复定义 ON UPDATE CASCADE。CASCADE 类型的操作不会激活触发器 (triggers)。
  • SET NULL:更新或删除父表中记录时,将从表中匹配的记录其外键设置为 NULL,前提时从表中该外键没有指定为 NOT NULL
  • RESTRICT:默认为该项。禁用父表中的更新或删除操作,这与缺省 ON DELETEON UPDATE 子语句效果一样。
  • NO ACTION:来自 SQL 标准中定义的一种操作,与上面 RESTRICT 等效。一些数据库支持延迟检查(deferred check), NO ACTION 便是这种可延迟检查的操作。在 MySQL 中,外键的检查是及时的,所以 NO ACTIONRESTRICT 完全等效。
  • SET DEFAULT: MySQL 能够解析识别该动作,但 InnoDBNDB 引擎不支持。

添加外键

创建外键的语法
[CONSTRAINT [symbol]] FOREIGN KEY
[index_name] (col_name, ...)
REFERENCES tbl_name (col_name,...)
[ON DELETE reference_option]
[ON UPDATE reference_option] reference_option:

RESTRICT | CASCADE | SET NULL | NO ACTION | SET DEFAULT

文章开头提到的订单表示例:

CREATE TABLE product (
category INT NOT NULL, id INT NOT NULL,
price DECIMAL,
PRIMARY KEY(category, id)
) ENGINE=INNODB; CREATE TABLE customer (

id INT NOT NULL,

PRIMARY KEY (id)

) ENGINE=INNODB; CREATE TABLE product_order (

no INT NOT NULL AUTO_INCREMENT,

product_category INT NOT NULL,

product_id INT NOT NULL,

customer_id INT NOT NULL,
<span class="pl-k">PRIMARY KEY</span>(no),
INDEX (product_category, product_id),
INDEX (customer_id), <span class="pl-k">FOREIGN KEY</span> (product_category, product_id)
<span class="pl-k">REFERENCES</span> product(category, id)
<span class="pl-k">ON</span> <span class="pl-k">UPDATE</span> CASCADE <span class="pl-k">ON DELETE</span> RESTRICT, <span class="pl-k">FOREIGN KEY</span> (customer_id)
<span class="pl-k">REFERENCES</span> customer(id)

) ENGINE=INNODB;

所以这个关系里有两个父表 customerproduct,一个从表 product_order

对现有表添加外键可使用如下的语句:

ALTER TABLE tbl_name
ADD [CONSTRAINT [symbol]] FOREIGN KEY
[index_name] (col_name, ...)
REFERENCES tbl_name (col_name,...)
[ON DELETE reference_option]
[ON UPDATE reference_option]

创建外键时可指定 [symbol],即给外键取一个名称,这样在其他操作时可以引用,比如删除外键时。

删除外键

同样是通过 ALTER TABLE 语句来完成。

ALTER TABLE tbl_name DROP FOREIGN KEY fk_symbol;

删除外键时,如果该外键在创建时取了名称,名通过该名称来删除,如果没有,则需要先查询 MySQL 在创建该外键时自动生成的名称 fk_symbol 是什么。可通过 SHOW CREATE TABLE <table_name> 来完成查询。譬如:

mysql> SHOW CREATE TABLE dept_manager\G
*************************** 1. row ***************************
Table: dept_manager
Create Table: CREATE TABLE `dept_manager` (
`emp_no` int(11) NOT NULL,
`dept_no` char(4) COLLATE utf8mb4_general_ci NOT NULL,
`from_date` date NOT NULL,
`to_date` date NOT NULL,
PRIMARY KEY (`emp_no`,`dept_no`),
KEY `dept_no` (`dept_no`),
CONSTRAINT `dept_manager_ibfk_1` FOREIGN KEY (`emp_no`) REFERENCES `employees` (`emp_no`) ON DELETE CASCADE,
CONSTRAINT `dept_manager_ibfk_2` FOREIGN KEY (`dept_no`) REFERENCES `departments` (`dept_no`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci
1 row in set (0.00 sec)

相关资源

MySQL 中的外键的更多相关文章

  1. [原创]MYSQL中利用外键实现级联删除和更新

    MySQL中利用外键实现级联删除.更新 MySQL支持外键的存储引擎只有InnoDB,在创建外键的时候,要求父表必须有对应的索引,子表在创建外键的时候也会自动创建对应的索引.在创建索引的时候,可以指定 ...

  2. SET FOREIGN_KEY_CHECKS=0;在Mysql中取消外键约束。

    SET FOREIGN_KEY_CHECKS=0;在Mysql中取消外键约束.

  3. SET FOREIGN_KEY_CHECKS=0;在Mysql中取消外键约束

      Mysql中如果表和表之间建立的外键约束,则无法删除表及修改表结构.   解决方法是在Mysql中取消外键约束:  SET FOREIGN_KEY_CHECKS=0;     然后将原来表的数据导 ...

  4. mysql中主外键关系

    一.外键: 1.什么是外键 2.外键语法 3.外键的条件 4.添加外键 5.删除外键 1.什么是外键: 主键:是唯一标识一条记录,不能有重复的,不允许为空,用来保证数据完整性 外键:是另一表的主键, ...

  5. mysql|中主外键关系(转)

    http://my.oschina.net/liting/blog/356150 一.外键: 1.什么是外键 2.外键语法 3.外键的条件 4.添加外键 5.删除外键 1.什么是外键: 主键:是唯一标 ...

  6. MySQL中的外键是什么、有什么作用

    本文参加博文大赛,如果您满意的话麻烦点击这里给我投票原,查看原文点击这里.最近自学数据库MySQL,然后有个疑问,一直不得其解,查询了相关资料,最后还是没有解决. 我的疑问是 "使用外键约束 ...

  7. MySQL中利用外键实现级联删除、更新

    MySQL支持外键的存储引擎只有InnoDB,在创建外键的时候,要求父表必须有对应的索引,子表在创建外键的时候也会自动创建对应的索引.在创建索引的时候,可以指定在删除.更新父表时,对子表进行的相应操作 ...

  8. 如何在MySQL中设置外键约束

    引用:http://blog.sina.com.cn/s/blog_53729e4601011wja.html MySql外键设置详解   (1) 外键的使用: 外键的作用,主要有两个:    一个是 ...

  9. Mysql中的外键分析(什么是外键,为什么要用外键,添加外键,主外键关联删除)

    有一个东西一直在我脑海中是个很烦的东西,但是这东西不搞清楚会阻碍自己的前进.自己做项目demo永远只能用一张表... 所以今天还是学习了下外键希望能够搞明白一些... 百度上搜索外键的作用" ...

随机推荐

  1. nginx 反向代理之 proxy_pass

    格式很简单: proxy_pass URL; 其中URL包含:传输协议(http://, https://等).主机名(域名或者IP:PORT).uri. 示例如下: proxy_pass http: ...

  2. 使用 html2canvas 点击保存时把当前页面生成图片

     style:   #box{     background-image:url('./img/pone.png')     }   body:   <div id="box" ...

  3. 递归找到多级文件夹中所有pdf文件的py程序

    因个人需要,写了一个可以递归找到多级文件夹中所有pdf的小程序,发布出来供有需要的人参考或使用. import os import re import shutil from os.path impo ...

  4. 超级简单的数组加单链表实现Map

    /** * 超级简单的数组加单链表实现Map * @author jlj * */ public class MyHashMap { public MyList[] lists; public int ...

  5. Hbase如何批量删除指定数据

    有时我们需要批量删除一些hbase中符合某些条件的数据,本文提供一种简单的shell命令的方式批量删除hbase里的数据.思路就是,建立hive与hbase的关联表,通过hive sql查询出符合条件 ...

  6. C/C++ 中的宏/Macro

    宏(Macro)本质上就是代码片段,通过别名来使用.在编译前的预处理中,宏会被替换为真实所指代的代码片段,即下图中 Preprocessor 处理的部分. C/C++ 代码编译过程 - 图片来自 nt ...

  7. Git - Git推送本地分支到远程分支报错(! [rejected] non-fast-forward)的解决办法

    一般都是冲突造成的,解决方案执行如下命令(dev为分支名称): git fetch origin dev  #获取远程 dev 分支的修改 git merge origin dev       #合并 ...

  8. Spring Boot 2.2.2.RELEASE 版本中文参考文档

    写在前面 在我初次接触MongoDB的时候,是为了做一个监控系统和日志分析系统.当时在用Java操作MongoDB数据里的数据的时候,都是在网上查找Demo示例然后完成的功能,相信大家也同样的体会,网 ...

  9. QT--HTTP文件下载器

    QT--HTTP文件下载器 1.pro文件添加 QT       += core gui network 2.头文件 #include <QNetworkAccessManager> #i ...

  10. Fundebug前端异常监控插件更新至2.0.0,全面支持TypeScript

    摘要: 是时候支持TS了! Fundebug前端异常监控服务 Fundebug提供专业的前端异常监控服务,我们的插件可以提供全方位的异常监控,可以帮助开发者第一时间定位各种前端异常,包括但不限于Jav ...