我有一个带有嵌入式注释的List文档。连同用户在视图中的评论,我想显示他们的屏幕名称和个人资料图片。配置文件图片可能会更改,屏幕名称也可能会更改。
我正在尝试确定设计的最佳实践。为了最好地利用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
但风险在于,如果用户更改了注释数据(用户的屏幕名称和配置文件图片),则除非在用户模型上有一个after_save过滤器,以便更新注释中的所有实例。
有关正确设计的指导吗?我可以这样做,以便不嵌入评论并使其成为一个用户有很多评论和一个列表有很多评论,但我正在努力发挥Mongo的优势。
答案 0 :(得分:2)
您的应用程序,它的访问模式,扩展和性能要求胜过后端问题。使用SQL,规范化和链接/引用几乎是您唯一的选择,但使用MongoDB,您可以嵌入。
MongoDB提供了将模式与应用程序需求相匹配的灵活性,您可以根据需要选择规范化/链接/引用或非规范化/嵌入,而Mongoid使其易于选择。
(a)归一化减少了冗余,遵循不要重复自己(DRY)的良好原则。 (b)非规范化引入冗余,遵循常见的做法,例如缓存或记忆性能。
一般情况下,根据您的应用需求:
需要高一致性 - 是:normalize / link,no:denormalize / embed
需要高读取性能 - 是:denormalize / embed,no:normalize / link
需要高写入性能 - 是:normalize / link,no:denormalize / embed
需要高缩放 - 是:normalize / link,no:denormalize / embed
关系:
一对一 - 是:denormalize / embed,no:...
一对多 - 是:denormalize / embed,no:...
多对多 - 是:normalize / link,no:...
有各种处理一致性的技术,例如,背景或夜间进程以实现最终一致性,后备缓存可立即保持一致性等。
坏消息是没有不需要思考的公式。好消息是MongoDB可以灵活地匹配您的应用程序。 10gen提供有关Schema Design的演讲。
答案 1 :(得分: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字段。