Tạo hai chỉ mục từng phần :
CREATE UNIQUE INDEX favo_3col_uni_idx ON favorites (user_id, menu_id, recipe_id)
WHERE menu_id IS NOT NULL;
CREATE UNIQUE INDEX favo_2col_uni_idx ON favorites (user_id, recipe_id)
WHERE menu_id IS NULL;
Bằng cách này, chỉ có thể có một tổ hợp (user_id, recipe_id)
trong đó menu_id IS NULL
, triển khai hiệu quả các ràng buộc mong muốn.
Hạn chế có thể có:
- Bạn không thể có khóa ngoại tham chiếu đến
(user_id, menu_id, recipe_id)
. (Có vẻ như bạn không muốn tham chiếu FK rộng ba cột - hãy sử dụng cột PK thay thế!) - Bạn không thể căn cứ
CLUSTER
trên một chỉ mục một phần. - Các truy vấn không có
WHERE
phù hợp điều kiện không thể sử dụng chỉ mục một phần.
Nếu bạn cần một hoàn chỉnh chỉ mục, bạn có thể thả WHERE
một cách khác điều kiện từ favo_3col_uni_idx
và các yêu cầu của bạn vẫn được thực thi.
Chỉ mục, hiện bao gồm toàn bộ bảng, trùng lặp với bảng kia và lớn hơn. Tùy thuộc vào các truy vấn điển hình và tỷ lệ phần trăm NULL
giá trị này có thể hữu ích hoặc không. Trong những tình huống khắc nghiệt, nó thậm chí có thể giúp duy trì cả ba chỉ mục (hai chỉ mục một phần và một chỉ mục tổng ở trên cùng).
Đây là một giải pháp tốt cho một cột có thể trống duy nhất , có thể cho hai. Nhưng nó sẽ nhanh chóng vượt qua khỏi tầm tay vì bạn cần một chỉ mục riêng biệt cho mọi tổ hợp các cột có thể nullable, do đó, số lượng tăng lên theo phương thức nhị thức. Đối với nhiều cột có thể nullable , thay vào đó hãy xem:
- Tại sao ràng buộc DUY NHẤT của tôi không kích hoạt?
Ngoài ra:Tôi khuyên bạn không nên sử dụng các mã nhận dạng trường hợp hỗn hợp trong PostgreSQL.