Mic*_*ael 6 sql postgresql constraints date-range
我有一个表格,描述了在不同时间在机器上安装了哪些软件版本:
machine_id::integer, version::text, datefrom::timestamp, dateto::timestamp
Run Code Online (Sandbox Code Playgroud)
我想做一个限制,以确保没有日期范围重叠,即不可能同时在一台机器上安装多个软件版本.
如何在SQL中实现这一目标?我正在使用PostgreSQL v8.4.
Ant*_*sma 12
在PostgreSQL 8.4中,这只能通过触发器来解决.触发器必须检查插入/更新是否存在冲突行.由于事务可序列化不实现谓词锁定,因此您必须自己进行必要的锁定.要SELECT FOR UPDATE
在计算机表中执行该操作,以便其他任何事务都不能同时插入可能冲突的数据.
在PostgreSQL 9.0中,将有一个更好的解决方案,称为排除约束(在CREATE TABLE中有所记录).这将允许您指定日期范围不得重叠的约束.该功能的作者杰夫戴维斯对此进行了两部分的写作:第1 部分,第2部分.Depesz还有一些描述该功能的代码示例.
与此同时(从版本9.2开始,如果我正确阅读了手册),postgreSQL增加了对rangetypes的支持.
使用这些范围,问题突然变得非常简单(例子从手册中复制):
CREATE TABLE reservation (
during tsrange,
EXCLUDE USING gist (during WITH &&)
);
Run Code Online (Sandbox Code Playgroud)
就是这样.测试(也从手册中复制):
INSERT INTO reservation VALUES
('[2010-01-01 11:30, 2010-01-01 15:00)');
Run Code Online (Sandbox Code Playgroud)
INSERT 0 1
INSERT INTO reservation VALUES
('[2010-01-01 14:45, 2010-01-01 15:45)');
Run Code Online (Sandbox Code Playgroud)
错误:冲突的键值违反排除约束"reservation_during_excl"DETAIL:键(期间)=(["2010-01-01 14:45:00","2010-01-01 15:45:00"))与现有冲突key(during)=(["2010-01-01 11:30:00","2010-01-01 15:00:00")).
归档时间: |
|
查看次数: |
4269 次 |
最近记录: |