SQL FK和是否存在的预检查

SQL FK和是否存在的预检查,sql,foreign-keys,Sql,Foreign Keys,我想知道每个人对在插入和更新之前预先检查外键查找与让数据库处理外键查找的看法。如您所知,如果相应的行不存在,服务器将抛出异常 在.NET中,我们总是尽量避免使用异常编码,即不使用引发的异常来驱动代码流。这意味着我们试图在运行时之前检测潜在的错误 对于SQL,我看到了两个相反的观点 1) 无论您是否检查数据库,都将始终检查。这意味着你可能会浪费(多少是主观的)CPU周期做同样的检查两次。这使得人们倾向于让数据库只做这件事 2) 预检查允许开发人员向调用应用程序返回更多信息性异常。对于需要执行的每个

我想知道每个人对在插入和更新之前预先检查外键查找与让数据库处理外键查找的看法。如您所知,如果相应的行不存在,服务器将抛出异常

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

对于SQL,我看到了两个相反的观点

1) 无论您是否检查数据库,都将始终检查。这意味着你可能会浪费(多少是主观的)CPU周期做同样的检查两次。这使得人们倾向于让数据库只做这件事

2) 预检查允许开发人员向调用应用程序返回更多信息性异常。对于需要执行的每个检查,可以返回不同的错误代码,而不是接收通用的“外键冲突”


你的想法是什么?

我不认为预先检查FK违规有什么好处


如果您想要更多的信息性错误语句,您可以简单地将insert包装在try-catch块中,并在此时返回自定义错误消息。这样,您只会在发生故障时运行额外的查询,而不是每次都运行。

数据完整性维护是数据库的工作,所以我认为您应该让数据库来处理它。在这种情况下引发的异常是有效的,即使可以避免,它也是正确引发的异常,因为它意味着代码中的某些内容工作不正常,它正在发送一条孤立记录以进行插入(或者在第一次插入时失败-无论插入方式如何)。此外,无论如何,您都应该有try/catch,这样您就可以实现一种有意义的方法来处理此问题……

在以下情况之前不要进行测试:

  • DB引擎将在INSERT时进行检查(您有两次读取索引,而不是一次)
  • 如果没有降低并发性和性能的锁提示或信号量,它将无法扩展(第二个重叠并发调用可以在第一个调用插入之前传递EXISTS)
您可以做的是将INSERT包装在它自己的TRY/CATCH中,并忽略错误xxxx(外键冲突,对不起,我不知道)。我以前提到过这一点(对于唯一键,错误2627)


这可以很好地扩展到高容量

在数据库世界中,您很少关心CPU。这一切都是关于内存和磁盘IO的,所以双重检查FK是否存在可能会导致双重磁盘读取(取决于服务器负载以及页面是否在插入之前被交换)。其他发布的答案与此类似,但gbn提供了其他链接。