2011-03-18 55 views
8

我想使用MongoDB,C#和NoRM来处理一些示例项目,但是现在我有更多的时间围绕数据模型进行包装。使用RDBMS的相关数据是没有问题的。然而,在MongoDB中,我很难决定如何处理它们。MongoDB,C#和NoRM +非规范化

让我们以StackOverflow为例......我没有理解,一个问题页面上的大多数数据应该包含在一个文档中。标题,问题文本,修订,评论...在一个文档对象中都很好。

哪里开始变得朦胧是用户数据喜欢的用户名,头像,信誉(更改尤其常见)的问题...你非规范化和更新数以千计的文件记录每次有用户改变时间或者你以某种方式将数据链接在一起?

什么是最有效的方式来完成用户关系,而不会导致每次页面加载时发生大量的查询?我注意到NoRM中的DbReference<T>类型,但尚未找到使用它的好方法。如果我有可空的可选关系怎么办?

感谢您的洞察!

+0

+1,我想知道同样的事情。 – jgauffin 2011-03-18 14:56:33

回答

1

我认为你需要取得平衡。

如果我是你,我只是在每篇文章中引用userid而不是他们的名字/声望。

虽然与RDBMS不同,但您可以选择在文档中嵌入注释。

+0

我同意。我喜欢使用DBRef,因为用户数据易于频繁更新。另一方面的评论在文档中是完全可以接受的。 – jocull 2011-04-05 15:13:37

1

为什么你想避免非规范化和更新'成千上万的文档记录'?为非规范化而设计的Mongodb db。 Stackoverlow在后台处理数百万个不同的数据。有些数据可能会在短时间内陈旧,并且没关系。

所以上述的主要思想是,你应该有非规范化的文件,以便快速显示他们在UI。

无法以任何方式查询引用文档,您需要非规范化。

另外我建议看看cqrs架构。

+0

这不是我想避免非规范化,但我想避免固有的不良设计。从用户记录中分离一些常见的东西,我可以每秒更新数千条用户记录,这一点似乎是1.像过度使用一样2.像磁盘空间使用不当一样。没有其他选择吗? – jocull 2011-03-18 15:56:37

+0

这取决于你想要的东西:如果你关心'磁盘空间'和反规范化,就像你对我的回答可能不是你的,但是如果你关心性能,你想达到你的速度 - 比你应该去上面描述的办法。 – 2011-03-18 16:03:04

+2

更何况,磁盘空间*便宜* – 2011-03-18 18:26:28

2

我发现的余额是使用SQL作为规范化数据库,Mongo作为非规范化副本。我使用ESB来保持它们彼此同步。我使用了一个概念,我称之为“准备好的文档”和“存储的文档”。存储的文档是仅保存在mongo中的数据。对于非关系数据很有用。准备好的文档包含可以使用规范化数据库中的数据重建的数据。它们以某种方式充当活动高速缓存 - 如果数据不同步(在复杂的文档中这是一个昂贵的过程,因为这些文档需要重建许多查询),可以从头开始重建。他们也可以一次更新一个字段。这是服务总线进入的地方。它响应在规范化数据库更新后发送的事件,然后更新相关的mongo准备文档。

使用每个数据库,以他们的长处。允许SQL成为确保数据完整性的写入数据库。让Mongo成为快速发展的只读数据库,它可以包含子文档,因此您需要更少的查询。

**编辑** 我只是重新读你的问题,并意识到你实际上要求什么。如果有帮助,我会离开我的原始答案。

我将处理您给出的Stackoverflow示例的方式是在每个注释中存储用户标识。你会加载其中会有所有注释的帖子。那是一个查询。

然后,您将遍历注释数据并提取需要加载的用户标识数组。然后将这些加载为批量查询(使用Q.In()查询运算符)。这两个查询总数。然后,您需要将数据合并到一个最终表单中。您需要在这种情况下执行此操作,以及何时使用类似于ESB的操作来手动更新每个文档。使用最适合数据结构的每个单独场景的方法。

+0

我喜欢这个解决方案。加载一批用户ID然后组装数据是个好主意。 – jocull 2011-09-17 04:48:10