Mysql foreignkey 相关
Posted xz2ll
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Mysql foreignkey 相关相关的知识,希望对你有一定的参考价值。
foreignkey 是指一对多关系时建立的关系:
外键是表中与另一个表的另一个字段匹配的字段。外键对相关表中的数据施加限制,这使mysql能够保持参照完整性。
操作:
能看懂图吗?
下面直接看代码:
我们有两个表:customers
和orders.
每个客户都有零个或多个订单,每个订单只能属于一个客户。customers
表和orders
表之间的关系是一对多关系,并且orders
由该customerNumber
字段指定的表中的外键建立。表中的customerNumber
字段与orders
表中的customerNumber
主键字段相关 customers
。
该customers
表称为父表或被引用表,该orders
表称为子表或引用表。
外键可以是一列或一组列。子表中的列通常引用父表中的主键列。
一个表可能有多个外键,并且子表中的每个外键都可能引用不同的父表。
子表中的行必须包含父表中存在的值,例如,表中的每个订单记录orders
必须具有表customerNumber
中存在的值customers
。因此,多个订单可以指同一个客户,这种关系被称为一个(客户)多个(订单)或一对多。
有时,子表和父表是相同的。外键返回到表的主键,例如下employees
表:
该reportTo
列是一个外键,它指的employeeNumber
是employees
表格的主键,以反映员工之间的报告结构,即每个员工向另一个员工报告,员工可以有零个或多个直接报告。我们有一个关于自联接的特定教程,可以帮助您根据这种表格查询数据。
该reportTo
外键也被称为递归或自引用的外键。
外键实施参照完整性,可帮助您自动维护数据的一致性和完整性。例如,您无法为不存在的客户创建订单。
另外,您可以为customerNumber
外键设置级联删除操作,这样当您删除customers
表中的客户时,与客户关联的所有订单也会被删除。这为您节省了使用多个DELETE语句 或DELETE JOIN语句的时间和精力。
与删除相同,还可以定义级联更新操作,以便customerNumber
外键执行跨表更新,而不使用多个UPDATE语句或UPDATE JOIN语句。
在MySQL中,InnoDB 存储引擎支持外键,因此您必须创建InnoDB表才能使用外键约束。
添加外键代码:
CONSTRAINT constraint_name FOREIGN KEY foreign_key_name (columns) REFERENCES parent_table(columns) ON DELETE action ON UPDATE action
- 该
CONSTRAINT
子句允许您为外键约束定义约束名称。如果你忽略它,MySQL会自动生成一个名字。 - 该
FOREIGN KEY
子句指定子表中引用父表中主键列的列。你可以在FOREIGN KEY
子句之后放置一个外键名,或者让它为MySQL创建一个名字。注意MySQL会自动创建一个带有foreign_key_name
名字的索引。 - 该
REFERENCES
子句指定父表和它的子表中的列引用的列。在规定的子表和父表的列数FOREIGN KEY
和REFERENCES
必须相同。 - 该
ON DELETE
子句允许您定义删除父表中的记录时,子表中记录发生的情况。如果您省略了ON DELETE
子句并删除了在子表中具有记录的父表中的记录,那么MySQL将拒绝删除。此外,MySQL还为您提供了一些操作,以便您可以使用其他选项,例如ON DELETE CASCADE ,要求MySQL删除子表中引用父表中的记录时父表中的记录被删除的记录。如果您不希望删除子表中的相关记录,则可以使用该ON DELETE SET NULL
操作。MySQL会将子表中的外键列值设置为NULL
当父表中的记录被删除时,使用子表中的外键列必须接受NULL
值的条件。请注意,如果您使用ON DELETE NO ACTION
或ON DELETE RESTRICT
操作,MySQL将拒绝删除。 - 该
ON UPDATE
子句允许您指定更新父表中的行时发生的子表中的行。ON UPDATE
当父表中的行更新时,可以省略该子句以使MySQL拒绝对子表中的行进行任何更新。该ON UPDATE CASCADE
操作允许您执行交叉表更新,当父表ON UPDATE SET NULL
中的行更新时,该操作会将子表中的行中的值重置为值NULL
。该ON UPDATE NO ACTION
或UPDATE RESTRICT
行动拒绝任何更新。
MySQL创建表外键示例
下面的示例创建一个dbdemo
数据库和两个表:categories
和 products.
每个类别具有一个或多个产品和每个产品只属于一个类别。表中的cat_id
字段products
被定义为带有UPDATE ON CASCADE
和DELETE ON RESTRICT
动作的外键。
CREATE DATABASE IF NOT EXISTS dbdemo; USE dbdemo; CREATE TABLE categories( cat_id int not null auto_increment primary key, cat_name varchar(255) not null, cat_description text ) ENGINE=InnoDB; CREATE TABLE products( prd_id int not null auto_increment primary key, prd_name varchar(355) not null, prd_price decimal, cat_id int not null, FOREIGN KEY fk_cat(cat_id) REFERENCES categories(cat_id) ON UPDATE CASCADE ON DELETE RESTRICT )ENGINE=InnoDB;
将外键添加到表中
MySQL添加外键语法
要将外键添加到现有表中,可以使用ALTER TABLE语句和上面的外键定义语法:
ALTER table_name ADD CONSTRAINT constraint_name FOREIGN KEY foreign_key_name(columns) REFERENCES parent_table(columns) ON DELETE action ON UPDATE action;
MySQL添加外键示例
现在,我们添加一个名为的新表,vendors
并更改products
表以包含供应商ID字段:
USE dbdemo; CREATE TABLE vendors( vdr_id int not null auto_increment primary key, vdr_name varchar(255) )ENGINE=InnoDB; ALTER TABLE products ADD COLUMN vdr_id int not null AFTER cat_id;
要将外键添加到products
表中,请使用以下语句:
2 3 4 5 ALTER TABLE products ADD FOREIGN KEY fk_vendor(vdr_id) REFERENCES vendors(vdr_id) ON DELETE NO ACTION ON UPDATE CASCADE;
现在,该products
表有两个外键,一个categories
表指向表,另一个指向vendors
表。
删除MySQL外键
您还可以使用该ALTER TABLE
语句删除外键,如下所示:
ALTER TABLE table_name DROP FOREIGN KEY constraint_name;
在上面的声明中:
- 首先,指定要从中删除外键的表名。
- 其次,您将约束名称放在该
DROP FOREIGN KEY
子句之后。
注意,这constraint_name
是在创建或向表中添加外键时指定的约束的名称。如果你忽略它,MySQL会为你生成一个约束名称。
要获取表的生成约束名称,请SHOW CREATE TABLE
按如下所示使用该语句:
SHOW CREATE TABLE table_name;
例如,要查看products
表的外键,可以使用以下语句:
SHOWS CREATE TABLE products;
On Delete和On Update都有Restrict,No Action, Cascade,Set Null属性。现在分别对他们的属性含义做个解释。
- ON DELETE
restrict(约束):当在父表(即外键的来源表)中删除对应记录时,首先检查该记录是否有对应外键,如果有则不允许删除。
no action:意思同restrict.即如果存在从数据,不允许删除主数据。
cascade(级联):当在父表(即外键的来源表)中删除对应记录时,首先检查该记录是否有对应外键,如果有则也删除外键在子表(即包含外键的表)中的记录。
set null:当在父表(即外键的来源表)中删除对应记录时,首先检查该记录是否有对应外键,如果有则设置子表中该外键值为null(不过这就要求该外键允许取null)
- ON UPDATE
restrict(约束):当在父表(即外键的来源表)中更新对应记录时,首先检查该记录是否有对应外键,如果有则不允许更新。
no action:意思同restrict.
cascade(级联):当在父表(即外键的来源表)中更新对应记录时,首先检查该记录是否有对应外键,如果有则也更新外键在子表(即包含外键的表)中的记录。
set null:当在父表(即外键的来源表)中更新对应记录时,首先检查该记录是否有对应外键,如果有则设置子表中该外键值为null(不过这就要求该外键允许取null)。
注:NO ACTION和RESTRICT的区别:只有在及个别的情况下会导致区别,前者是在其他约束的动作之后执行,后者具有最高的优先权执行。
以上是关于Mysql foreignkey 相关的主要内容,如果未能解决你的问题,请参考以下文章
Django:如何获取列表相关的 ForeignKey 记录?
用于从相关查询中列出所有 ForeignKey 对象的 Django 查询
在 django 中删除 ForeignKey 时在相关模型上发出信号