首頁  >  文章  >  mysql有外鍵嗎

mysql有外鍵嗎

百草
百草原創
2023-06-13 13:29:501597瀏覽

mysql有外鍵,主要用來建立主表與從表的關聯關係,可以為兩個表的資料建立連接,約束兩個表中資料的一致性和完整性。當主表刪除某筆記錄時,從表中對應的記錄也必須有對應的改變,一個表可以有一個或多個外鍵。外鍵可以為空值,若不為空值,則每一個外鍵的值必須等於主表中主鍵的某個值,且外鍵中列的數目和對應資料類型必須和主表的主鍵中的相同。

mysql有外鍵嗎

本教學作業系統:Windows10系統、mysql 8.0版本、Dell G3電腦。

mysql有外鍵。

MySQL外鍵(FOREIGN KEY)

#外鍵是指定表中與另一個表的另一個欄位相符的欄位。外鍵對相關表中的資料設定了約束,這使MySQL能夠保持參照完整性。

外鍵用來建立主表與從表的關聯關係,為兩個表的資料建立連接,約束兩個表中資料的一致性和完整性。

對於兩個具有關聯關係的表而言,相關聯字段中主鍵所在的表就是主表(父表),外鍵所在的表就是從表(子表)。

主表刪除某筆記錄時,從表中與之對應的記錄也必須有對應的改變。一個表可以有一個或多個外鍵,外鍵可以為空值,若不為空值,則每一個外鍵的值必須等於主表中主鍵的某個值。

我們來看看範例資料庫中的以下資料庫圖。

mysql有外鍵嗎

我們有兩個表:customers和orders, 每個客戶都有零個或多個訂單,每個訂單只能屬於一個客戶。 customers表和orders表之間的關係是一對多的,它orders由customerNumber欄位指定的表中的外鍵建立。 customers表中的customerNumber欄位與orders表中的customerNumber主鍵欄位相關 。

customers 表稱為父表或參考表,orders表稱為子表或引用表。

外鍵可以是一個欄位或一組欄位。子表中的列通常會引用父表中的主鍵列。

表可以有多個外鍵,子表中的每個外鍵可以引用不同的父表。

子表中的行必須包含父表中存在的值,例如,orders表中的每個訂單記錄必須具有customers表customerNumber中存在的值。因此,多個訂單可以引用同一個客戶,這種關係稱為一個(客戶)到多個(訂單)或一對多。

有時,子表和父表是相同的。外鍵引用表的主鍵,例如,下employees表:

mysql有外鍵嗎

reportTo列是一個外鍵,它引用employeeNumber作為employees表的主鍵的列,以反映員工之間的報告結構,即每位員工向另一個員工報告,員工可以有零個或多個直接報告。我們有一個關於自聯接教程可以幫助您根據這種表查詢資料。

reportTo外鍵也被稱為遞歸或自引用的外鍵。

外鍵強制執行參考完整性,可協助您自動維護資料的一致性和完整性。例如,您無法為不存在的客戶建立訂單。

此外,您可以customerNumber在外鍵的刪除操作上設定級聯,以便在刪除customers表中的客戶時,也會刪除與客戶關聯的所有訂單。這節省了使用多個DELETE語句 或DELETE JOIN語句的時間和精力。

與刪除相同,您也可以在更新作業上為customerNumber外鍵定義級聯,以便在不使用多個UPDATE語句或UPDATE JOIN語句的情況下執行跨表更新。

注意:在MySQL中,InnoDB 儲存引擎支援外鍵,因此您必須建立InnoDB表才能使用外鍵約束。

mysql定義外鍵時,需要遵守下列規則:

主表必須已經存在於資料庫中,或是目前正在建立的表。如果是後一種情況,則主表與從表是同一個表,這樣的表稱為自參照表,這種結構稱為自參照完整性。

必須為主表定義主鍵。

主鍵不能包含空值,但允許在外鍵中出現空值。也就是說,只要外鍵的每個非空值出現在指定的主鍵中,這個外鍵的內容就是正確的。

在主表的表名後面指定列名或列名的組合。這個列或列的組合必須是主表的主鍵或候選鍵。

外鍵中列的數目必須和主表的主鍵中列的數目相同。

外鍵中列的資料類型必須和主表主鍵中對應列的資料類型相同。

為表建立外鍵

MySQL建立外鍵語法

以下語法說明如何在CREATE TABLE語句中的子表中定義外鍵。

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.每个类别具有一个或多个产品和每个产品只属于一个类别。products表中的cat_id字段被定义为带有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 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,请使用以下语句: 

ALTER TABLE products
ADD FOREIGN KEY fk_vendor(vdr_id)
REFERENCES vendors(vdr_id)
ON DELETE NO ACTION
ON UPDATE CASCADE;

mysql有外鍵嗎

 现在,products表有两个外键,一个引用categories表,另一个引用vendors表。

以上是mysql有外鍵嗎的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn