web-dev-qa-db-ja.com

日付範囲の一意性制約

これらの列を持つ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を介して)日付範囲内の特定の数量の商品には1つの価格しか設定できないというルールを適用したいと思います。

この種の範囲ベースの制約は実行可能ですか?

15
spike

はい、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、重複する(&&)日付範囲を持つ2つの行を許可しないでください。

'[]'は、必要なすべてを含む日付範囲用です(範囲タイプのデフォルトは[)です)。

範囲タイプの制約 に関するドキュメントを参照してください。おそらく次のコマンドを実行して拡張機能を追加する必要もあります(これをインストールするデータベースごとに)。

CREATE EXTENSION btree_Gist;
23
ypercubeᵀᴹ