mongodb中的重复数据太多?

lb3vh1jj  于 2022-12-26  发布在  Go
关注(0)|答案(2)|浏览(128)

我是NOSQL的新手,最近对mongoDB很感兴趣,我正在从头开始创建一个新网站,并决定使用MONGODB/NORM(对于C#)作为我唯一的数据库。我已经阅读了很多关于如何正确设计文档模型数据库的内容,我认为在大多数情况下,我的设计都做得很好。我的新网站大约有6个月了,我我开始看到数据复制/同步的问题,我需要一遍又一遍地处理。从我读到的内容来看,这在文档模型中是预期的,并且对于性能来说是有意义的。也就是说,你将嵌入对象粘贴到文档中,这样读起来很快--没有连接;但是当然你不能总是嵌入,所以mongodb有DbReference的概念,它基本上类似于关系数据库中的外键。
这里有一个例子:我有用户和事件;两者都有自己的文档,用户参加事件,事件有用户参加者。我决定将数据有限的事件列表嵌入到用户对象中。我还将用户列表嵌入到事件对象中作为他们的“参加者”。这里的问题是现在我必须保持用户与也嵌入到事件对象中的用户列表同步。当我阅读它时,这似乎是首选的方法,也是NOSQL处理事情的方式。检索速度很快,但后备是当我更新主用户文档时,我还需要进入事件对象,可能找到所有对该用户的引用并更新。
所以我的问题是,这是人们需要处理的一个非常常见的问题吗?在您开始说“也许NOSQL策略不适合我在这里尝试做的事情”之前,这个问题必须发生到什么程度?什么时候不必执行连接的性能优势会因为您“您很难在嵌入式对象中保持数据同步,并为此对DB执行多次读取?

fwzugrvs

fwzugrvs1#

这就是文档存储的权衡。你可以像任何标准的RDMS一样以规范化的方式存储,并且你应该尽可能地争取规范化。只有在性能受到影响的地方,你才应该打破规范化并使你的数据结构扁平化。权衡是读取效率与更新成本。
Mongo有非常高效的索引,可以像传统RDMS一样使标准化更容易(大多数文档存储都不会免费给予这个功能,这也是Mongo更像是一个混合体而非纯文档存储的原因)。你可以在用户和事件之间建立一个关系集合。它类似于表格数据存储中的代理表。索引事件和用户字段应该很快,这将帮助您更好地规范化数据。
我喜欢画出扁平化结构与保持结构规范化的效率,当涉及到更新记录数据与阅读查询中需要的内容所需的时间时,你可以用大O符号来做,但你不必那么花哨。只要根据几个用例和不同的数据模型在纸上写下一些数字,就可以对需要做多少工作有一个很好的直觉。
基本上,我所做的是首先尝试预测记录更新次数与读取频率的概率,然后尝试预测更新成本与读取成本(当记录被规范化或扁平化时(或者可能是两者的部分组合,我可以设想...很多优化选项)。然后我可以判断保持平坦与从规范化的源建立数据的成本。一旦我标出了所有的变量,如果保持它平坦的节省为我节省了一大堆,那么我将保持它平坦。
几点提示:

  • 如果您需要快速的原子式快速查找(完全最新),您可能需要一个解决方案,其中您更喜欢扁平化而不是规范化,并承担更新的影响。
  • 如果您需要快速更新,并立即访问,则支持规范化。
  • 如果您需要快速查找,但不需要完全更新的数据,请考虑在批处理作业中构建规范化数据(可能使用map/reduce)。
  • 如果您的查询需要快速,并且更新很少,并且不一定要求您的更新可立即访问,或者要求事务级锁定(它在所有时间都经历过)(以保证您的更新已写入磁盘),您可以考虑将更新写入在后台处理它们的队列。(在这个模型中,您可能需要在稍后处理冲突解决与和解)。
  • 剖析不同的模型在代码中构建一个数据查询抽象层(在某种程度上类似于ORM),以便以后可以重构数据存储结构。

还有很多其他的想法你可以使用,网上有很多很棒的博客,比如www.example.com,来讨论highscalabilty.org,确保你理解CAP定理。
还可以考虑一个缓存层,比如Redis或者memcache,我会把其中一个产品放在数据层的前面,当我查询mongo的时候(它存储所有规范化的内容),我使用数据来构造一个扁平化的表示并将其存储该高速缓存中。当我更新数据时,我将使该高速缓存中引用我正在更新的内容的任何数据无效。(尽管您必须花费时间来使该高速缓存中的数据无效,并跟踪正在更新的数据,以考虑您的缩放因子)。计算机科学中最难的两件事是命名和缓存失效。”

g2ieeal7

g2ieeal72#

尝试将UserEvent属性类型的IList添加到User对象。您没有详细说明域模型的设计方式。请查看NoRM组http://groups.google.com/group/norm-mongodb/topics中的示例。

相关问题