外鍵

本文將說明 Spanner 中的外鍵,以及如何使用外鍵在資料庫中強制執行參照完整性。如要瞭解外鍵及其使用方式,請參閱以下主題:

Spanner 中的外鍵總覽

外鍵可定義資料表之間的關係。您可以使用外鍵,確保 Spanner 中這些關係的資料完整性。

假設您是某家電子商務公司的開發人員主管。您正在設計資料庫來處理客戶訂單。資料庫必須儲存每筆訂單、客戶和產品的相關資訊。圖 1 說明應用程式的基本資料庫結構。

訂單處理資料庫的基本結構。

圖 1. 訂單處理資料庫的圖表

您可以定義 Customers 資料表來儲存客戶資訊、Orders 資料表來追蹤所有訂單,以及 Products 資料表來儲存每項產品的相關資訊。

圖 1 也顯示資料表之間的連結,這些連結對應至下列實際關係:

  • 客戶下單。

  • 下單購買產品。

您決定資料庫強制執行下列規則,確保系統中的訂單有效。

  • 您無法為不存在的客戶建立訂單。

  • 消費者無法訂購你未販售的產品。

強制執行這些規則或限制時,您會維持資料的參照完整性。當資料庫維持參照完整性時,所有嘗試新增無效資料的動作都會失敗,這可能會導致資料之間的連結或參照無效。參照完整性可避免使用者操作錯誤。根據預設,Spanner 會使用外鍵強制執行參照完整性。

使用外鍵定義參照完整性

以下再次檢查訂單處理範例,並在設計中加入更多詳細資料,如圖 2 所示。

含有外鍵的資料庫結構定義

圖 2:含有外鍵的資料庫結構定義圖表

設計現在會顯示每個資料表中的欄名稱和類型。Orders 資料表也定義了兩個外鍵關係。FK_CustomerOrder 預期 Orders 中的所有資料列都具有有效的 CustomerIdFK_ProductOrder 外部索引預期 Orders 資料表中的所有 ProductId 值皆有效。下表將這些限制對應至您要強制執行的實際規則。

外鍵名稱 限制 實際描述
FK_CustomerOrder 預期 Orders 中的所有資料列都具有有效的 CustomerId 有效客戶下單
FK_ProductOrder 預期 Orders 中的所有資料列都具有有效的 ProductId 已下單購買有效的產品

Spanner 會強制執行使用強制外鍵指定的限制。也就是說,如果 Orders 資料表中含有 CustomersProducts 資料表中找不到的 CustomerIdProductId,Spanner 會讓任何嘗試在該資料表中插入或更新資料列的交易失敗。它也會讓嘗試更新或刪除 CustomersProducts 資料表中的資料列失敗,這些資料列會使 Orders 資料表中的 ID 失效。如要進一步瞭解 Spanner 如何驗證限制條件,請參閱「交易限制條件驗證」一節。

與強制外鍵不同,Spanner 不會驗證資訊外鍵的限制條件。也就是說,如果您在這種情況下使用資訊外鍵,則在 Orders 資料表中嘗試插入或更新資料列的交易,如果該資料列有 CustomerIdProductId,但在 CustomersProducts 資料表中找不到,則不會進行驗證,且交易不會失敗。與強制外鍵不同的是,只有 GoogleSQL 支援資訊外鍵,PostgreSQL 不支援。

外鍵特性

以下列出 Spanner 中外鍵的特性。

  • 定義外鍵的資料表是「參照」資料表,而外鍵欄是「參照」資料欄。

  • 外鍵會參照參照資料表的參照欄。

  • 如同範例所示,您可以為每個外鍵限制命名。如果您未指定名稱,Spanner 會為您產生名稱。您可以從 Spanner 的 INFORMATION_SCHEMA 查詢產生的名稱。限制名稱的範圍為結構定義,以及資料表和索引的名稱,且在結構定義中不得重複。

  • 參照欄和被參照欄的數量必須相同。順序很重要。例如,第一個參照資料欄會參照第一個參照資料欄,第二個參照資料欄會參照第二個參照資料欄。

  • 參照欄和其參照對應項目必須為相同類型。您必須能夠為資料欄建立索引。

  • 您無法在使用 allow_commit_timestamp=true 選項的資料欄上建立外鍵。

  • 不支援陣列資料欄。

  • 不支援 JSON 資料欄。

  • 外鍵可以參照同一個資料表的欄 (自參照外鍵)。例如,Employee 資料表含有 ManagerId 資料欄,該資料欄參照資料表的 EmployeeId 資料欄。

  • 外鍵也可以在資料表之間形成循環關係,也就是兩個資料表直接或間接地相互參照。建立外鍵之前,必須先建立參照的資料表。也就是說,您必須使用 ALTER TABLE 陳述式新增至少一個外鍵。

  • 參照的鍵不得重複。如果外鍵參照的資料欄與參照資料表的主鍵資料欄相符,Spanner 會使用參照資料表的 PRIMARY KEY。如果 Spanner 無法使用參照資料表的主鍵,就會在參照的資料欄上建立 UNIQUE NULL_FILTERED INDEX

  • 外鍵不會使用您建立的次要索引。而是自行建立索引。支援索引可用於查詢評估,包括明確的 force_index 指令。您可以從 Spanner 的 INFORMATION_SCHEMA 查詢基礎索引的名稱。詳情請參閱「備份索引」。

外鍵類型

外鍵分為兩種類型:強制資訊性。強制外鍵是預設值,可強制參照完整性。資訊外鍵不會強制執行參照完整性,因此最適合用於宣告要用於查詢最佳化的邏輯資料模型。詳情請參閱下列強制資訊性外鍵章節,以及外鍵類型比較表格。

強制外鍵

強制外鍵 (Spanner 中的預設外鍵類型) 會強制執行參照完整性。由於強制外鍵會強制參照完整性,因此會導致下列嘗試失敗:

  • 在參照資料表中加入資料列時,如果該資料列的外鍵值不存在於參照資料表中,則會失敗。

  • 從參照表中刪除參照表中資料列所參照的資料列會失敗。

所有 PostgreSQL 外鍵都會強制執行。根據預設,GoogleSQL 外鍵會強制執行。由於預設會強制執行外鍵,因此您不一定要使用 ENFORCED 關鍵字指定要強制執行 GoogleSQL 外鍵。

資訊外鍵

資訊外鍵用於宣告用於查詢最佳化的預期邏輯資料模型。雖然參照表鍵必須是資訊外鍵的唯一值,但系統不會強制執行參照完整性。如果您想在使用資訊外鍵時,選擇性驗證參照完整性,則需要在用戶端管理驗證邏輯。詳情請參閱「使用資訊外鍵」。

使用 NOT ENFORCED 關鍵字指定 GoogleSQL 外鍵是資訊性。PostgreSQL 不支援資訊外鍵。

外鍵類型的比較

強制資訊性的廣告活動都有其優點。以下各節將比較兩種外鍵類型,並提供一些最佳做法。

高階外鍵差異

大致來說,以下是強制資訊外鍵之間的差異:

  • 違規處置。強制外鍵可驗證及保證寫入時的參照完整性。資訊外鍵不會驗證或保證參照完整性。

  • 儲存空間。強制外鍵可能需要額外的儲存空間,用於限制資料表的備用索引。

  • 寫入總處理量。相較於資訊外鍵,強制外鍵在寫入路徑中可能會產生更多額外負擔。

  • 查詢最佳化。這兩種外鍵都可以用於查詢最佳化。當最佳化工具可使用資訊外鍵時,如果資料不符合資訊外鍵關係 (例如,如果某些受限制的鍵在參照資料表中沒有相符的參照鍵),查詢結果可能不會反映實際資料。

外鍵差異表

下表列出強制和資訊外鍵之間的詳細差異:

強制外鍵 資訊外鍵
關鍵字 ENFORCED NOT ENFORCED
由 GoogleSQL 支援 可以,根據預設,GoogleSQL 會強制執行外鍵。 是。
由 PostgreSQL 支援 可以,只能強制執行 PostgreSQL 中的外鍵。 不用
儲存空間 強制外部索引鍵需要最多兩個支援索引的儲存空間。 資訊外部索引鍵最多需要儲存一個支援索引。
視需要在參照的資料表欄上建立備援索引 是。 是。
視需要在參照資料表欄上建立備份索引 是。 不用
支援外鍵動作 是。 不用
驗證並強制執行參照完整性 是。 否。沒有驗證功能可提高寫入效能,但如果使用資訊外鍵進行查詢最佳化,可能會影響查詢結果。您可以使用用戶端驗證或強制外鍵,確保參照完整性。

選擇要使用的外鍵類型

您可以參考下列指南,決定要使用哪一種外鍵類型:

建議您先從強制外鍵著手。強制外部鍵可隨時保持資料和邏輯模型的一致性。除非強制外鍵無法用於您的用途,否則建議使用強制外鍵。

如果符合下列所有情況,建議您考慮使用資訊外鍵:

  • 您想在查詢最佳化中使用資訊外鍵所描述的邏輯資料模型。

  • 維持嚴格的參照完整性並不切合實際,而且會對效能造成重大影響。以下列舉幾個建議使用資訊外鍵的情況:

    • 您的上游資料來源採用最終一致性模型。在這種情況下,在來源系統中所做的更新可能不會立即反映在 Spanner 中。由於更新可能不會立即生效,因此可能會出現外鍵關係的短暫不一致情形。

    • 資料包含參照資料列,且參照資料列有大量參照關係。更新這些資料列可能會使用大量資源,因為 Spanner 必須驗證或在某些情況下刪除與維持參照完整性相關的所有資料列。在這種情況下,更新可能會影響 Spanner 效能,並減緩並行交易。

  • 應用程式可處理潛在的資料不一致情形,以及這些情形對查詢結果的影響。

使用資訊外鍵

以下主題僅適用於資訊外鍵。如要瞭解資訊和強制外鍵兩者都適用的主題,請參閱以下內容:

建立含有資訊外鍵的新資料表

您可以使用 DDL 陳述式,在 Spanner 資料庫中建立、移除及查看資訊外鍵 。您可以使用 CREATE TABLE 陳述式,在新的資料表中加入外鍵。同樣地,您也可以使用 ALTER TABLE 陳述式,在現有資料表中新增或移除外來鍵。

以下範例會使用 GoogleSQL 建立含有資訊外鍵的新資料表。PostgreSQL 不支援資訊外鍵。

GoogleSQL

CREATE TABLE Customers (
  CustomerId INT64 NOT NULL,
  CustomerName STRING(MAX) NOT NULL,
) PRIMARY KEY(CustomerId);

CREATE TABLE Orders (
  OrderId INT64 NOT NULL,
  CustomerId INT64 NOT NULL,
  Quantity INT64 NOT NULL,
  ProductId INT64 NOT NULL,
  CONSTRAINT FK_CustomerOrder FOREIGN KEY (CustomerId)
   REFERENCES Customers (CustomerId) NOT ENFORCED
 ) PRIMARY KEY (OrderId);

PostgreSQL

Not Supported

如需更多建立及管理外來鍵的範例,請參閱「建立及管理外來鍵關係」。如要進一步瞭解 DDL 陳述式,請參閱 DDL 參考資料

使用資訊外鍵進行查詢最佳化

查詢最佳化工具可使用強制外鍵資訊外鍵來改善查詢效能。使用資訊外鍵可讓您充分利用最佳化查詢計畫,而不會產生嚴格參照完整性執行的額外負擔。

如果您啟用查詢最佳化工具,讓其使用資訊外鍵資訊,請務必瞭解,最佳化結果的正確性取決於資料是否與資訊外鍵所描述的邏輯模型一致。如果存在不一致之處,查詢結果可能不會反映實際資料。不一致的例子包括限制資料欄中的值在參照資料欄中沒有相符的值。

根據預設,查詢最佳化工具會使用 NOT ENFORCED 外鍵。如要變更這項設定,請將資料庫選項 use_unenforced_foreign_key_for_query_optimization 設為 false。以下是 GoogleSQL 範例,可用來說明這一點 (PostgreSQL 中沒有資訊外鍵):

SET DATABASE OPTIONS (
    use_unenforced_foreign_key_for_query_optimization = false
);

布林值查詢陳述式提示 @{use_unenforced_foreign_key} 會根據個別查詢覆寫資料庫選項,藉此控制最佳化工具是否使用 NOT ENFORCED 外鍵。在排解非預期的查詢結果時,停用這個提示或資料庫選項可能會很有幫助。以下說明如何使用 @{use_unenforced_foreign_key}

@{use_unenforced_foreign_key=false} SELECT Orders.CustomerId
    FROM Orders
    INNER JOIN Customers ON Customers.CustomerId = Orders.CustomerId;

使用強制外鍵

以下主題僅適用於強制外鍵。如要瞭解資訊和強制外鍵兩者都適用的主題,請參閱以下內容:

建立含有強制外鍵的新資料表

您可以使用 DDL 在 Spanner 資料庫中建立、移除及強制外鍵。您可以使用 CREATE TABLE 陳述式,將外鍵新增至新資料表。同樣地,您可以使用 ALTER TABLE 陳述式,在現有資料表中新增或移除外鍵。

您可以使用 DDL 在 Spanner 資料庫中建立及移除外鍵。您可以使用 CREATE TABLE 陳述式,在新的資料表中加入外鍵。同樣地,您可以使用 ALTER TABLE 陳述式,在現有資料表中新增或移除外鍵。

以下是建立含有強制外來鍵的新資料表的範例。

GoogleSQL

CREATE TABLE Customers (
CustomerId INT64 NOT NULL,
CustomerName STRING(MAX) NOT NULL,
) PRIMARY KEY(CustomerId);

CREATE TABLE Orders (
OrderId INT64 NOT NULL,
CustomerId INT64 NOT NULL,
Quantity INT64 NOT NULL,
ProductId INT64 NOT NULL,
CONSTRAINT FK_CustomerOrder FOREIGN KEY (CustomerId)
  REFERENCES Customers (CustomerId) ENFORCED
) PRIMARY KEY (OrderId);

PostgreSQL

CREATE TABLE Customers (
CustomerId bigint NOT NULL,
CustomerName character varying(1024) NOT NULL,
PRIMARY KEY(CustomerId)
);

CREATE TABLE Orders (
OrderId BIGINT NOT NULL,
CustomerId BIGINT NOT NULL,
Quantity BIGINT NOT NULL,
ProductId BIGINT NOT NULL,
CONSTRAINT FK_CustomerOrder FOREIGN KEY (CustomerId)
  REFERENCES Customers (CustomerId),
PRIMARY KEY (OrderId)
);

如需更多建立及管理外來鍵的範例,請參閱「建立及管理外來鍵關係」。

外鍵動作

外鍵動作只能在強制外鍵上定義。

外鍵動作會控制當參照的資料欄遭到刪除或更新時,受限資料欄會發生什麼情況。Spanner 支援使用 ON DELETE CASCADE 動作。使用外鍵 ON DELETE CASCADE 動作時,如果您刪除包含參照外鍵的資料列,則在同一筆交易中,所有參照該鍵的資料列也會一併刪除。

使用 DDL 建立資料庫時,您可以透過動作新增外來鍵。使用 CREATE TABLE 陳述式,將外鍵和動作新增至新資料表。同樣地,您可以使用 ALTER TABLE 陳述式,將外鍵動作新增至現有資料表,或移除外鍵動作。以下範例說明如何使用外鍵動作建立新資料表。

GoogleSQL

CREATE TABLE ShoppingCarts (
CartId INT64 NOT NULL,
CustomerId INT64 NOT NULL,
CustomerName STRING(MAX) NOT NULL,
CONSTRAINT FKShoppingCartsCustomers FOREIGN KEY(CustomerId, CustomerName)
  REFERENCES Customers(CustomerId, CustomerName) ON DELETE CASCADE,
) PRIMARY KEY(CartId);

PostgreSQL

CREATE TABLE ShoppingCarts (
CartId bigint NOT NULL,
CustomerId bigint NOT NULL,
CustomerName character varying(1024) NOT NULL,
PRIMARY KEY(CartId),
CONSTRAINT fkshoppingcartscustomers FOREIGN KEY (CustomerId, CustomerName)
  REFERENCES Customers(CustomerId, CustomerName) ON DELETE CASCADE
);

以下列出 Spanner 中外鍵動作的特性。

  • 外鍵動作為 ON DELETE CASCADEON DELETE NO ACTION

  • 您可以查詢 INFORMATION_SCHEMA,找出有動作的外部鍵限制。

  • 系統不支援在現有外鍵限制上新增外鍵動作。您必須透過動作新增外鍵約束。

限制驗證

限制驗證僅適用於強制外鍵。

在交易提交時,或在交易中的後續作業可看到寫入作業的效果時,Spanner 會驗證強制外鍵限制。

插入參照欄的值會與參照資料表和參照欄的值進行比對。列出 NULL 參照值的資料列不會勾選,表示您可以將這些資料列加入參照表。

當 Spanner 嘗試使用 DML 陳述式或 API 更新資料時,會驗證所有適用的強制外鍵參照限制。如果任何限制條件無效,所有待處理的變更都會復原。

系統會在每個 DML 陳述式之後立即執行驗證。例如,您必須先插入參照資料列,才能插入參照資料列。使用變異 API 時,變異會緩衝,直到交易完成為止。強制外鍵驗證會延後至交易提交時才執行。在這種情況下,可以先插入參照資料列。

系統會評估每筆交易是否有影響強制外部索引鍵限制的修改。這些評估可能需要向伺服器提出額外要求。備份索引也需要額外的處理時間,才能評估交易修改作業並維護索引。每個索引也需要額外的儲存空間。

長時間執行的刪除連鎖動作

從參照資料表中刪除資料列時,Spanner 必須刪除參照資料表中參照已刪除資料列的所有資料列。這可能會導致連鎖效應,也就是單一刪除作業會導致數千個其他刪除作業。在資料表中加入外鍵限制 (含有刪除連鎖動作) 或建立含有外鍵限制 (含有刪除連鎖動作) 的資料表,可能會減緩刪除作業的速度。

外鍵刪除連鎖操作超出變異上限

使用外鍵刪除連鎖功能刪除大量記錄可能會影響效能。這是因為每個刪除的記錄都會觸發與其相關的所有記錄刪除作業。如果您需要使用外鍵刪除連鎖功能刪除大量記錄,請先明確刪除子項資料表中的資料列,再刪除父項資料表中的資料列。這可避免交易因突變限制而失敗。

強制外鍵和資料表交錯的比較

在許多父項子項關係中,如果子項資料表的主鍵包含父項資料表的主鍵欄,Spanner 的資料表交錯功能就相當適合。將子項資料列與父項資料列放置於相同的位置可以大幅提高效能。

外鍵是較為常見的父項子項關係解決方案,也能用於其他用途。外鍵並非僅限於主鍵欄,資料表可以同時含有多組外鍵關係,在某些關係中擔任父項,在其他關係中擔任子項。不過,外鍵關係並未表示資料表會在儲存空間層中共用位置。

請參考以下範例,其中使用 Orders 資料表,定義如下:

含有外鍵的資料庫結構定義

圖 3:資料庫結構定義圖表 (已強制執行外鍵)

圖 3 中的設計有一些限制。舉例來說,每筆訂單只能包含一個訂單商品。

假設您的客戶希望每次訂單可訂購多個產品。您可以引入 OrderItems 表格,為每項消費者訂購的產品新增項目,藉此改善設計。您可以引入另一個強制外來鍵,用來表示 OrdersOrderItems 之間的新一對多關係。不過,您也知道自己經常需要針對訂單和相應的訂單商品執行查詢。由於這類資料的共同位置可提升效能,因此建議您使用 Spanner 的資料表交錯功能建立父項-子項關係。

以下說明如何定義 OrderItems 資料表,並與 Orders 交錯。

GoogleSQL

CREATE TABLE Products (
ProductId INT64 NOT NULL,
Name STRING(256) NOT NULL,
Price FLOAT64
) PRIMARY KEY(ProductId);

CREATE TABLE OrderItems (
OrderId INT64 NOT NULL,
ProductId INT64 NOT NULL,
Quantity INT64 NOT NULL,
FOREIGN KEY (ProductId) REFERENCES Products (ProductId)
) PRIMARY KEY (OrderId, ProductId),
INTERLEAVE IN PARENT Orders ON DELETE CASCADE;

PostgreSQL

CREATE TABLE Products (
ProductId BIGINT NOT NULL,
Name varchar(256) NOT NULL,
Price float8,
PRIMARY KEY(ProductId)
);

CREATE TABLE OrderItems (
OrderId BIGINT NOT NULL,
ProductId BIGINT NOT NULL,
Quantity BIGINT NOT NULL,
FOREIGN KEY (ProductId) REFERENCES Products (ProductId),
PRIMARY KEY (OrderId, ProductId)
) INTERLEAVE IN PARENT Orders ON DELETE CASCADE;

圖 4 是更新資料庫結構定義的視覺化呈現,這是因為我們引入了新表格 OrderItems,並與 Orders 交錯。這裡也可以看到這兩個資料表之間的一對多關係。

資料庫結構定義:顯示 Orders 與新 OrderItems 資料表之間的一對多關係

圖 4:新增交錯的 OrderItems 資料表

在這種設定中,每個訂單中可以有多個 OrderItems 項目,且每個訂單的 OrderItems 項目會交錯排列,因此會與訂單一併放置。以這種方式實體交錯 OrdersOrderItems 可提升效能,有效地預先彙整資料表,讓您一併存取相關資料列,同時減少磁碟存取次數。舉例來說,Spanner 可利用主鍵在本機進行彙整,減少存取磁碟的次數並降低網路流量。

如果交易中的變異數量超過 80,000,交易就會失敗。這種大量連鎖刪除作業適用於具有「交錯在父項」關係的資料表,但不適用於具有外鍵關係的資料表。如果您有外部關鍵字關係,且需要刪除大量資料列,請先明確刪除子表格中的資料列。

如果使用者資料表與其他資料表有外鍵關係,且從參照資料表刪除資料列會觸發數百萬筆資料列的刪除作業,則應在設計結構時,使用「交錯式父項」的刪除層級動作。

比較表

下表概要比較強制外鍵和資料表交錯的差異。您可以根據這項資訊,決定適合設計的內容。

父項/子項關係類型 資料表交錯 強制外鍵
可使用主鍵
可使用非主鍵欄
支援的父項數量 0 .. 1 0 .. N
將父項和子項資料一起儲存
支援逐步刪除
空值比對模式 如果所有參照值與參照值不相符,則會通過。
空值與空值不相符;空值與非空值相符。
如果任何參照值為空值,則會通過。
如果所有參照值均非空值,且參照表中有值等於參照值的資料列,則會通過。
如果找不到相符的資料列,則會失敗。
違規處置時間 使用 mutation API 時,每個作業。
使用 DML 時,每個陳述式。
使用 mutation API 時,每筆交易。
使用 DML 時,每個陳述式。
可移除 否。除非刪除整個子項資料表,否則建立後就無法移除資料表交錯。

支援索引

外鍵不會使用使用者建立的索引。而是自行建立索引。強制資訊外鍵在 Spanner 中建立的支援索引方式不同:

  • 對於強制外鍵,Spanner 最多可為每個外鍵建立兩個次要備援索引,一個用於參照欄,另一個用於參照的欄。

  • 針對資訊外鍵,Spanner 可視需要為參照欄建立最多一個備援索引。資訊外鍵不會為參照欄建立備份索引。

無論是強制外鍵或資訊外鍵,外鍵通常都會參照參照資料表的主鍵,因此通常不需要參照資料表的索引。因此,資訊外部索引鍵通常沒有任何支援索引。如有需要,為參照資料表建立的備援索引就是 UNIQUE NULL_FILTERED 索引。如果任何現有資料違反索引的唯一性限制,建立外部索引的作業就會失敗。

資訊外部索引鍵沒有參照資料表的支援索引。對於強制外部索引鍵,參照資料表的備用索引為 NULL_FILTERED

如果有兩個以上的外鍵需要相同的備援索引,Spanner 會為每個外鍵建立一個索引。當使用這些索引的外部鍵遭到刪除時,系統也會刪除基礎索引。您無法變更或捨棄備援索引。

Spanner 會使用每個資料庫的資訊結構定義,儲存關於支援索引的中繼資料。INFORMATION_SCHEMA.INDEXESSPANNER_IS_MANAGED 值為 true 的資料列,會描述備援索引。

除了直接叫用資訊結構描述的 SQL 查詢外,Google Cloud 主控台不會顯示任何關於資料庫支援索引的資訊。

長期執行的結構定義變更

在現有資料表中加入強制外鍵,或使用外鍵建立新資料表,可能會導致作業執行時間過長。在建立新表格的情況下,必須等到長時間執行的作業完成後,才能寫入表格。

下表說明在 Spanner 中,當強制外鍵和資訊外鍵位於新資料表或現有資料表時,會發生什麼情況:

資料表類型 強制外鍵 資訊外鍵
新增 Spanner 會視需要為每個外部索引鍵回填參照的索引。 Spanner 會視需要為每個外部索引鍵回填參照的索引。
現有 Spanner 會視需要回填參照和參照索引。Spanner 也會驗證資料表中的現有資料,確保資料符合外鍵的參照完整性限制條件。如果有任何資料無效,結構定義變更就會失敗。 Spanner 會視需要回填參照的索引,且不會驗證資料表中的現有資料。

系統不支援下列功能:

  • 在現有的強制外鍵限制中新增外鍵動作。
  • 變更現有外鍵的強制執行方式。

無論是哪種情況,我們都建議您改為採取以下做法:

  1. 新增限制條件,並加入必要的動作或執行機制。
  2. 放棄舊的限制。

新增限制並放棄舊限制,可避免發生「長時間執行的變更限制作業」問題。舉例來說,假設您想在現有外鍵上新增 DELETE CASCADE 動作。使用 ON DELETE CASCADE 動作建立新的外部鍵後,兩個限制的效果都是 DELETE CASCADE 動作。接著,您就可以放心刪除舊的限制。

如果其他外部索引鍵限制未使用索引,則移除限制可能會導致移除外部索引鍵支援索引。因此,如果先刪除舊的限制條件,之後再透過動作新增相同的外部鍵限制條件,可能會導致執行時間過長的作業,例如回填索引、驗證不重複索引限制條件,或驗證外部鍵參照限制條件。

您可以查詢 INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS.SPANNER_STATE,檢查外鍵建立狀態。

後續步驟