如何避免在 MongoDB(使用 Mongoid)或 ActiveRecord(使用 MySQL 的 Rails)中插入两次相同的记录?
Posted
技术标签:
【中文标题】如何避免在 MongoDB(使用 Mongoid)或 ActiveRecord(使用 MySQL 的 Rails)中插入两次相同的记录?【英文标题】:How to avoid the same record inserted twice in MongoDB (using Mongoid) or ActiveRecord (Rails using MySQL)? 【发布时间】:2010-09-15 02:34:18 【问题描述】:例如,如果我们正在做 Analytics 记录 page_type、item_id、date、pageviews、timeOnPage。
似乎有几种方法可以避免它。有自动的方法吗?
在唯一标识记录的字段上创建索引,例如[page_type, item_id, date]
,并使索引唯一,这样在添加相同记录时,它会拒绝它。
或者,如果数据库或框架支持,则将上面的主索引设为唯一的主索引。不过,在 Rails 中,通常 ID 1、2、3、4 是主索引。
或者,使用[page_type, item_id, date]
查询记录,然后如果它已经存在则更新该记录(或者如果pageviews 和timeOnPage 已经具有相同的值,则不执行任何操作)。如果记录不存在,则使用此数据插入一条新记录。但是如果需要这样查询记录,看起来我们无论如何都需要在这三个字段上建立索引。
一直插入新记录,但查询值时,使用类似
select * from analytics where ... order by created_at desc limit 1
即获取最新创建的记录并忽略其余记录。但这似乎是 1 条记录的解决方案,但在汇总值(进行聚合)时不太可行,例如 select sum(pageviews)
或 select count(*)
。
除了使用上述方法之外,还有一些自动解决方案吗?
【问题讨论】:
【参考方案1】:简,
您的第一个选项对我来说似乎可行。和最简单的方法。 Mongo 默认支持此功能。
插入时它将检查唯一组合,如果存在它将忽略插入并在服务器日志中写入“E11000 重复键错误索引”消息。否则它将继续正常插入。
但这似乎不适用于批量插入。如果有任何重复,则整个批次都将失败。快速谷歌搜索显示现有的 mongo 错误报告 jira ticket。它仍然开放。
【讨论】:
【参考方案2】:我不能代表 Mongoid/MongoDB,但如果您希望在关系数据库中强制执行唯一性约束,您应该创建一个 uniqueness constraint。这就是他们的目的!在 mysql 中,这相当于一个唯一索引;您可以将其指定为CONSTRAINT ... UNIQUE (col1, col2)
,但无论如何这只会创建一个唯一索引。
【讨论】:
以上是关于如何避免在 MongoDB(使用 Mongoid)或 ActiveRecord(使用 MySQL 的 Rails)中插入两次相同的记录?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 MongoDB 和 Mongoid 在 Rails 3 上进行适当的数据库测试 (TDD)
如何实现has_many:通过与Mongoid和mongodb的关系?
如何在 Mongoid / MongoDB 中为 $within 查询选择单位