需要有关Chat App的MongoDB Schema的建议。嵌入式vs相关文档

时间:2010-09-06 15:34:02

标签: ruby-on-rails ruby mongodb mongoid nosql

我正在开始一个MongoDB项目,只是为了解决问题,并且有机会学习MongoDB / NoSQL模式。它将是一个实时聊天应用程序,堆栈包括:Rails 3,Ruby 1.9.2,Devise,Mongoid / MongoDB,CarrierWave,Redis,JQuery。

我将分别处理实时聊天轮询/消息排队。不确定Node.js,APE或自定义EventMachine应用程序。但是对于Mongo,我正在考虑将它用于应用程序中的其他所有内容,特别是聊天记录和历史记录。

我的问题是如何最好地设计架构,因为我以前的经验都是关于MySQL和关系数据库架构的。作为一个子问题,我们何时最好将嵌入式文档与相关文档进行对比。

该应用将具有:

  • 有多个会议室的多个帐户
  • 多个房间
  • 每间客房多个用户
  • 允许用户进入的房间列表
  • 每个房间有多个用户聊天
  • 基于每个房间和每个用户的可搜索聊天记录
  • 给定聊天的可选文件附件

鉴于Mongo(至少我上次检查过)的文件限制为4MB,我认为没有房间收藏和存储所有房间聊天,因为嵌入式文件会很好用。

从我到目前为止的想法来看,我正在考虑做类似的事情:

  • 帐户集合
  • 房间的集合
    • 每个房间都与帐户有关
    • 聊天室中所有聊天消息的聊天记录集中的相关文档
    • 列出当前房间内所有用户的嵌入式文档
  • 用户的集合
    • 嵌入文档,列出用户当前所在的所有房间
    • 嵌入文档,列出允许用户进入的所有房间
  • 聊天的集合
    • 每次聊天都与房间收藏中的房间有关。
    • 每个聊天都与用户集合中的用户相关联
    • 包含可选上传文件附件信息的嵌入式文档。

我主要担心的是,在这最终看起来像一个关系模式并且我打败了目的之前,我还能走多远?肯定有比嵌入更多的相关内容。

另一个问题是,引用相关文档要比访问我听过的嵌入式文档慢得多。

我想制作通用查询,例如:

  • 给我所有房间的帐户
  • 给我所有聊天室(或通过日期范围过滤)
  • 告诉我来自特定用户的所有聊天
  • 在给定的房间或给定的组织中提供所有上传的文件

有关如何以可扩展的方式有效地构建架构的任何建议?谢谢大家。

2 个答案:

答案 0 :(得分:5)

我认为你几乎走在正确的轨道上。我将capped collection用于聊天行,每行包含用户ID,房间ID,时间戳以及所说的内容。一旦达到上限集合的“结束”,这些数据就会过期,因此如果您需要历史日志,您需要定期将数据从上限集合中复制到“日志”集合中,但是上限集合专门用于记录 - 样式应用程序,您不会删除文档,并且插入顺序很重要。在聊天的情况下,这是一个完美的匹配。

我建议的唯一其他变化是在单独的集合中维护上传。

答案 1 :(得分:2)

我是mongodb作为文档数据库的忠实粉丝。但你确定你正在使用mongodb吗?什么是mongodb强大的?

这是一个主观问题,但对我而言,对文档进行原位(原子)更新是使mongodb强大的原因。而且我真的看不到你那么用它。除此之外,你还遇到了文档大小限制问题。(根据经验,我可以告诉你,将文件嵌入到mongodb并不是一个好主意)。您希望在数据库之上也有一个实时聊天应用程序。

您的文档架构似乎合乎逻辑。但是我不会选择mongodb这样的项目,你的应用程序很大程度上依赖于插入。我会选择CouchDB。

使用CouchDB,您不必担心附件问题,您可以轻松嵌入它们。 “_changes”会让你的生活变得更加轻松,建立一个实时聊天应用程序/长池/喂食搜索引擎(如果你想实现一个)。

我在沙发上看到了open source showcase project。它与您的目标有一些相似之处:Anologue。你应该看看它。

PS:对不起,这有点偏离主题,但我无法忍受。