[英]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.