建立及管理檢查限制

CHECK 限制條件可讓您指定一或多個資料欄的值必須符合布林運算式。本頁面說明如何在 GoogleSQL 方言資料庫和 PostgreSQL 方言資料庫中,新增及管理這類限制。

為新資料表新增檢查條件約束

在下列 CREATE TABLE 程式碼片段中,我們建立資料表來儲存演唱會相關資訊。如要規定演唱會的結束時間必須晚於開始時間,我們需要加入檢查限制。

GoogleSQL

CREATE TABLE Concerts (
  ConcertId INT64,
  StartTime Timestamp,
  EndTime Timestamp,
  CONSTRAINT start_before_end CHECK(StartTime < EndTime),
) PRIMARY KEY (ConcertId);

PostgreSQL

CREATE TABLE Concerts (
  ConcertId BIGINT,
  StartTime TIMESTAMPTZ,
  EndTime TIMESTAMPTZ,
  CONSTRAINT start_before_end CHECK(StartTime < EndTime),
  PRIMARY KEY (ConcertId)
);

限制定義以 CONSTRAINT 關鍵字開頭。我們已在這個範例中明確命名限制 start_before_end,方便您在錯誤訊息中找到該限制,以及在需要參照該限制時使用。如果未提供名稱,Spanner 會提供一個,產生的名稱開頭為前置字元 CK_。限制名稱的範圍是結構定義,與資料表和索引的名稱相同,且在結構定義中不得重複。檢查限制定義包含 CHECK 關鍵字,後接括號中的運算式。運算式只能參照這個資料表的資料欄。在本例中,它會參照 StartTimeEndTime,而檢查限制會確保演唱會的開始時間一律早於結束時間。

插入新資料列或更新現有資料列的 StartTimeEndTime 時,系統會評估檢查限制運算式的值。如果運算式評估結果為 TRUENULL,檢查限制會允許資料變更。如果運算式評估結果為 FALSE,系統就不允許變更資料。

  • 檢查限制 expression 條件有以下限制。

    • 運算式只能參照同一資料表中的資料欄。

    • 運算式必須參照至少一個非產生的資料欄,無論是直接參照,還是透過參照非產生資料欄的產生資料欄參照。

    • 運算式不得參照已設定 allow_commit_timestamp 選項的資料欄。

    • 運算式不得包含子查詢

    • 運算式不得包含非決定性函式,例如 CURRENT_DATE()CURRENT_TIMESTAMP()

在現有資料表中新增檢查限制

使用下列 ALTER TABLE 陳述式新增限制,確保所有演唱會 ID 都大於零。

ALTER TABLE Concerts
ADD CONSTRAINT concert_id_gt_0 CHECK (ConcertId > 0);

我們再次為限制條件命名,這次是 concert_id_gt_0。在現有資料表新增 CHECK 限制後,系統會立即對新資料強制執行限制,並開始執行長時間執行的作業,驗證現有資料是否符合新限制。由於這項驗證是透過長時間執行的作業進行,因此不會影響資料表上進行中的交易。詳情請參閱「結構定義更新效能」。如果現有資料有任何違規情形,系統會回溯限制。

移除檢查限制

下列 DDL 陳述式會從 Concerts 資料表捨棄 CHECK 限制。

ALTER TABLE Concerts
DROP CONSTRAINT concert_id_gt_0;

修改檢查限制運算式

不允許修改 CHECK 限制的運算式。您必須捨棄現有限制,並使用新運算式建立新限制。

查看檢查條件約束的屬性

Spanner 的 INFORMATION_SCHEMA 包含資料庫的檢查限制資訊。以下列舉幾個可透過查詢資訊結構定義回答的問題。

資料庫中定義了哪些檢查條件約束?

SELECT tc.CONSTRAINT_NAME, tc.TABLE_NAME, tc.CONSTRAINT_TYPE
FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS as tc
WHERE tc.CONSTRAINT_TYPE = 'CHECK';

資料庫中的檢查限制目前狀態為何?

如果您已在現有資料表中新增檢查限制,可能需要查看目前狀態,判斷是否已根據限制驗證所有現有資料。如果下列查詢中的 SPANNER_STATE 傳回 VALIDATING_DATA,表示 Spanner 仍在根據該限制驗證現有資料。

SELECT cc.CONSTRAINT_NAME, cc.SPANNER_STATE
FROM INFORMATION_SCHEMA.CHECK_CONSTRAINTS as cc;

後續步驟