8

我是 MongoDB 的新手,所以请多多包涵。

我有两个问题:

首先,采取以下措施:

// add a record
$obj = array( "title" => "Calvin and Hobbes", "author" => "Bill Watterson" );

MongoDB 是否将“标题”和“作者”存储为该集合中该对象的每个条目的文本?或者它是否创建了一个模式并将这些转换为字段编号(或者根本没有,只存储数据)?

我的第二个问题是:什么时候应该使用“关系”?假设我有 100 个经销商,每个经销商包含(对象方面)1,000 个客户,每个客户有 10 个项目。这使得操纵一个巨大的整体对象。

在 SQL 世界中,这都是相关的“对象”。在 Document 世界中,我们尝试通过嵌入子对象来存储完整的对象。

但是,这可能很笨拙。对此的最佳做法是什么?有人可以指出我的指导方针。

谢谢。

4

2 回答 2

13

MongoDB 是否为该集合中的每个条目提供字段名称?

是的,MongoDB 确实存储了每条记录的文本。实际上,如果磁盘空间是一个限制因素,这通常不是什么大问题,您可能需要考虑其他因素。

什么时候应该使用“关系”?

这更像是一门艺术而不是一门科学。Mongo Documentation on Schemas是一个很好的参考,但这里有一些事情需要考虑:

  • 尽可能多地投入

    文档数据库的乐趣在于它消除了许多连接。您的第一直觉应该是尽可能多地放在一个文档中。因为 MongoDB 文档具有结构,并且因为您可以在该结构中有效地查询,所以不需要像在 SQL 中那样立即规范化数据。特别是,除了其父文档之外无用的任何数据都应该是同一文档的一部分。

  • 可以从多个地方引用到自己的集合中的分离数据。

    这与其说是“存储空间”问题,不如说是“数据一致性”问题。如果许多记录将引用相同的数据,那么更新单个记录并在其他地方保留对它的引用会更有效且更不容易出错。

  • 文档大小注意事项

    MongoDB 对单个文档施加了 4MB 的大小限制。在 GB 数据的世界中,这听起来很小,但它也是 3000 万条推文或 25 万条典型的 Stack Overflow 答案或 20 张闪烁的照片。另一方面,这比一个人可能希望在典型网页上一次呈现的信息要多得多。首先考虑什么会使您的查询更容易。在许多情况下,对文档大小的关注将是过早的优化。

    在您给出的示例中,我将制作 3 个单独的集合,因为我不需要了解其他 9 个项目来为项目创建列表。我将保持简单的查询。(但请参阅底部的 Protip)

  • 复杂的数据结构:

    MongoDB 可以存储任意深度嵌套的数据结构,但不能有效地搜索它们。如果您的数据形成树、森林或图形,您实际上需要将每个节点及其边缘存储在单独的文档中。(请注意,有专门为此类数据设计的数据存储,也应考虑)

  • 数据一致性

    MongoDB 在效率和一致性之间进行权衡。规则是对单个文档的更改始终是原子的,而对多个文档的更新不应该被认为是原子的。也没有办法“锁定”服务器上的记录(您可以使用例如“锁定”字段将其构建到客户端的逻辑中)。在设计架构时,请考虑如何保持数据的一致性。通常,您在文档中保存的越多越好。

专家提示

即使您确实使用了引用,在父文档中保留一些来自引用的数据通常也是一个好主意。通常,我会保留足够的信息来建立与父代中的后代的有意义的链接。

在您的示例中,这意味着将客户名称与 ObjectID 一起保存在经销商的文档中,这样我就可以按名称创建指向每个客户的链接,而无需单独查询。如果为客户端构建 URL 需要除了他们的文档 ID 之外的其他内容,我也会存储它。

像这样的技巧可以减少 1+n 查询的情况。

于 2011-03-02T20:43:12.317 回答
1

MongoDB 是否将“标题”和“作者”存储为该集合中该对象的每个条目的文本?

MongoDB 是无模式的——所以答案很明显:是的,因为没有模式这样的东西

我的第二个问题是:什么时候应该使用“关系”?假设我有 100 个经销商,每个经销商包含(对象方面)1,000 个客户,每个客户有 10 个项目。这使得操纵一个巨大的整体对象。

请检查

http://www.mongodb.org/display/DOCS/Schema+Design

您的选择是嵌入式文档、数据库引用或多个查询。

于 2011-03-02T17:55:34.357 回答