Tarih aralığı ile benzersizlik kısıtlaması


15

Şu pricessütunları içeren bir tablo düşünün :

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

Ben veritabanı bir ürünün bir tarih aralığında (üzerinden where <date> BETWEEN start_date AND end_date) belirli bir miktarda sadece bir fiyat olabilir kuralını uygulamak istiyorum .

Bu tür bir aralık tabanlı kısıtlama yapılabilir mi?

Yanıtlar:


23

Evet, EXCLUDEkısıtlamaların genelleştirilmesi olan bir UNIQUEkısıtlama kullanabilirsiniz:

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

Kısıtlama şu şekilde yorumlanabilir:

Aynı product_id, aynı quantityve çakışan ( &&) tarih aralıklarına sahip iki satıra izin verme .

İstenen '[]'her şey dahil tarih aralığı içindir (varsayılan [)aralık aralık türleri içindir).

Aralık türleriyle ilgili kısıtlamalar hakkındaki belgelere bakın . Ayrıca, uzantıyı çalıştırarak da eklemeniz gerekir (bir kez, bunun yüklenmesini istediğiniz her veritabanı için):

CREATE EXTENSION btree_gist;

Bu harika. Özel alt sınır daterangeolduğu için tam olarak aynı olduğunu düşünmüyorum , ancak bunu düzeltmek kolay. Verilerimi gerçekten bir daterangesütun türü kullanmak için mi taşımalıyım (bu daha iyi ise ayrı bir soru yapabilir) mi yoksa bu iki sütunlu şey makul mü?
başak

Eğer iyi hatırlıyorsam, kapsayıcı alt sınır ve özel üst sınır varsayılan. Her şey dahil için düzenleyeceğim. Genellikle otel benzeri uygulamalarda yaygın olduğu için varsayılanı tercih ederim. (Ben 2 de otelde olsun, ben 8th off, 6 gün kaldı. Bir sonraki işgalci 8th gelebilir)
ypercubeᵀᴹ

Aslında tersine çevrilmiş olabilirim ... bugün sadece aralık türleri hakkında bilgi edindim ve belgeleri okuyorum!
başak

Neyin tercih edileceğinden emin değilim, 2 sütun veya tarih aralığı olan bir tane. Ayrı bir soru sorabilirsiniz. Muhtemelen istediğiniz kullanıma, sorgulara, kullanım kolaylığına (ve dizin gereksinimlerine) bağlı olacaktır. Ayrı sütunlar varsa, örneğin üzerinde bir dizin olması daha kolay olur (product_id, start_date). Bir tarih (product_id, lower(range_column))
aralığı
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.