我需要验证约束吗?

xeh*_*puk 3 postgresql constraint

我创建了一个外键约束,并且知道不存在违规情况,因此我将其标记为NOT VALID跳过检查。

\n

文档中:

\n
\n

但数据库不会假设该约束适用于表中的所有行,直到使用该VALIDATE CONSTRAINT选项对其进行验证为止。

\n
\n

它没有提到后果 \xe2\x80\x93甚至在注释\xe2\x80\x93 中也没有提及,如果有的话。

\n

如果约束没有标记为永远有效,这有关系吗?

\n

Erw*_*ter 7

对于你的实际问题:

如果约束没有标记为永远有效,这有关系吗?

不用于运行数据库。唯一的效果是 Postgres 将pg_constraint.convalidated约束标志设置为false。然后它像对待任何其他约束一样对待 FK 约束,验证任何新写入的数据。只是,如果你稍后运行VALIDATE CONSTRAINT- 那就是:

ALTER TABLE tbl VALIDATE CONSTRAINT tbl_col_fkey;
Run Code Online (Sandbox Code Playgroud)

...引用完整性只有在之前被标记过的情况下才会被实际验证NOT VALID。然后它被标记为有效。

快速检查源代码也没有发现任何影响,正如预期的那样。

如果您绝对确信引用完整性完好无损,理论上您可以利用它并以超级用户身份在系统目录中手动设置该标志:

UPDATE pg_constraint
SET    convalidated = true
WHERE  conrelid = 'public.tbl'::regclass
AND    conname = 'tbl_col_fkey';
Run Code Online (Sandbox Code Playgroud)

但如果你用枪指着我的头我就不会那么做。

首先,您一开始就不应该弄乱系统目录。坚持使用记录良好的 DDL 命令来操作系统目录,否则可能会破坏数据库(集群)。

其次,你永远不应该做出这样的假设,而应该投入工作来确定

第三,虽然我的答案对于当前版本的 Postgres 可能是正确的,但对于下一个版本可能会改变。我们这里处于无证领土。

最后,如果您确实无法正确验证约束,请继续使用该NOT VALID版本。一切都很好。

相关博客文章:

  • @Joe:你听错了。我刚刚测试过,“ON DELETE CASCADE”适用于“NOT VALID”约束。请参阅:*db<>fiddle [此处](https://dbfiddle.uk/?rdbms=postgres_13&fiddle=87a3cf5af62823c1c5edbcbc1ee07719)* (2认同)
  • @KillianHuyghe:我不知道 Postgres 查询规划器/优化器会根据“VALID”或“NOT VALID”FK 约束应用任何优化。引用的答案似乎只是基于理论上的可能性进行假设。 (2认同)