1

我有一个带有嵌入式评论的列表文档。除了用户在视图中的评论,我还想显示他们的屏幕名称和个人资料图片。个人资料图片可以更改,屏幕名称也可以更改。

我试图确定这里的最佳设计实践是什么。为了最好地利用 Mongo,嵌入的评论看起来应该如下所示:

评论模型

class Comment
  include Mongoid::Document
  field :user_id
  field :username
  field :profile_pic_url
  field :content
  field :created_at, type: Date
  embedded_in :list, :inverse_of => :comments
end

但风险在于,如果用户更改评论数据(用户的屏幕名称和个人资料图片),它们就会变得陈旧,除非在 User 模型上有一个 after_save 过滤器,例如,它希望更新评论中的所有实例。

有关正确设计的任何指导?我可以做到不嵌入评论,让用户有很多评论,列表有很多评论,但我正在努力发挥 Mongo 的优势。

4

2 回答 2

2

您的应用程序、它的访问模式、扩展和性能要求胜过后端问题。使用 SQL,规范化和链接/引用几乎是您唯一的选择,但使用 MongoDB,您可以嵌入。

MongoDB 提供了将模式匹配到应用程序需求的灵活性,您可以根据需要选择规范化/链接/引用或反规范化/嵌入,而 Mongoid 使其易于选择。

(a) 归一化减少冗余,遵循不要重复自己 (DRY) 的良好原则。(b) 非规范化引入了冗余,遵循缓存或记忆等常见做法以提高性能。

一般来说,根据您的应用程序的需要:

需要高一致性 - 是:规范化/链接,否:非规范化/嵌入

需要高读取性能 - 是:非规范化/嵌入,否:规范化/链接

需要高写入性能 - 是:规范化/链接,否:非规范化/嵌入

需要高缩放 - 是:规范化/链接,否:非规范化/嵌入

关系:

一对一 - 是:非规范化/嵌入,否:...

一对多 - 是:非规范化/嵌入,否:...

多对多 - 是:规范化/链接,否:...

有多种处理一致性的技术,例如,后台或夜间进程以实现最终一致性,后备缓存以实现即时一致性等。

坏消息是没有不需要思考的公式。好消息是 MongoDB 可以灵活地匹配您的应用程序。10gen 提供有关模式设计的讲座。

于 2013-01-11T18:07:04.743 回答
1

我会引用一个用户,而不是把每个字段放在每个评论中。

class User
  include Mongoid::Document
  include Mongoid::Timestamps
  field :user_id
  field :username
  field :profile_pic_url
  has_many :comments
end

class Comment
  include Mongoid::Document
  include Mongoid::Timestamps
  field :content
  belongs_to :user
  embedded_in :list, :inverse_of => :comments
end

您可以在http://mongoid.org/en/mongoid/docs/relations.html#has_many找到有关 has_many 关系的文档

我还继续使用了额外的时间戳,并删除了记录在http://mongoid.org/en/mongoid/docs/extras.html#timestamps中的 created_at 字段。

于 2013-01-09T22:22:22.720 回答