Mysql foreignkey 相关

Posted xz2ll

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Mysql foreignkey 相关相关的知识,希望对你有一定的参考价值。

foreignkey  是指一对多关系时建立的关系:

 外键是表中与另一个表的另一个字段匹配的字段。外键对相关表中的数据施加限制,这使mysql能够保持参照完整性。  

操作:

  技术分享图片

能看懂图吗?

 

下面直接看代码:

  

我们有两个表:customersorders. 每个客户都有零个或多个订单,每个订单只能属于一个客户。customers表和orders之间的关系是一对多关系,并且orders由该customerNumber字段指定表中的外键建立表中customerNumber字段与orders表中的customerNumber主键字段相关  customers

customers 表称为父表或被引用表,该orders表称为子表引用表

外键可以是一列或一组列。子表中的列通常引用父表中主键列。

一个表可能有多个外键,并且子表中的每个外键都可能引用不同的父表。

子表中的行必须包含父表中存在的值,例如,表中的每个订单记录orders必须具有表customerNumber中存在的值customers因此,多个订单可以指同一个客户,这种关系被称为一个(客户)多个(订单)或一对多。

有时,子表和父表是相同的。外键返回到表的主键,例如下employees表:

技术分享图片

reportTo列是一个外键,它指的employeeNumberemployees表格的主键,以反映员工之间的报告结构,即每个员工向另一个员工报告,员工可以有零个或多个直接报告。我们有一个关于自联接的特定教程,可以帮助您根据这种表格查询数据。

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
View Code
  • CONSTRAINT子句允许您为外键约束定义约束名称。如果你忽略它,MySQL会自动生成一个名字。
  • FOREIGN KEY子句指定子表中引用父表中主键列的列。你可以在FOREIGN KEY子句之后放置一个外键名,或者让它为MySQL创建一个名字。注意MySQL会自动创建一个带有foreign_key_name名字的索引
  • REFERENCES子句指定父表和它的子表中的列引用的列。在规定的子表和父表的列数FOREIGN KEYREFERENCES必须相同。
  • ON DELETE子句允许您定义删除父表中的记录时,子表中记录发生的情况。如果您省略了ON DELETE子句并删除了在子表中具有记录的父表中的记录,那么MySQL将拒绝删除。此外,MySQL还为您提供了一些操作,以便您可以使用其他选项,例如ON DELETE CASCADE  ,要求MySQL删除子表中引用父表中的记录时父表中的记录被删除的记录。如果您不希望删除子表中的相关记录,则可以使用该ON DELETE SET NULL操作。MySQL会将子表中的外键列值设置为NULL当父表中的记录被删除时,使用子表中的外键列必须接受NULL值的条件。请注意,如果您使用ON DELETE NO ACTIONON DELETE RESTRICT操作,MySQL将拒绝删除。
  • ON UPDATE子句允许您指定更新父表中的行时发生的子表中的行。ON UPDATE当父表中的行更新时,可以省略该子句以使MySQL拒绝对子表中的行进行任何更新。ON UPDATE CASCADE操作允许您执行交叉表更新,当父表ON UPDATE SET NULL中的行更新时,该操作会将子表中的行中的值重置为值NULLON UPDATE NO ACTIONUPDATE RESTRICT行动拒绝任何更新。

 

 

 

MySQL创建表外键示例

下面的示例创建一个dbdemo数据库和两个表:categories和  products.每个类别具有一个或多个产品和每个产品只属于一个类别。表中cat_id字段products被定义为带有UPDATE ON CASCADEDELETE 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;
View Code

将外键添加到表中

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;
View Code

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;
View Code

要将外键添加到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;
View Code

现在,该products表有两个外键,一个categories表指向表,另一个指向vendors表。

删除MySQL外键

您还可以使用该ALTER TABLE语句删除外键,如下所示:

技术分享图片
ALTER TABLE table_name 
DROP FOREIGN KEY constraint_name;
View Code

在上面的声明中:

  • 首先,指定要从中删除外键的表名。
  • 其次,您将约束名称放在该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 相关的主要内容,如果未能解决你的问题,请参考以下文章

MYSQL创建表、约束、外键

Django:如何获取列表相关的 ForeignKey 记录?

用于从相关查询中列出所有 ForeignKey 对象的 Django 查询

在 django 中删除 ForeignKey 时在相关模型上发出信号

如何使用'select_related'从相关(ForeignKey)django模型中接收并非所有字段

mysql foreignkey