【问题标题】:Why would you NOT set IGNORE_DUP_KEY to ON?为什么不将 IGNORE_DUP_KEY 设置为 ON?
【发布时间】:2009-02-10 18:57:26
【问题描述】:

IGNORE_DUP_KEY = ON 基本上告诉 SQL Server 插入不重复的行,但默默地忽略任何重复;默认行为是在不允许的列中有重复项时引发错误并中止整个事务。

我处理过大量数据,这些数据通常至少有一个重复,而实际上不应该重复,所以当我知道一个值不应该重复时,我喜欢使用UNIQUE 约束;但是,当我尝试批量加载数据时,我想要的最后一件事是让它完成 90%,然后突然遇到重复并出错整个事情(是的,我知道明显的解决方案是确保没有重复,但有时我只是收到一个填满数据的电子表格,并告诉我尽快加载它)。

那么,将默认设置为 OFF 的原因是什么,以及为什么您希望它一直处于打开状态,以便任何非重复条目成功而您不这样做不必担心任何重复;无论如何,重复的内容很可能是错误的。

它与性能有关,还是与其他有关?这似乎是个好主意,但它不是默认行为肯定是有原因的。

主要是,我是否有充分的理由使用它,我应该知道,还是应该根据具体情况进行评估?

【问题讨论】:

标签: sql-server tsql database-design


【解决方案1】:

每当数据库中的“正常”出现偏差时,您可能想知道它。

您保持密钥的唯一性是因为业务需求导致的一些限制。数据库只是保持交易的一面,说'嘿,你希望这是独一无二的,但现在你说的是相反的东西。下定决心'

如果这是故意的,您可以使用 IGNORE_DUP_KEY 要求数据库关闭 :)

【讨论】:

  • 一条评论,将忽略设置为 ON 并非没有后果。如果您有一个标识列,您将看到每个因重复而被忽略的插入的标识跳过。
  • 在非聚集索引上启用此选项会降低性能Maintaining Unique Indexes with IGNORE_DUP_KEY,并可能导致并发插入批次Range lock (RS-U) due to IGNORE_DUP_KEY index option 的严重范围锁定。因此,当您想一次插入多行并忽略重复项时,请仅将其应用于集群键。
  • @eremmel 你刚刚救了我的培根,谢谢你的评论!在过去的几天里,我一直在用头撞墙,试图弄清楚为什么我在没有可序列化隔离的情况下获得 Range 锁,当时我的大脑中出现了这个关于 ignore_dup_key 导致性能问题的小痒痒。快速搜索把我带到了这篇文章,你摇滚!我只希望这是一个完整的答案,所以它更明显:)
【解决方案2】:

我猜这可能是因为默认设置是为了防止任何无效事务静默失败。考虑到所有因素,我更愿意选择何时忽略意外后果,但除非我另有说明,否则请告诉我。

示例:如果我存入工资支票,我希望有人能注意到我的雇主是否不小心签发了重复的支票号码。

【讨论】:

  • 这也是真的。我想最好的原因是它会谨慎行事并引发错误,除非您另有说明。
【解决方案3】:

无论如何,重复的可能是错误的。

我敢打赌他们是!他们是虫子。你当然想知道他们!开启IGNORE_DUP_KEY默认是...

  1. 隐藏错误...
  2. ...通过破坏数据。 (当然,数据库在物理上保持一致,但从业务逻辑的角度来看,数据仍然是错误的。)

从任何标准来看,这都是一个糟糕的选择。

在特殊情况下打开它,然后尽快摆脱它,以免不小心隐藏错误。

【讨论】:

  • 但是文档和问题都表明您不能损坏数据,因为即使使用 IGNORE_DUP_KEY = ON 也不允许重复。
  • @FrancoisBourgeois 不确定您在说什么。当然,只有非唯一索引才有可能重复。它们是逻辑应用程序错误,而不是 SQL Server 中的错误。
  • 它没有破坏数据,因为它没有插入重复值,它只是跳过它而不引发警告。
  • @user3071296 数据库在物理上是一致的,但是插入的数据是错误的。从应用程序的角度来看,这是数据损坏。当应用程序破坏数据时,就是数据损坏。
  • 因此,如果您对忽略重复键的表执行“插入...选择...从...”,那么哪些数据会默默地错误和损坏?
【解决方案4】:

它可以用作健全性检查。如果您知道不应该有冲突,请将其关闭,它会因错误而快速失败。 OTOH 用于临时控制台会话,我明白你的意思。

【讨论】:

  • 是的 - 我想这涉及到决定“重复输入”的场景是否是一种例外情况,以及是否应该引发错误,或者只是忽略它。
【解决方案5】:

我有一个多对多的关系。我有一个具有唯一索引的产品到类别表,表中除了 prodid 和 katid 之外没有其他数据。

所以我在唯一 (prodid,katid) 索引上设置 IGNORE_DUP_KEY。

所以我可以放心地说“将产品 (1,2,3) 添加到类别 (a,b,c)”,而不必检查某些产品是否已经在某些类别中;我只关心最终结果。

【讨论】:

    猜你喜欢
    • 2011-02-05
    • 2014-08-01
    • 2010-10-16
    • 2017-10-31
    • 2014-10-30
    • 1970-01-01
    • 1970-01-01
    • 2015-08-29
    相关资源
    最近更新 更多