【问题标题】:SQL FK and Pre-Checking for ExistenceSQL FK 和预检查是否存在
【发布时间】:2011-08-15 17:53:15
【问题描述】:

我想知道大家对于在 INSERTS 和 UPDATES 之前预先检查外键查找与让数据库处理它的看法是什么。如您所知,如果相应的行不存在,服务器将抛出异常。

在 .NET 中,我们总是尽量避免使用异常编码,即不使用引发的异常来驱动代码流。这意味着我们会尝试在运行时检测到潜在错误。

使用 SQL 我看到两个相反的点

1) 不管你是否检查数据库总是会的。这意味着您可能会浪费(多少是主观的)CPU 周期来执行相同的检查两次。这使得人们倾向于让数据库只做这件事。

2) 预检查允许开发人员向调用应用程序提出更多信息异常。可以为每项需要完成的检查返回不同的错误代码,而不是接收通用的“外键违规”。

你有什么想法?

【问题讨论】:

  • 在数据库世界中,您很少关心 CPU。这完全是关于内存和磁盘 IO,所以仔细检查 FK 是否存在可能会导致双重磁盘读取(取决于服务器负载以及在插入发生之前页面是否被换出)

标签: sql foreign-keys


【解决方案1】:

之前不要测试:

  • DB 引擎无论如何都会检查 INSERT(您有 2 次索引读取,而不是 1 次)
  • 如果没有锁定提示或信号量,它将无法扩展,这会降低并发性和性能(第二次重叠并发调用可以在第一次调用执行 INSERT 之前传递 EXISTS)

您可以做的是将 INSERT 包装在 自己的 TRY/CATCH 中并忽略错误 xxxx(外键违规,抱歉不知道)。我之前提到过(对于唯一键,错误 2627)

这可以很好地扩展到大容量。

【讨论】:

  • 其他发布的答案与此类似,但 gbn 提供了额外的链接。
【解决方案2】:

数据完整性维护是数据库的工作,所以我会说你让数据库来处理它。在这种情况下引发的异常是一个有效的情况,即使它可以避免,它也是一个正确引发的异常,因为这意味着代码中的某些东西不能正常工作,它正在发送一个孤立的记录以供插入(或其他东西第一次插入失败 - 无论您插入它的方式)。此外,无论如何你都应该有 try/catch,这样你就可以实现一种有意义的方式来处理这个......

【讨论】:

    【解决方案3】:

    我没有看到预先检查 FK 违规的好处。

    如果您想要更多信息的错误语句,您可以简单地将您的插入内容包装在一个 try-catch 块中,并在此时返回自定义错误消息。这样,您只需在失败时而不是每次都运行额外的查询。

    【讨论】:

      猜你喜欢
      • 2010-10-02
      • 2012-03-10
      • 2011-07-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-16
      • 1970-01-01
      • 2010-09-15
      相关资源
      最近更新 更多