我们有一个用例,我们将 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/