Làm cách nào để thêm một ràng buộc kiểm tra trong Postgres mà không khóa bảng?


9

Tôi muốn thêm một ràng buộc kiểm tra vào một bảng rất lớn. Cái gì đó như:

ALTER TABLE "accounts" ADD CONSTRAINT "positive_balance" CHECK ("balance" >= 0);

Thật không may, khối PostgreQuery 9.3 đọc hoặc ghi cho đến khi hoàn thành kiểm tra ràng buộc. Tôi đã xác minh điều này bằng cách bắt đầu một giao dịch, chạy ALTER TABLE, sau đó mở giao dịch thứ hai và kiểm tra xem tôi không thể đọc hoặc ghi từ bảng cho đến khi giao dịch đầu tiên hoàn thành.

Có cách nào tôi có thể thêm CHECKràng buộc này mà không khóa bảng không?


Điều này không cụ thể đối với các ràng buộc kiểm tra. Tất cả (hoặc gần như tất cả) các câu lệnh DDL yêu cầu một khóa độc quyền trên bàn - điều này cũng không có gì đặc biệt đối với Postgres, hầu hết DBMS hoạt động theo cách đó cho các câu lệnh DDL.
a_horse_with_no_name

Câu trả lời:


11

Bạn có thể tạo NOT VALIDràng buộc KIỂM TRA, điều này sẽ thực thi ràng buộc về phía trước, nhưng sẽ không kiểm tra toàn bộ bảng để xác thực khi tạo. Vào một số ngày sau đó, bạn có thể cố gắng VALIDATEràng buộc (khi khóa trên bàn là ok)

Vui lòng xem lại tài liệu - Trích dẫn dưới đây:

ADD table_constraint [ NOT VALID ]

Biểu mẫu này thêm một ràng buộc mới vào một bảng bằng cách sử dụng cú pháp tương tự như CREATE TABLE, cộng với tùy chọn NOT VALID, hiện chỉ được phép cho các ràng buộc khóa ngoài và CHECK. Nếu ràng buộc được đánh dấu NOT VALID, kiểm tra ban đầu có khả năng kéo dài để xác minh rằng tất cả các hàng trong bảng thỏa mãn ràng buộc được bỏ qua. Ràng buộc vẫn sẽ được thi hành đối với các lần chèn hoặc cập nhật tiếp theo (nghĩa là chúng sẽ thất bại trừ khi có một hàng khớp trong bảng được tham chiếu, trong trường hợp có khóa ngoại; và chúng sẽ thất bại trừ khi hàng mới khớp với kiểm tra được chỉ định ràng buộc). Nhưng cơ sở dữ liệu sẽ không cho rằng ràng buộc giữ cho tất cả các hàng trong bảng, cho đến khi được xác thực bằng cách sử dụng VALIDATE CONSTRAINTtùy chọn.


6

(Không đủ đại diện để nhận xét về câu trả lời khác)

Không rõ từ cụm từ trong câu trả lời được chấp nhận "khi khóa trên bàn là ok" nghĩa là gì.

Theo tài liệu của Postgres ALTER TABLE :

VALIDATE CONSTRAINTlấy một cái SHARE UPDATE EXCLUSIVEtrên bàn đã thay đổi

và từ các tài liệu Khóa

SHARE UPDATE EXCLUSIVEcho phép giao dịch đồng thời khác để có được một ROW EXCLUSIVEkhóa (được sử dụng bởi INSERT, UPDATE, DELETE), và SELECTđược phép với bất kỳ khóa kiểu ngoài ACCESS EXCLUSIVE.

Ý nghĩa - "đọc / ghi" sẽ không bị chặn khi chạy VALIDATE CONSTRAINT- bạn không cần phải "đợi cho đến khi khóa bàn".


1
Tại thời điểm viết (PostgreQuery 9.3), đã VALIDATE CONSTRAINTlấy một ACCESS EXCLUSIVEkhóa. Tuy nhiên, đây là thông tin tốt cho độc giả và phiên bản trong tương lai. +1 từ tôi
Joishi Bodio

Ah, tốt để biết - cảm ơn đã cập nhật / làm rõ!
lùn
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.