如何避免插入重复记录?
Posted
技术标签:
【中文标题】如何避免插入重复记录?【英文标题】:How can you avoid inserting duplicate records? 【发布时间】:2010-08-19 23:00:00 【问题描述】:我有一个返回 XML 的 Web 服务调用,我将其转换为域对象,然后我想将这些域对象插入到我的核心数据存储中。
但是,我真的想确保不插入重复项(对象有一个日期戳,这使它们独一无二,我希望将其用于唯一性检查)。我真的不想遍历每个对象,进行提取,然后在没有找到任何内容时插入,因为这对性能来说真的很差......
我想知道是否有更简单的方法?也许对我记忆中的对象进行“分组”????这可能吗?
【问题讨论】:
【参考方案1】:您的问题已经有了答案。你需要遍历它们,寻找它们,如果它们存在更新;否则插入。没有其他办法。
由于您是唯一的一个值,您可以通过设置谓词一次获取所有相关对象:
[myFetchRequest setPredicate:[NSPredicate predicateWithFormat:@"timestamp in %@", myArrayOfIncomingTimestamps]];
这将为您提供所有已处于故障状态的对象。然后,您可以针对该数组运行内存中的谓词以检索现有对象以更新它们。
还有一点建议。时间戳是一个非常独特的 ID。我会强烈建议您重新考虑。
【讨论】:
是的,但我的问题是循环遍历它们并检查每个都不够快,哦,好吧,看起来这可能是唯一的方法......顺便说一句,我不是使用时间戳作为键,它更像是一条业务规则,规定同一时间戳上的任何记录都被视为重复 考虑到 XML 解析的速度有多慢,如果获取和唯一性超过解析总时间的 5%,我会感到惊讶。我建议分析代码并查看您的热点在哪里。获取和测试唯一性是唯一可以完成的方法,尽管正如我提到的,它们可以被预取以提高性能。 谢谢马库斯,事实证明(到目前为止)你是对的,所花费的时间很短,所以这就是坏事......谢谢【参考方案2】:时间戳不是唯一的。但是,我们会假设您有唯一的 ID(例如 UUID/GUID/其他)。
在普通的 SQL 领域中,您可以在 GUID 上添加索引并进行搜索,或者添加唯一性约束,然后尝试插入(如果插入失败,则进行更新),或者进行更新(并且如果更新失败,做一个插入,如果插入失败,做另一个更新......)。请注意,许多数据库中的默认事务在这里不起作用——它们锁定行,但您不能锁定尚不存在的行。
【讨论】:
我知道时间戳不是唯一的,我没有声称它们是唯一的,我说我的业务规则规定对象/记录同时被认为是相等的【参考方案3】:你怎么知道一条记录是重复的?您有主键或其他唯一键吗? (你应该。)检查那个键——如果它已经存在于商店的实体中,那么更新它,否则,插入它。
【讨论】:
问题确实表明存在一个被视为“唯一记录”的时间戳,尽管不一定作为“主键”实现以上是关于如何避免插入重复记录?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Laravel 中在一秒钟内发出并发请求时避免重复记录
如何在SQL Server中使用用户定义的表类型插入数据时避免重复记录