Postgresql
如何在不鎖定表的情況下在 Postgres 中添加檢查約束?
我想向一個非常大的表添加一個檢查約束。就像是:
ALTER TABLE "accounts" ADD CONSTRAINT "positive_balance" CHECK ("balance" >= 0);
不幸的是,PostgreSQL 9.3 會阻止讀取或寫入,直到完成約束檢查。我通過啟動事務、執行
ALTER TABLE
、然後打開第二個事務並檢查在第一個事務完成之前我無法從表中讀取或寫入來驗證這一點。有什麼方法可以在
CHECK
不鎖定表的情況下添加此約束?
您可以創建一個
NOT VALID
CHECK 約束,它將強制執行該約束,但不會在創建時檢查整個表以進行驗證。在以後的某個日期,您可以嘗試VALIDATE
約束(當表上的鎖定正常時)請查看文件- 引用如下:
ADD table_constraint [ NOT VALID ]
這種形式使用與 相同的語法向表添加新約束
CREATE TABLE
,加上選項NOT VALID
,目前僅允許用於外鍵和 CHECK 約束。如果約束標記為NOT VALID
,則跳過可能很長的初始檢查以驗證表中的所有行是否滿足約束。約束仍將針對後續插入或更新強制執行(也就是說,除非引用表中存在匹配行,否則它們將失敗,在外鍵的情況下;除非新行與指定的檢查匹配,否則它們將失敗約束)。但是數據庫不會假定約束適用於表中的所有行,直到使用該VALIDATE CONSTRAINT
選項對其進行驗證。