【问题标题】:Enforce unique constraint only on some queries仅对某些查询强制执行唯一约束
【发布时间】:2018-06-20 02:07:27
【问题描述】:

假设我有一个 accounts 表,并且在该表中我有一个 profile_id 列。我希望能够在具有相同profile_id 的列中拥有多行,但我也想能够说“如果没有其他行具有此profile_id 值,则插入”。通常,我会为此使用唯一约束,但是当我期望 profile_id 存在时,我无法覆盖它。

如果值已经存在,有没有办法(没有竞争条件)出现插入错误或失败,或者让插入忽略约束并输入与约束不匹配的值?

【问题讨论】:

  • 请提供示例数据以阐明您想要做什么。
  • 假设架构有一个num 列。我希望能够将 1 插入该 num 列,然后尝试再次插入 1,但它失败了。就像一个独特的约束。但是我,在查询级别,希望能够说“我希望 1 已经存在,并且无论如何都想插入另一个 1”,基本上覆盖了唯一约束。我不知道什么样的样本数据能说明这一点。
  • 您不能插入到列中。您可以将 row 插入到 table 中。听起来您有两个数据用例:(1)插入具有重复值的新行应该失败,(2)插入具有重复值的新行应该成功。我做对了吗?您希望系统如何区分这两种情况?你会传递旗帜或其他东西吗?
  • 没错,有时我希望插入的行成功,有时我希望它失败,这取决于我正在运行的查询。我希望有一种方法可以修改插入语句以使其成功或失败,否则它不会。

标签: sql postgresql


【解决方案1】:

你可以建立一个部分索引;这至少是您问题的部分解决方案。也就是说,定义一个类似这样的列:

only_uniques_allowed

然后建立索引:

create unique index unq_t_profile_id_uniques on (profile_id) where only_uniques_allowed;

然后,任何将only_uniques_allowed 设置为true 的行都会有一个唯一的profile_id在具有此设置的行中

但是,您并不真的想强制执行约束,因此您想要做的最好在应用程序级别完成。或者它可能表明您需要不同的数据模型。

【讨论】:

  • 我曾想过only_uniques_allowed 解决方案,但这不会将我限制为具有相同值的两行吗?一个是only_uniques_allowed = True,另一个是only_uniques_allowed = False?很抱歉这个愚蠢的问题,但是是什么使该索引成为部分索引?对我来说,这似乎是一个普通的multi-column index
  • @Paddy。 . . where 子句使其成为部分索引;)现在我已经编辑了答案以表达我的意图。
  • 啊,和this method很像,那么? (一旦你告诉我我正在寻找的短语是“部分索引”,我就发现了。)这听起来像是一个合理的答案,我会试一试,如果事实证明它像我一样工作,我会回来接受这个答案希望。出于好奇,是什么让它只是“部分解决方案”?
  • @Paddy。 . .因为您仍然可以有重复项,正如您所提到的,一个带有“true”标志的行和一个带有“false”标志的行。
  • 你是说我最多只能有两个在表中具有相同的 profile_id 吗?抱歉,我不清楚这一点。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-03-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-06
相关资源
最近更新 更多