MongoDB、C# 和 NoRM + 非规范化

Posted

技术标签:

【中文标题】MongoDB、C# 和 NoRM + 非规范化【英文标题】:MongoDB, C# and NoRM + Denormalization 【发布时间】:2011-07-18 05:53:46 【问题描述】:

我正在尝试使用 MongoDB、C# 和 NoRM 来处理一些示例项目,但在这一点上,我很难将我的头脑集中在数据模型上。用RDBMS的相关数据是没有问题的。然而,在 MongoDB 中,我很难决定如何处理它们。

让我们以 *** 为例...我完全理解问题页面上的大部分数据都应该包含在一个文档中。标题、问题文本、修订、cmets……都在一个文档对象中。

我开始变得模糊的地方是关于用户数据的问题,比如用户名、头像、声誉(变化尤其频繁)……你是否每次都去规范化和更新成千上万的文档记录是用户更改还是您以某种方式将数据链接在一起?

在不导致每次页面加载时发生大量查询的情况下,实现用户关系的最有效方法是什么?我注意到 NoRM 中的 DbReference<T> 类型,但还没有找到使用它的好方法。如果我有可以为空的可选关系怎么办?

感谢您的洞察!

【问题讨论】:

+1,我也想知道同样的事情。 【参考方案1】:

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

充分利用每个数据库的优势。允许 SQL 成为确保数据完整性的写入数据库。让 Mongo 成为一个速度极快且可以包含子文档的只读数据库,这样您就需要更少的查询。

** 编辑 ** 我刚刚重新阅读了您的问题,并意识到您的实际要求。我留下我原来的答案,以防万一它有帮助。

我处理您给出的 *** 示例的方式是将用户 ID 存储在每个评论中。您将加载包含所有 cmets 的帖子。那是一个查询。

然后,您将遍历评论数据并提取需要加载的用户 ID 数组。然后将它们作为批处理查询加载(使用 Q.In() 查询运算符)。总共有两个查询。然后,您需要将数据合并为最终形式。您需要在何时这样做和何时使用类似 ESB 之类的工具来手动更新每个文档之间取得平衡。使用最适合数据结构的每个单独场景的方法。

【讨论】:

我喜欢这个解决方案。加载一批用户 ID,然后组装数据是个好主意。【参考方案2】:

我认为你需要取得平衡。

如果我是你,我只会在每个帖子中引用用户 ID 而不是他们的姓名/声誉。

与 RDBMS 不同的是,您可以选择在文档中嵌入 cmets。

【讨论】:

我同意。我喜欢使用 DBRef,因为用户数据容易频繁更新。另一方面,文档中的注释是完全可以接受的。【参考方案3】:

为什么要避免非规范化和更新“数千条文档记录”? Mongodb db 专为非规范化而设计。 Stackoverlow 在后台处理数百万个不同的数据。有些数据可能会在短时间内过时,这没关系。

所以上面说的主要思想是你应该有非规范化的文档,以便在 ui 上快速显示它们。

你不能通过引用的文档来查询,你需要以任何方式去规范化。

另外我建议看看cqrs架构。

【讨论】:

不是我想避免非规范化,而是我想避免天生不好的设计。将像用户记录这样常见的东西分离到我每秒可以持续更新数千条用户记录的程度似乎 1. 像矫枉过正 2. 像磁盘空间使用不当。没有其他选择吗? 这取决于你想要什么:如果你关心“磁盘空间”和非规范化,比如对你来说太过分了,我的回答可能不适合你,但是如果你关心性能并且想要达到如此速度 - - 比你应该按照上述方式进行。 更不用说,磁盘空间便宜 对 DBRef 的想法?据我了解,经常访问的记录已被缓存,并且仍然非常高效。 mongodb.org/display/DOCS/Database+References 是的,我第一次想到 DBRef 来自关系数据库世界。 mongodb 中的 DBRef 总是很糟糕,因为它是在客户端完成的(在驱动程序内部),缓存是额外的,但非规范化更好,因为使用非规范化的数据你可以用 dbref 查询不能,而且 dbref 它是对数据库的额外请求。 【参考方案4】:

尝试调查cqrs and event sourcing 架构。这将允许您按队列更新所有这些数据。

【讨论】:

以上是关于MongoDB、C# 和 NoRM + 非规范化的主要内容,如果未能解决你的问题,请参考以下文章

带有 NoRM 驱动程序的 MongoDb 中的多态性问题

详解OpenCV的矩阵规范化函数normalize()范围化矩阵的范数或值范围(归一化处理),并附NORM_MINMAX情况下的示例代码

在 tensorboard 中可视化 batch_norm 参数

岭回归和Lasso回归以及norm1和norm2

在 MongoDB 中搜索多个集合

c# winform中预防窗体重复打开