2012-01-18 29 views
6

Tôi có một bảng line_items với các cột sau:Làm thế nào để thêm một chỉ số duy nhất có điều kiện trên PostgreSQL

product_id 
variant_id 

variant_id là nullable.

Đây là điều kiện:

  • Nếu variant_id là NULL thì product_id phải là duy nhất.
  • Nếu variant_id có giá trị thì sự kết hợp của product_idvariant_id phải là duy nhất.

Điều đó có thể thực hiện được trong PostgreSQL không?

Trả lời

20

Tạo một UNIQUE multicolumn INDEX trên (product_id, variant_id):

CREATE UNIQUE INDEX line_items_prod_id_var_id_idx 
ON line_items (product_id, variant_id); 

Tuy nhiên, điều này sẽ cho phép nhiều mục của (1, NULL) cho (product_id, variant_id)NULL giá trị không được coi là giống hệt nhau.
Để bù đắp cho điều đó, bổ sung tạo ra một partial UNIQUE INDEX trên product_id:

CREATE UNIQUE INDEX line_items_prod_id_var_null_idx 
ON line_items (product_id) 
WHERE variant_id IS NULL; 

Bằng cách này bạn có thể nhập (1,2), (1,3)(1, NULL), nhưng cả hai đều không một lần thứ hai. Đồng thời tăng tốc truy vấn với các điều kiện trên một hoặc cả hai cột.

answer on dba.SE Gần đây tôi đã viết rất giống và gần như trực tiếp áp dụng cho vấn đề của bạn.

0

Tùy chọn khác là sử dụng các biểu thức trong các trường khóa của bạn. Điều này có thể không xảy ra khi bạn đặt câu hỏi, nhưng có thể hữu ích cho những người khác gặp phải vấn đề này ngay bây giờ.

CREATE UNIQUE INDEX line_items_prod_id_var_id_idx 
ON line_items (product_id, (coalesce(variant_id, 0))); 

Cấp, điều này giả định rằng variant_id của bạn là một số nguyên auto-incrementing mà bắt đầu tại 1. Cũng lưu ý các dấu ngoặc xung quanh khái niệm. Mỗi tài liệu, chúng được yêu cầu.

http://www.postgresql.org/docs/9.3/static/sql-createindex.html

Các vấn đề liên quan