【问题标题】:Moving messaging schema to MongoDB将消息传递模式移动到 MongoDB
【发布时间】:2011-05-03 08:50:23
【问题描述】:

我有这个架构来支持站内消息传递:

当我向其他成员发送消息时,消息会保存到消息表中;一条记录被添加到 MessageSent 表中,并且每个收件人的一条记录被添加到 MessageInbox 表中。 MessageCount 用于跟踪收件箱/发送文件夹中的消息数量,并使用 MessageInbox/MessageSent 上的插入/删除触发器填充 - 这样我总是可以知道成员有多少消息,而无需进行昂贵的“选择计数( *)" 查询。

另外,当我查询成员的消息时,我加入到成员表以获取成员的名字/姓氏。

现在,我将把应用程序迁移到 MongoDB,但我不太确定集合模式应该是什么。因为 MongoDB 中没有可用的连接,所以我必须对其进行完全非规范化,所以我将拥有带有完整消息信息的 MessageInbox、MessageDraft 和 MessageSent 集合,对吗?

然后我不确定以下内容:

  1. 如果用户更改了他的名字/姓氏怎么办?它将被非规范化存储为某些消息中的发送者,作为其他消息中的接收者的一部分 - 我如何以最佳方式更新它?

  2. 如何获取消息计数?同时会有大量的请求,所以它必须表现良好。

非常感谢任何想法、cmets 和建议!

【问题讨论】:

    标签: mongodb schema messaging


    【解决方案1】:

    我可以为您提供一些关于我在 MongoDB 中模拟 JOIN 所做的工作。

    在这种情况下,我将相应用户(或多个用户)的 ID 存储在给定对象中,例如消息集合中的消息对象。

    (我不建议这是您的架构,只是将其用作我的方法的示例)

    {
        _id: "msg1234",
        from: "user1234",
        to: "user5678",
        subject: "This is the subject",
        body: "This is the body"
    } 
    

    我会查询数据库以获取我需要的所有消息,然后在我的应用程序中迭代结果并构建一个用户 ID 数组。我会将此数组过滤为唯一的,然后使用$in 运算符再次查询数据库以查找给定数组中的任何用户。

    然后在我的应用程序中,我会将结果连接回对象。

    它需要对数据库进行两次查询(如果您想加入其他集合,可能需要更多次查询),但这说明了许多人长期以来一直在倡导的事情:在您的应用程序层中执行您的 JOIN。让数据库花时间查询数据,而不是处理数据。无论如何,您可能可以比数据库更快、更便宜地扩展您的应用程序服务器。

    我正在使用这种模式在我的应用程序中创建实时活动源,它可以完美且快速地运行。我更喜欢这种非规范化可能会改变的东西,比如用户信息,因为在写入数据库时​​,如果新数据不适合旧数据的位置,MongoDB 可能需要重新写入整个对象。如果我需要在我的数据库中重写数百(或数千)个活动项目,那将是一场灾难。

    此外,MongoDB 上的写入是阻塞的,所以如果发生我刚才描述的情况,所有的读取和写入都将被阻塞,直到写入操作完成。我相信这个问题计划在 2.x 系列中以某种方式解决,但它仍然不会完美。

    另一方面,索引查询非常快,即使您需要执行其中两个来获取数据。

    【讨论】:

    • 这是个好主意。关于以表演方式收集消息的任何想法?
    • 最好的方法可能是将预先计算的计数存储在某处。 MongoDB 2.x 计划有额外的聚合运算符,例如 $sum,但还没有。对于这样的事情,您可能只想将它存储在某个地方,并在发送消息时使用 $inc 运算符来增加它。
    猜你喜欢
    • 1970-01-01
    • 2014-11-18
    • 2018-11-28
    • 1970-01-01
    • 1970-01-01
    • 2014-01-25
    • 2013-04-05
    • 2012-08-29
    • 1970-01-01
    相关资源
    最近更新 更多