postgresql - 防止开始时间、结束时间列中的时间重叠

标签 postgresql database-design constraints

我们有一个用例,我们将 start_week 和 end_week 存储在一行中,并希望确保这些行之间的值永远不会重叠,即它们是互斥的。示例如下

Ideal
code - startw - endw
T1 - 201401 - 201404
T2 - 201405 - 201408
T3 - 201409 - 201416

Not Ideal
code - startw - endw
T1 - 201401 - 201404
T2 - 201403 - 201408
T3 - 201407 - 201408
T3 - 201406 - 201410

是否可以在 Postgres 中添加这样的约束,以便在插入过程中捕获错误?解决此类问题并避免插入而不是在插入数据后运行检查的最佳方法是什么。

最佳答案

PostgreSQL 有一个专门为此设计的功能 - exclusion constraints .

参见CREATE TABLE ... EXCLUDE ... .

出于您的目的,您需要 constraint on a range 。手册中介绍了您的情况。

由于您使用了奇怪的日期格式,这有点复杂;您需要将它们转换为 tstzrange 以用于排除约束。

create table exclude(code text, startw integer, endw integer);

insert into exclude(code, startw, endw) values
('T1', 201401, 201404),
('T2', 201405, 201408),
('T3', 201409, 201416);

你不能只是:

alter table exclude 
  add constraint no_overlapping_timestamps 
  EXCLUDE USING gist( tstzrange(startw, endw) WITH && );

因为你没有使用真实的时间戳;您必须将周数转换为上面表达式中的时间戳。我无法为你做到这一点,因为我不知道你如何定义“周”。如果这是标准方式,那么:

alter table exclude 
  add constraint no_overlapping_timestamps 
  EXCLUDE USING gist( tstzrange(to_date(startw, 'YYYYWW'), to_date(endw, 'YYYYWW')) WITH && );

关于postgresql - 防止开始时间、结束时间列中的时间重叠,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25890073/

相关文章:

通过 SSL 的 Postgresql LDAP 身份验证

Django-Postgres : how to group by DATE a datetime field with timezone enabled

postgresql - 如何编写一个迭代函数,使当前行输出基于先前行输出?

java - 领域对象共享微服务

swift - 如何在 swift 约束上使用 if else 语句

hibernate - Spring Boot spring.datasource.schema VS spring.jpa.properties.hibernate.default_schema

sql-server - 使用位掩码存储不相关的位列

database - 房间/人员管理应用程序数据库结构

mysql - MySQL中的完整性约束表示 "must have one primary attribute"

sql - Postgres中判断约束名称是否为系统生成