在 Mongo 中规范化只是为了减小文件大小/提高性能



使用MongoDB,我相当清楚规范化何时有意义,但我试图从数据大小或查询性能的角度理解它是否有意义。

例如,假设我有一个包含 2,000 家零售店的列表。例如,我不关心其他任何事情,所以我只有商店名称。至少几个字符,但永远不会超过一百个。

我有2000万条去商店的人的记录。我会记录一些关于这次旅行的信息,以及这个商店的名字。

在MySQL中,表/记录的文件大小会严重影响查询性能。规范化存储名称以便我可以存储字符串一次,然后写入密钥(一个 int),反而节省了大量磁盘空间。这转化为性能提升。

在MongoDB中,这种类型的数据很小且不重要,应该简单地嵌入。但是,我担心在 2000 万条记录之后,查询和/或文件大小会因为有多少冗余数据而遇到性能问题。

如果 500 万人都去了一家商店,那么在 mongo 文档中将有 500 万个嵌入该字符串的副本。这将占用更多的磁盘空间,并且似乎可能会消耗整数的性能。

我想如果我确实规范化了数据,Mongo 仍然会有一些性能开销来查询额外的数据。

如果 500 万人都去了一家商店,那么在 mongo 文档中将有 500 万个嵌入该字符串的副本。

是的,更糟糕的是,如果名称发生变化,您必须更新5M条目

这将占用更多的磁盘空间,并且似乎可能会消耗整数的性能。

我会放弃整数作为键。如果排序(序列器成为瓶颈),整数会产生瓶颈,如果使用 HiLo 等算法,则不会单调。使用ObjectId或其他非顺序但单调的东西。

单调通常会提高数据局部性(如果创建时间是局部性标准,则通常是这样),并有助于更有效地利用 BTree。

我有2000万条去商店的人的记录。我会记录一些关于这次旅行的信息,以及这个商店的名字。

这是一个典型的图形问题。人和商店是节点,行程是边缘。MongoDB处理规范化图比人们想象的要好。

直接比较这两种方法的性能很棘手 - 额外的往返会使规范化查询变慢,但您可以选择在每次行程中额外存储商店的名称。性能开销不会很大,但会增加 RAM 压力。

总而言之,为较少的查询调整数据结构当然是有好处的,但是对于从平均 80 字节减少到 24 字节的绝对大小,我不会这样做。规范化结构更容易保持一致(或最终一致,当存储两者时),易于查询,并且可以使用$in有效地"连接"。好处是明确的数据所有权和更大的灵活性(例如,将查询反转为"谁曾经去过x的地方")要容易得多。

规范化的问题取决于您在 95% 的时间内访问数据的方式。例如,如果您有一个网站或应用程序首先列出商店,并且然后根据请求显示前往商店的行程,然后绝对规范化

向集合中的 Store 属性添加索引将提高搜索性能,无论它是否为 int

假设您已经这样做了,从我所读到的内容来看,文档大小不会影响文档的搜索,因为它将使用索引来查找具有引用存储的行

最新更新