数据库Upserts - 好或坏的做法?

时间:2010-12-22 09:59:04

标签: mysql sql-server oracle database-design

寻找关于Upsert(插入或是否存在,然后更新)过程在数据库编程中是否被视为不良做法的一些见解。如果它具有任何相关性,我在SQL服务器中工作。

在几个月前我工作的地方,常驻数据库专家在新编写的数据库编码标准(我同意其中大部分)中都说过,应该避免使用Upserts。

我无法真正看到这个逻辑上的原因,并认为我自己合理地意识到良好的编程习惯。我认为它们对于直接数据管理很有用,并有助于避免过多的存储过程编号。

寻找一些有助于我就此得出结论的见解/讨论。

感谢。

更新回复评论:

我所指的具体上下文是在数据库中创建或更新域实体数据表示。比如说,“Person”对象作为数据库中“Person”表的表示存在。我只需要一种机制来创建一个新的Person,或者更新一个现有的Person。在这里,我可以选择创建Upsert存储过程,或者两个单独的存储过程 - 一个用于Update,一个用于Insert。

anyone视图中的任何优点或缺点?

4 个答案:

答案 0 :(得分:12)

主要问题是当意图添加新记录时覆盖现有记录,因为选择的任何密钥都是重复的。比如说一个登录名。您看到登录存在,因此您应该在应该回复登录重复的错误时进行更新。

第二个问题是恢复已删除的记录。假设进程“A”查询记录,进程“B”删除它,然后进程“A”提交更改。打算删除的记录现在返回到数据库中,而不是将异常传回“A”,表示已将其删除。

答案 1 :(得分:9)

我喜欢有目的地进行节目。

要么我正在创建一些东西,在这种情况下,如果那里已经存在实体,我希望插入失败(重复)。或者,我正在更新我知道的东西,在这种情况下,我希望更新失败(实际上不会发生)。

使用upsert / merge,这会变得模糊。我还是没有成功?我部分成功了吗?行中的一些值是我的(来自插入),其中一些是以前的?

话虽如此,Upserts很有用(这就是他们开始实施的原因)并禁止它们只是愚蠢。这就像禁止道路,因为犯罪分子利用它们远离警察。有无数种情况,其中up​​serts是唯一合理的做事方式。任何在系统之间同步数据的人都知道这一点。

答案 2 :(得分:1)

取决于你所谈论的内容。数据?那么,这是由数据处理过程决定的,还是?如果我需要插入或更新,那么我需要这样做。如果它是关于模式对象的,类似。

答案 3 :(得分:0)

两个进程的第一个示例中的异议 - 第二个进程通过添加具有相同密钥的新记录来“恢复”已删除的记录 - 仅在特定情况下有效,这些情况可能是由于设计不良或者是无论“upsert”程序是否使用相同的密钥写入记录,或者两个单独的程序写入插入的记录,都会发生。

如果必须避免使用相同的密钥,则在插入中使用自动递增的标识密钥。如果不需要避免使用相同的密钥,则必须实现良好的数据库设计以避免创建“幻像连接”。例如,在电信领域,电话号码经常被重复使用并且是“唯一”密钥。它们不能成为主键,因为#2号人员可能会“继承”电话号码,但可能不会“继承”#1的逾期未付帐单或通话记录等。因此,自动递增主键加服务日期或其他的组合任何连接逻辑都将使用唯一的标识符来防止错误的数据链接。