来自PostgreSQL文档
排除约束确保如果使用指定的运算符在指定的列或表达式上比较任何两行,则这些运算符比较中的至少一个将返回false或null.语法是:
Run Code Online (Sandbox Code Playgroud)CREATE TABLE circles ( c circle, EXCLUDE USING gist (c WITH &&) );
我想知道是什么EXCLUDE USING gist (c WITH &&)意思?特别是gist(),c WITH &&和EXCLUDE USING.
它可以改写check吗?谢谢.
我正在创建一个在PostgreSQL 9.2.4中存储任意日期/时间范围的数据库.我想在这个数据库上设置一个约束,它强制日期/时间范围不重叠,不相邻(因为两个相邻的范围可以表示为单个连续范围).
为此,我使用EXCLUDE带有GiST索引的约束.这是我目前的约束:
ADD CONSTRAINT overlap_exclude EXCLUDE USING GIST (
box(
point (
extract(EPOCH FROM "from") - 1,
extract(EPOCH FROM "from") - 1
),
point (
extract(EPOCH FROM "to"),
extract(EPOCH FROM "to")
)
) WITH &&
);
Run Code Online (Sandbox Code Playgroud)
列from和to都是TIMESTAMP WITHOUT TIME ZONE,并且是以UTC格式存储的日期/时间(在我的应用程序中将数据插入这些列之前,我转换为UTC,并且我在postgresql.conf中将我的数据库的时区设置为"UTC").
但是,我想我可能遇到的问题是,这个约束正在做出(错误的)假设,即没有小于一秒的时间增量.
值得注意的是,对于我存储的特定数据,我只需要第二个分辨率.不过,我觉得我可能还是需要处理这个,因为SQL类型timestamp和timestamptz都超过一秒更高的分辨率.
我的问题是:是否有任何问题,只是假设第二个解决方案,因为这是我的所有应用程序需要(或想要),或者,如果有,我怎么能改变这个约束来处理一个秒的分数健壮的方式?
是否有约束或其他一些 PostgreSQL 功能阻止 CIDR 列的值重叠?
例如:
192.168.1.0/24和192.168.1.1/32
它们不能共存,因为192.168.1.1/32它们包含在192.168.1.0/24子网中。
我已经定义了这个表:
CREATE TABLE market.price_history (
item_id bigint NOT NULL,
valid_time tstzrange DEFAULT tstzrange(now(), 'infinity'),
sale_price money NOT NULL,
promo_code bool NOT NULL DEFAULT false,
EXCLUDE USING gist(item_id WITH =, valid_time WITH &&),
EXCLUDE USING gist(item_id WITH =, sale_price WITH =, valid_time WITH &&)
);
Run Code Online (Sandbox Code Playgroud)
但是当我执行此 SQL 时:
WITH new_row_valid_time as(
SELECT tstzrange(MAX(upper(valid_time)),
'infinity'::timestamptz) as adjacent_valid_time
FROM market.price_history
WHERE item_id = 11
)
INSERT INTO market.price_history as ph
(item_id, valid_time, sale_price, promo_code)
VALUES(11, -- same id as existent row
(SELECT adjacent_valid_time …Run Code Online (Sandbox Code Playgroud) 例如:索引为userid, sdate,edate
userid sdate edate
001 2019-01-01 2019-01-30
Run Code Online (Sandbox Code Playgroud)
如果我插入新数据,例如:
userid sdate edate
001 2019-01-03 2019-01-20
or
001 2019-01-13 2019-02-10
or
001 2019-02-01 2019-02-15
Run Code Online (Sandbox Code Playgroud)
我在下面尝试使用 GIST,但是如何使用 来组合它ON CONFLICT?
CREATE EXTENSION btree_gist
CREATE TABLE test(
ID INT PRIMARY KEY NOT NULL,
USERID CHAR(5),
SDATE DATE,
EDATE DATE,
EXCLUDE USING gist
(USERID WITH =,
daterange(SDATE, EDATE, '[]') WITH &&)
);
Insert Into test (usersid, sdate, edate)
Values (@UsersId, @SDate, @EDate)
ON Conflict ON CONSTRAINT test_userid_daterange_excl
Do Update …Run Code Online (Sandbox Code Playgroud) 我读了一本书
排除约束
CREATE TABLE movies
(
Title TEXT,
Copies INTEGER
);
ALTER TABLE movies ADD EXCLUDE (title WITH=, copies WITH=);
Run Code Online (Sandbox Code Playgroud)
排除约束是什么意思?Microsoft SQL Server 中的相应术语(和示例 SQL 脚本)是什么?
我正在尝试对下表完成 PostgreSQL 约束:
CREATE TABLE contracts
(
id bigint NOT NULL,
startdate date NOT NULL,
enddate date NOT NULL,
price numeric(19,2) NOT NULL,
deleted boolean NOT NULL,
supplier_id bigint NOT NULL,
)
Run Code Online (Sandbox Code Playgroud)
它包含不同价格的供应商合同。在给定时间内,给定供应商只能存在一份合同。我制定了以下约束来强制执行:
ALTER TABLE contracts ADD CONSTRAINT overlaping_contracts EXCLUDE USING GIST (
supplier_id WITH =,
daterange(startdate, enddate) WITH &&
);
Run Code Online (Sandbox Code Playgroud)
这确保了不能插入与现有合同重叠的新合同。现在我们还支持合约的“软删除”。这会使旧合同无效并将“已删除”标志设置为 true。现在我想插入同一时期的新合同,但这重叠触发了约束。
我尝试将条件唯一索引与上述约束结合起来,但无法使其工作。有关排除约束的文档非常少。
我的直觉告诉我我必须添加类似的东西
deleted = false
Run Code Online (Sandbox Code Playgroud)
到排除约束,但我找不到正确的语法来执行此操作。
如何将排除约束与条件唯一索引结合起来,以便仅对已删除 = false 的行强制执行重叠约束?
简化的 MN 连接表
CREATE TABLE dummy (
fkey1 int, /* omitting FK clause */
fkey2 int,
/* could also separate begin and end dates */
effective_dates_of_assignment daterange,
EXCLUDE /* WHAT GOES HERE?? */
)
Run Code Online (Sandbox Code Playgroud)
我想要一个明显的排除规则,即如果fkey字段相同,则日期不会重叠。(如果密钥不同,则不排除。)
到目前为止,我最好的想法是添加贡献的多维数据集模块并在所有三个字段上创建一个要点多列索引。但是,尽管它看起来像一个 3D 立方体,但其中两个立方体的重叠约束将会退化。那么这里发生的是
EXCLUDE USING gist (cube([fkey1, fkey2, lower(effective_dates_of_assignment)],
[fkey1, fkey2, upper(effective_dates_of_assignment)])
WITH &&)
Run Code Online (Sandbox Code Playgroud)
这个使用附加模块的解决方案对于相对常见的用例来说是否是最佳的?