ข้อ จำกัด ที่ไม่ซ้ำกับช่วงวันที่


15

พิจารณาpricesตารางที่มีคอลัมน์เหล่านี้:

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

ฉันต้องการให้ฐานข้อมูลบังคับใช้กฎว่าผลิตภัณฑ์หนึ่ง ๆ สามารถมีราคาหนึ่งรายการในปริมาณเฉพาะในช่วงวันที่ (ผ่านwhere <date> BETWEEN start_date AND end_date)

ข้อ จำกัด ประเภทนี้เป็นไปได้หรือไม่

คำตอบ:


23

ใช่คุณสามารถใช้EXCLUDEข้อ จำกัด ซึ่งเป็นลักษณะทั่วไปของUNIQUEข้อ จำกัด :

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
    );

ข้อ จำกัด สามารถตีความได้ว่าการพูด:

ไม่อนุญาตให้มีสองแถวที่มีช่วงวันที่product_idเหมือนกันquantityและทับซ้อนกัน ( &&)

'[]'สำหรับอยากช่วงวันที่รวมทุกอย่าง (เริ่มต้นคือ[)ชนิดช่วง)

ดูเอกสารเกี่ยวกับข้อ จำกัด ในประเภทช่วง คุณอาจต้องเพิ่มส่วนขยายด้วยการเรียกใช้ (หนึ่งครั้งสำหรับแต่ละฐานข้อมูลที่คุณต้องการติดตั้ง):

CREATE EXTENSION btree_gist;

นี่มันเจ๋งมาก. ฉันไม่คิดว่าdaterangeจะเหมือนกันเพราะมันเป็นขอบเขตล่างที่พิเศษ แต่ก็ง่ายที่จะแก้ไข ฉันควรจะโยกย้ายข้อมูลของฉันเพื่อใช้daterangeประเภทคอลัมน์ (อาจทำให้คำถามแยกต่างหากถ้าดีกว่า) หรือสิ่งที่สองคอลัมน์นี้สมเหตุสมผลหรือไม่
ขัดขวาง

ค่าเริ่มต้นในขอบเขตล่างรวมและขอบเขตพิเศษเฉพาะถ้าฉันจำได้ดี ฉันจะแก้ไขให้รวมทุกอย่าง ฉันมักจะชอบค่าเริ่มต้นเนื่องจากเป็นเรื่องปกติในแอปพลิเคชันที่เหมือนโรงแรม (ฉันได้รับที่โรงแรมที่ 2 ฉันลงที่ 8 พัก 6 วันผู้ครอบครองต่อไปสามารถมาที่ 8 ได้)
ypercubeᵀᴹ

จริง ๆ แล้วฉันอาจจะพลิกซึ่งเป็นที่ ... เพิ่งค้นพบเกี่ยวกับประเภทช่วงวันนี้และฉันกำลังอ่านเอกสาร!
ขัดขวาง

ฉันไม่แน่ใจเกี่ยวกับสิ่งที่เป็นที่นิยม 2 คอลัมน์หรือหนึ่งคอลัมน์ที่มี daterange คุณสามารถถามคำถามแยกต่างหาก มันอาจจะขึ้นอยู่กับการใช้งานที่คุณต้องการแบบสอบถามความสะดวกในการใช้งาน (และความต้องการดัชนี) (product_id, start_date)หากมีคอลัมน์ที่แยกต่างหากก็จะง่ายขึ้นเช่นการมีดัชนีใน ด้วย daterange ที่จะต้องเป็นดัชนีในวันที่(product_id, lower(range_column))
ypercubeᵀᴹ
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.