SQL FK 和预检查是不是存在
Posted
技术标签:
【中文标题】SQL FK 和预检查是不是存在【英文标题】:SQL FK and Pre-Checking for ExistenceSQL FK 和预检查是否存在 【发布时间】:2011-08-15 17:53:15 【问题描述】:我想知道大家对于在 INSERTS 和 UPDATES 之前预先检查外键查找与让数据库处理它的看法是什么。如您所知,如果相应的行不存在,服务器将抛出异常。
在 .NET 中,我们总是尽量避免使用异常编码,即不使用引发的异常来驱动代码流。这意味着我们会尝试在运行时检测到潜在错误。
使用 SQL 我看到两个相反的点
1) 不管你是否检查数据库总是会的。这意味着您可能会浪费(多少是主观的)CPU 周期来执行相同的检查两次。这使得人们倾向于让数据库只做这件事。
2) 预检查允许开发人员向调用应用程序提出更多信息异常。可以为每项需要完成的检查返回不同的错误代码,而不是接收通用的“外键违规”。
你有什么想法?
【问题讨论】:
在数据库世界中,您很少关心 CPU。这完全是关于内存和磁盘 IO,所以仔细检查 FK 是否存在可能会导致双重磁盘读取(取决于服务器负载以及在插入发生之前页面是否被换出) 【参考方案1】:之前不要测试:
DB 引擎无论如何都会检查 INSERT(您有 2 次索引读取,而不是 1 次) 如果没有锁定提示或信号量,它将无法扩展,这会降低并发性和性能(第二次重叠并发调用可以在第一次调用执行 INSERT 之前传递 EXISTS)您可以做的是将 INSERT 包装在 自己的 TRY/CATCH 中并忽略错误 xxxx(外键违规,抱歉不知道)。我之前提到过(对于唯一键,错误 2627)
Only inserting a row if it's not already there Select / Insert version of an Upsert: is there a design pattern for high concurrency? SQL Server 2008: INSERT if not exits, maintain unique column这可以很好地扩展到大容量。
【讨论】:
其他发布的答案与此类似,但 gbn 提供了额外的链接。【参考方案2】:数据完整性维护是数据库的工作,所以我会说你让数据库来处理它。在这种情况下引发的异常是一个有效的情况,即使它可以避免,它也是一个正确引发的异常,因为这意味着代码中的某些东西不能正常工作,它正在发送一个孤立的记录以供插入(或其他东西第一次插入失败 - 无论您插入它的方式)。此外,无论如何你都应该有 try/catch,这样你就可以实现一种有意义的方式来处理这个......
【讨论】:
【参考方案3】:我没有看到预先检查 FK 违规的好处。
如果您想要更多信息的错误语句,您可以简单地将您的插入内容包装在一个 try-catch 块中,并在此时返回自定义错误消息。这样,您只需在失败时而不是每次都运行额外的查询。
【讨论】:
以上是关于SQL FK 和预检查是不是存在的主要内容,如果未能解决你的问题,请参考以下文章