所有产品的单一大集合与每个产品类别的单独集合

Single big collection for all products vs Separate collections for each Product category

我是 NoSQL 的新手,我正在尝试找出为我的数据库建模的最佳方法。我将在项目中使用 ArangoDB,但我认为如果使用 MongoDB.

这个问题也成立

数据库将存储12类产品。每个类别预计包含数百或数千种产品。产品也将不断添加/删除。

所有产品都会有一些通用字段,但每个类别也会有独特的字段/对数据的不同限制。

请记住,在某些情况下我需要同时查询所有类别,例如在所有类别中搜索产品,而在其他情况下我只需要查询一个类别.

我应该创建一个集合“Product”并使用一个字段来指示类别,还是为每个类别创建一个单独的集合?

我已经阅读了很多与这个想法相关的问题(1 个集合与许多)但除了“它取决于”之外我还没有得出结论。

所以我的问题是:在这个特定的用例中,就性能和速度而言,哪个选项是最佳的,多个集合与单个集合 + 分片?

如有任何帮助,我们将不胜感激。

正如您所提到的,您需要使用您的数据和用例。你会有更好的画面。

需要做出如下决定。

  1. 确定您近期将拥有的文件数量。如果你一年有 100 万份文件,那么尝试至少 300 万份数据

  2. 确定所需的索引数。

  3. 决定每秒写入、读取的次数。

  4. 确定每个类别的文档大小。

  5. 确定查询模式。

根据需求进行一些输入

  1. 如果您有更多的写入和更多的索引,那么单个整体收集将变慢,因为需要更新多个索引。

  2. 由于每个类别有不同的字段集,您可以尝试使用多个集合。 还有$unionWith to combine data from multiple collections. But do check the performance it purely depends on the above decisions. Note this open issue

  3. 如果您决定使用单体收集,请推迟分片。一旦发现查询变慢就实施此方法。

  4. 如果您对同一个文档进行多次写入,则写入将按顺序执行。它也会减慢您的阅读速度。

  5. 考虑在从集合中清除更多数据时回收磁盘space。多个集合在这里很好。


  1. 迫使我建议整体集合的一点是 I'd need to query all the categories at the same time。您可能需要添加更多类别,但将所有类别合并为一个响应在性能方面不会更好。

  2. 由于您实际上没有像 RDBMS 中那样的连接用例,因此您可以从模型的角度使用单一整体集合。我怀疑你可能有一个连接密钥。

如果我的任何观点不正确,请告诉我。

到SQL还是到否SQL?

我认为在 NoSQL 实施此之前,您应该问问自己为什么要这样做。我非常喜欢 NoSQL 但有些数据绝对比其他数据更适合该模型。

您所描述的数据是关系型 SQL 数据库的典型案例。如果这是一个业余项目并且您想尝试 NoSQL,那很好,但是如果这是针对生产环境或客户的,您可能会让他们的处境更加困难。

关系型还是非关系型?

您提到了所有产品的公共字段。如果您希望更新这些字段并在所有产品中反映这些更新,那么您就有关系数据。

背景

可能值得一读Sarah Mei 2013 article about this。跳到 “MongoDB 如何存储数据” 部分并从那里开始阅读。警告:这篇文章名为“为什么你永远不应该使用 MongoDB”并且(可能是故意的)对 Mongo 有一定的偏见,因此通过正确的视角阅读这篇文章很重要。您应该从本文中得到的信息是 MongoDB 并不适合所有数据类型。

Mongo中处​​理关系数据的两种策略:

  1. 每次更新其中一个公共字段时,都会使用新的公共字段数据更新每个产品的文档。这通常只有在您的更新或文档很少但不是两者都很少的情况下才可以。
  2. 使用引用并进行连接。
  • 在 Mongo 中,连接通常发生在代码端(多个数据库调用)
  • 在 Arango(以及其他图形数据库,以及一些键值存储)中,连接发生在数据库端(单个数据库调用)

决定

在决定使用哪个数据库以及如何对数据建模时,这些是需要考虑的重要因素

我用过 MongoDB、ArangoDB 和 Neo4j。

  • Mongo 绝对有最好的工具而且很容易找到帮助,但我认为它不适合这种情况
  • 与 Arango 合作非常愉快,但还没有得到应有的采用
  • 我不会向任何寻求 NoSQL 解决方案的人推荐 Neo4j,因为它的节点和关系只支持平面属性(没有嵌套,所以不是真正的文档)
  • 也可能值得考虑 MariaDB 或 Postgres