C# 如何确保输入的时间范围不重叠?
我需要确保我的数据库只包含两个或更多列是唯一的条目。这可以通过对这些列使用C# 如何确保输入的时间范围不重叠?,c#,sql,postgresql,database-design,exclusion-constraint,C#,Sql,Postgresql,Database Design,Exclusion Constraint,我需要确保我的数据库只包含两个或更多列是唯一的条目。这可以通过对这些列使用唯一的约束轻松实现 在我的例子中,我只需要在重叠的时间范围内禁止复制。该表有valid\u from和valid\u to列。在某些情况下,可能首先需要通过设置valid\u to=now,然后插入调整为valid\u from=now和valid\u to=infinity的新条目,使活动条目过期 使用UPDATE,我似乎可以在没有任何问题的情况下使以前的条目过期,但是插入新条目似乎很麻烦,因为我的基本列当前是唯一的,因
唯一的约束轻松实现
在我的例子中,我只需要在重叠的时间范围内禁止复制。该表有valid\u from
和valid\u to
列。在某些情况下,可能首先需要通过设置valid\u to=now
,然后插入调整为valid\u from=now
和valid\u to=infinity
的新条目,使活动条目过期
使用UPDATE
,我似乎可以在没有任何问题的情况下使以前的条目过期,但是插入新条目似乎很麻烦,因为我的基本列当前是唯一的,因此无法再次添加
我曾想过将valid\u从
添加到
,并将valid\u添加到
,作为UNIQUE
约束的一部分,但这只会使约束更加松散,并允许
存在重复和重叠的时间范围
如何进行约束以确保不存在重叠的valid\u from
和valid\u to
tsrange
我似乎在寻找使用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\u gist
。每分贝一次。在我的示例中需要它,因为默认情况下,没有为类型integer
安装所需的运算符类:
CREATE EXTENSION btree_gist;
见:
然后:
创建表注册(
tbl_id默认情况下作为标识生成的整数主键
,col_是一个不为空的整数
,列b整数不为空
,从时间戳开始有效
,对时间戳有效
,约束无重叠
排除使用gist(列a与=、列b与=、tsrange(有效列from、有效列to)与&&)
);代码>
每个列都需要列出其各自的运算符
你需要一个范围类型。您提到了从
到
的独立列valid\u和valid\u到
。您还可以在失败的命令中提到tsrange
和valid
。那太令人困惑了。假设有两列timestamp
列,则使用表达式tsrange(valid\u from,valid\u to)
的表达式索引即可
相关的:
通常,timestamp
(tstzrange
)应该选择在timestamp
(tsrange
)之上。见:
也许,一个更好的设计是您的注册
表与新的注册范围
表中的1-N个条目之间的一对多关系。和一些逻辑来确定当前有效的条目(对于任何给定的时间点)。取决于更多未披露的信息。准确(最小)的表定义将是有用的(CREATE table
语句)。永远是你的博士后版本。另外,为什么您的解决方案似乎不起作用?有错误消息吗?您可以免费安装扩展吗?
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 &&)
);