[英]How to ensure entries with non-overlapping time ranges?
我需要確保我的數據庫只包含其中兩個或更多列是唯一的條目。 這可以通過對這些列的UNIQUE
約束輕松實現。
就我而言,我只需要禁止重疊時間范圍的重復。 該表具有valid_from
和valid_to
列。 在某些情況下,可能首先需要通過設置valid_to = now
來使活動條目過期,然后插入一個調整為valid_from = now
和valid_to = infinity
的新條目。
我似乎可以使用UPDATE
使先前的條目過期而沒有任何問題,但是插入新條目似乎很麻煩,因為我的基列當前是UNIQUE
,因此無法再次添加。
我想添加valid_from
和valid_to
作為UNIQUE
約束的一部分,但這只會使約束更加松散,並允許存在重復和重疊的時間范圍。
如何進行約束以確保不存在重疊valid_from
和valid_to
tsrange
的重復項?
我似乎在尋找EXCLUDE USING GIST
,但它似乎不支持多列? 這似乎對我不起作用:
ALTER TABLE registration
DROP Constraint IF EXISTS registration_{string.Join('_', listOfAttributes)}_key,
ADD Constraint registration_{string.Join('_', listOfAttributes)}_key EXCLUDE USING GIST({string.Join(',', listOfAttributes)} WITH =, valid WITH &&);
你走在正確的軌道上。 但是排除約束的語法略有不同。
根據未公開的表定義,您可能需要先安裝擴展(附加模塊) btree_gist
。 每分貝一次。 我的示例需要它,因為默認情況下沒有為類型integer
安裝所需的運算符 class :
CREATE EXTENSION btree_gist;
看:
然后:
CREATE TABLE registration (
tbl_id integer PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY
, col_a integer NOT NULL
, col_b integer NOT NULL
, valid_from timestamp
, valid_to timestamp
, CONSTRAINT no_overlap
EXCLUDE USING gist (col_a with =, col_b with =, tsrange(valid_from, valid_to) WITH &&)
);
每列都需要列出其各自的運算符。
你需要一個范圍類型。 您提到了單獨的列valid_from
和valid_to
。 而且您還在失敗的命令中提到tsrange
和valid
。 這很令人困惑。 假設有兩個timestamp
列,一個帶有表達式tsrange(valid_from, valid_to)
的表達式索引可以做到這一點。
有關的:
通常,應該選擇timestamptz
( tstzrange
) 而不是timestamp
( tsrange
)。 看:
也許,一個優秀的設計將是您的registration_range
registration
中的1-N 個條目之間的一對多關系。 還有一些邏輯來確定當前有效的條目(對於任何給定的時間點)。 取決於更多未公開的信息。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.