如何避免在 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)中插入两次相同的记录?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Mongoid 查看原始 mongoDB 查询

如何使用 MongoDB 和 Mongoid 在 Rails 3 上进行适当的数据库测试 (TDD)

如何实现has_many:通过与Mongoid和mongodb的关系?

如何在 Mongoid / MongoDB 中为 $within 查询选择单位

如何在 mongoid dsl 中编写 mongodb $near 查询?

批量查找 mongoDB 记录(使用 mongoid ruby​​ 适配器)