Ràng buộc duy nhất với phạm vi ngày


15

Hãy xem xét một pricesbảng với các cột sau:

id         integer primary key
product_id integer -- foreign key
start_date date not null
end_date   date not null
quantity   integer
price      numeric

Tôi muốn cơ sở dữ liệu thực thi quy tắc rằng một sản phẩm chỉ có thể có một mức giá ở một số lượng cụ thể trong phạm vi ngày (thông qua where <date> BETWEEN start_date AND end_date).

Là loại ràng buộc dựa trên phạm vi có thể thực hiện được?

Câu trả lời:


23

Có, bạn có thể sử dụng một EXCLUDEràng buộc, đó là một khái quát của các UNIQUEràng buộc:

ALTER TABLE prices 
  ADD CONSTRAINT unique_price_per_product_quantity_daterange
    EXCLUDE  USING gist
    ( product_id WITH =, 
      quantity WITH =, 
      daterange(start_date, end_date, '[]') WITH &&   -- this is the crucial
    );

Các ràng buộc có thể được hiểu là nói:

Không cho phép hai hàng có phạm vi ngày giống nhau product_id, giống nhau quantityvà chồng chéo ( &&).

Đây '[]'là cho phạm vi ngày bao gồm tất cả mong muốn (mặc định là [)cho các loại phạm vi).

Xem tài liệu về các ràng buộc về các loại phạm vi . Có lẽ bạn cũng cần thêm tiện ích mở rộng bằng cách chạy (một lần, cho mỗi cơ sở dữ liệu nơi bạn muốn cài đặt này):

CREATE EXTENSION btree_gist;

Điều này thật tuyệt. Tôi không nghĩ daterangechính xác giống nhau vì nó là độc quyền ràng buộc thấp hơn, nhưng đó là dễ dàng để sửa chữa. Tôi có nên thực sự di chuyển dữ liệu của mình để sử dụng daterangeloại cột (có thể đặt câu hỏi riêng nếu điều đó tốt hơn) hoặc điều này có hợp lý không?
tăng đột biến

Mặc định bao gồm giới hạn dưới bao gồm và giới hạn trên độc quyền, nếu tôi nhớ rõ. Tôi sẽ chỉnh sửa cho toàn bộ. Tôi thường thích mặc định vì nó phổ biến trong các ứng dụng giống như khách sạn. (Tôi đến khách sạn lúc 2, tôi xuống lúc 8, ở lại 6 ngày. Người chiếm đóng tiếp theo có thể đến vào lúc 8)
ypercubeᵀᴹ

Tôi thực sự có thể được lật lên đó là ... chỉ cần tìm hiểu về các loại phạm vi ngày hôm nay và tôi đang đọc tài liệu!
tăng đột biến

Tôi không chắc chắn về những gì tốt hơn, 2 cột hoặc một cột với daterange. Bạn có thể hỏi một câu hỏi riêng biệt. Nó có thể sẽ phụ thuộc vào việc sử dụng bạn muốn, truy vấn, dễ sử dụng (và nhu cầu chỉ mục). Nếu có các cột riêng biệt, ví dụ như có một chỉ mục sẽ dễ dàng hơn (product_id, start_date). Với một daterange, đó sẽ phải là một chỉ số trên(product_id, lower(range_column))
ypercubeᵀᴹ
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.