当前位置: 首页 > 面试题库 >

SQL约束,用于检查另一个表中是否不存在值

金谭三
2023-03-14
问题内容

在我的PostgreSQL 9.4 数据库中,我有一个表fields,该表的列name具有唯一值。

我正在创建fields_new具有相似结构(此处不重要)和一列的新表name。我需要一种方法来限制name要插入的值,使其fields_new不存在于中fields.name

例如,如果fields.name包含值 ‘color’‘length’ ,则需要防止fields_new.name包含
‘color’‘length’ 值。因此,换句话说,我需要提供name两个表中的列之间没有任何重复的值。约束应该是双向的。


问题答案:

仅对新条目强制实施约束 fields_new

CHECK约束应该是 不可变的 ,通常会排除对其他表的任何形式的引用,而这些表本质上是不可变的。

为了允许一些回旋余地(尤其是具有时间功能),STABLE可以容忍一些功能。显然,在具有并发写入访问权限的数据库中,这是不完全可靠的。如果引用表中的行发生更改,则它们可能违反了约束。

声明 约束的无效性质 NOT VALID (Postgres
9.1+)。这样,Postgres也不会尝试在还原过程中强制执行它(这可能注定会失败)。详细信息在这里:

  • 恢复转储时禁用所有约束和表检查

该约束仅适用于新行。

CREATE OR REPLACE FUNCTION f_fields_name_free(_name text)
  RETURNS bool AS
$func$
SELECT NOT EXISTS (SELECT 1 FROM fields WHERE name = $1);
$func$  LANGUAGE sql STABLE;

ALTER TABLE fields_new ADD CONSTRAINT fields_new_name_not_in_fields
CHECK (f_fields_name_free(name)) NOT VALID;

另外,当然,一个UNIQUEPRIMARY KEY约束上fields_new(name),以及对fields(name)

双向执行

您可以更进一步,将上述CHECK约束反映在第二张桌子上。当两个事务同时写入两个表时,仍然不能保证避免恶劣的竞争条件。

或者,
您可以使用触发器手动维护“物化视图”:两name列的并集。在UNIQUE此处添加约束。不像对单个表的相同约束那样坚如磐石:可能存在同时写入两个表的竞争条件。但是可能发生的最坏情况是僵局,迫使事务被回滚。如果所有写操作都级联到“实例化视图”,则不会出现永久违规。

只是,你需要触发器INSERT/ UPDATE/DELETE这两个表。



 类似资料:
  • 目前,我在postgres中有一些重复的表A和表B,我只想选择表A中存在但表B中不存在的行,这是左连接的一种形式吗? 实现这一目标的最佳方式是什么?

  • 问题内容: 我的表设置如下: 我想构造一个select语句,该语句将显示在value_search中没有条目的所有进程名称(带有其各自的id_string)。 进程表中的id_string可以为 null ,并且仍然具有名称,但是如果可能的话,必须将其排除。value_search中的id_string永远不能为 null 我该怎么做呢? 问题答案: 通常,如果您想要其他表中不存在的行,则将LEF

  • 我需要检查一个arraylist中的任何值是否存在于另一个arraylist中: 它打印“它不包含”。我需要知道是否有方法比较这两个arraylist,如果其他arraylist中存在任何值,它应该返回。我知道迭代可以有所帮助。有什么简单的方法可以做到这一点吗?

  • 问题内容: 我有两个arraylist 我想检查a2中是否存在a1的所有元素。这是我正在尝试的问题 这没有给出一致的结果…还有其他方法可以做到吗? 问题答案: 不知道我是否正确理解了您的问题,为什么使用? 试过这个: 它输出 添加一个额外的元素将使它失败(如预期): 它输出

  • 问题内容: 我有下表Goods_In_Wagon(Goods_ID,Wagon_ID,Total_Weight)。我需要创建一些if语句检查约束,说 “如果WAGON_ID在90到99之间,则Total_Weight必须大于10。” AND“如果WAGON_ID在100到110之间,则Total_Weight必须大于20。” AND“如果WAGON_ID在111到120之间,则Total_Weig

  • 如果表已经存在,如何检查TarantoolSQL?