【问题标题】:Single big collection for all products vs Separate collections for each Product category所有产品的单一大集合与每个产品类别的单独集合
【发布时间】:2021-04-29 08:50:46
【问题描述】:

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

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

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

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

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

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

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

任何帮助将不胜感激。

【问题讨论】:

    标签: mongodb data-structures nosql data-modeling arangodb


    【解决方案1】:

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

    需要以下一些决定。

    1. 确定您在不久的将来将拥有的文件数量。如果您一年内有 100 万个文档,那么请尝试至少 300 万个数据

    2. 确定所需的索引数量。

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

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

    5. 确定查询模式。

    一些基于需求的输入

    1. 如果你有更多的写入和更多的索引,那么单个单体集合会更慢,因为需要更新多个索引。

    2. 由于每个类别有不同的字段集,您可以尝试使用多个集合。 有$unionWith 可以组合来自多个集合的数据。但是要检查性能,它完全取决于上述决定。还要注意这个open issue

    3. 如果您决定使用整体收集,请推迟分片。一旦您发现查询速度较慢,请执行此操作。

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

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


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

    2. 由于您没有像在 RDBMS 中那样的真正连接用例,因此从模型的角度来看,您可以使用单个整体集合。我怀疑你是否有加入密钥。

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

    【讨论】:

    • 谢谢。老实说,我认为解决方案对于我的用例来说是显而易见/精确的,但我想没有办法绕过测试。
    • 是的,就是这样。您可以根据用例对数据进行重构。这就是您获得的灵活性。
    • 只是为了确保,在您的第 7 点“迫使我建议单一集合的观点”中,您建议对所有类别使用单个集合,对吗?
    【解决方案2】:

    使用 SQL 还是使用 NoSQL?

    我认为,在您在 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

    【讨论】:

    • 这开始是一个评论,但有点长......现在它变成了一个非常不同的野兽。对此感到抱歉。希望它仍然有用,即使不是很切题
    猜你喜欢
    • 1970-01-01
    • 2018-06-09
    • 2014-02-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-22
    相关资源
    最近更新 更多