admin

UNIQUE约束与INSERT之前的检查

sql

我有一个带有列-ID,Property,Property_Value的SQLServer表RealEstate。该表大约有5到1千万行,并且将来还会增加。我只想在此表中不存在Id,Property,Property_Value的组合时插入行。

示例表-

1,Rooms,5
1,Bath,2
1,Address,New York
2,Rooms,2
2,Bath,1
2,Address,Miami

2,Address,Miami不允许插入。但是,2,Price,2billion还可以。我很好奇,知道这样做的“最佳”方法和 原因
。为什么这部分对我来说最重要。两种检查方法是-

  1. 在应用程序级别-应用程序应在插入行之前检查是否存在行。
  2. 在数据库级别-在所有3列上设置唯一约束,然后让数据库而不是人员/应用程序进行检查。

有没有一种方案会比另一方案更好的方案?

谢谢。


阅读 195

收藏
2021-05-10

共1个答案

admin

我认为在大多数情况下,两者之间的差异会很小,因此选择主要应通过选择最终对于第一次看代码的人来说最容易理解的实现来驱动。

但是,我认为异常处理有一些 优点:

  • 异常处理避免了潜在的竞争状况。如果另一个过程在您的支票和插入内容之间插入了一条记录,则“检查然后插入”方法可能会失败。因此,即使您正在执行“先检查后插入”操作,您仍然希望对插入进行异常处理,并且如果您已经在进行异常处理,那么您也可以取消初始检查。

  • 如果您的代码不是存储过程,并且必须通过网络与数据库进行交互(即应用程序和数据库不在同一个盒子上),那么您要避免进行两个单独的网络调用(一个用于检查,另一个用于数据库调用)。其他)(通过插入操作),并通过异常处理来实现,这提供了一种通过单个网络调用处理整个事件的简单方法。现在,有很多方法可以执行“检查然后插入”方法,同时又避免了第二次网络调用,但是仅捕获异常可能是解决该问题的最简单方法。

另一方面,异常处理需要一个唯一的约束(实际上是一个唯一的索引),这需要进行性能折衷:

  • 在非常大的表上创建唯一约束会很慢,并且会对该表的每个插入都造成性能下降。在真正的大型数据库上,您还必须预算用于执行约束的唯一索引所消耗的额外磁盘空间。
  • 另一方面,如果您的查询可以利用该索引,则可能会使从表中选择的速度更快。

我还要注意,如果您实际要执行的操作是“更新其他插入”(即,如果具有唯一值的记录已经存在,则您想更新该记录,否则插入一个新的记录)记录),那么您实际要使用的是特定数据库的UPSERT方法(如果有)。对于SQLServer和Oracle,这将是MERGE语句。

2021-05-10