PostgreSQL 约束,在提交时检查,而不是更早检查

dot*_*otz 8 sql postgresql constraints unique-index unique-constraint

是否可以在 PostgreSQL 中创建唯一索引或其他类型的约束,这将在事务 COMMIT 上进行检查,而不是提前一毫秒?

我需要一对 (record_id, ordering) 的索引,因此我确保在给定的 record_id 中只有一个且不超过一个记录具有相同的顺序。问题出在哪里?好吧,问题在于我使用的 Web 框架处理重新排序项目的方式。看起来,当移动一个项目时,当其排序顺序发生更改时,框架会使用新的排序值写入新项目,然后不久之后它会更新另一个项目,从而创建一种临时情况,其中多个记录具有相同的订购值。重新排序所有内容后,所有记录都会更新,并且在事务提交时,一切都应该再次正常。

如果重要的话,我正在使用 PostgreSQL 10。

kro*_*lko 10

使用SET CONSTRAINTS命令:

\n\n
\n

设定限制

\n\n

SET CONSTRAINTS \xe2\x80\x94 设置当前事务的约束检查时序

\n\n

概要

\n\n
SET CONSTRAINTS { ALL | name [, ...] } { DEFERRED | IMMEDIATE }\n
Run Code Online (Sandbox Code Playgroud)\n\n

描述

\n\n

SET CONSTRAINTS 设置当前事务中约束检查的行为。在每个语句末尾检查 IMMEDIATE 约束。在事务提交之前不会检查 DEFERRED 约束。每个约束都有自己的\n IMMEDIATE 或 DEFERRED 模式。

\n\n

创建时,约束会被赋予以下三个特征之一:\n DEFERRABLE INITIALLY DEFERRED、DEFERRABLE INITIALLY IMMEDIATE 或 NOT\n DEFERRABLE。第三类始终是 IMMEDIATE,并且不受 SET CONSTRAINTS 命令的影响。前两个类以指定模式启动每个事务,但可以通过 SET CONSTRAINTS 在事务内更改它们的行为。

\n\n

带有约束名称列表的 SET CONSTRAINTS 仅更改那些约束(必须全部可延迟)的模式。每个约束名称都可以是架构限定的。如果未指定架构名称,则使用当前架构搜索路径来查找第一个匹配名称。SET\n CONSTRAINTS ALL 更改所有可延迟约束的模式。

\n\n

当 SET CONSTRAINTS 将约束模式从 DEFERRED 更改为 IMMEDIATE 时,新模式将追溯生效:在事务结束时检查的任何未完成的数据修改将在执行期间检查。 SET\n 约束命令。如果违反任何此类约束,则 SET\n CONSTRAINTS 将失败(并且不会更改约束模式)。因此,SET\n CONSTRAINTS 可用于强制在事务中的特定点进行约束检查。

\n\n

目前,只有 UNIQUE、PRIMARY KEY、REFERENCES(外键)和\n EXCLUDE 约束受此设置影响。当插入或修改行时(而不是在语句末尾),总是立即检查 NOT NULL 和 CHECK\n 约束。尚未声明 DEFERRABLE 的唯一性和排除约束也会立即检查。

\n\n

声明为 \xe2\x80\x9cconstraint 触发器\xe2\x80\x9d 的触发器的触发也由此设置控制 \xe2\x80\x94 它们在检查关联约束的同时触发\n 。

\n
\n\n
\n\n

您还可以在(例如)CREATE TABLE的参考文档中找到这一点

\n\n
[ CONSTRAINT constraint_name ]\n{ NOT NULL |\n  NULL |\n  CHECK ( expression ) [ NO INHERIT ] |\n  DEFAULT default_expr |\n  GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY [ ( sequence_options ) ] |\n  UNIQUE index_parameters |\n  PRIMARY KEY index_parameters |\n  REFERENCES reftable [ ( refcolumn ) ] [ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ]\n    [ ON DELETE action ] [ ON UPDATE action ] }\n[ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ]\n
Run Code Online (Sandbox Code Playgroud)\n\n

约束可以是:

\n\n
    \n
  • 最初推迟| 最初立即
  • \n
  • 可延期| 不可延期
  • \n
\n