MongoDB架构设计(嵌套数组 vs 分离集合)

3

我正在编写客户管理Web应用程序。我试图找出正确的方式来管理我的客户付款关系。每天,应用程序会向另一个API发送请求,并同步我存储在数据库中的每个客户的付款金额。我不断需要根据客户类型(合同类型、销售日期等)运行有关付款(付款金额)的报告。我已经有了clients集合。我在两种方案之间进行选择:

{
      "client_id": "asdf123",
      "client_last_name": "BB",
      "address": "123 Main St",
      "city": "ATLANTA",
      "payments_history": [
        {
          "contract_number": "asdf123",
          "payment_date": ISODate("2012-09-02T07:00:00.0Z"),
          "amount": 103.33,
          "payment_number": NumberInt(1)
        },
        {
          "contract_number": "asdf123",
          "payment_date": ISODate("2012-09-30T07:00:00.0Z"),
          "amount": 103.33,
          "payment_number": NumberInt(2)
        },
        {
          "contract_number": "asdf123",
          "payment_date": ISODate("2012-11-04T07:00:00.0Z"),
          "amount": 103.33,
          "payment_number": NumberInt(3)
        }
      ]
  }

与创建单独的集合“payments”,其中每个文档都是一个payment相比,我认为最好将这些类型的数据分开,因为每次查询都会使每个client文档增长到庞大的数据量(如果我选择特定字段仍将占用大量内存)。但另一方面,我将无法运行聚合报告(因为它基于两个不同的集合中的数据)。最佳方法是什么?我应该将它们分开并在服务器端(php)上使用两个不同的查询进行聚合吗?

老实说,我看不出在这里使用MongoDB或NoSQL的必要性,因为这似乎是一个非常简单的关系型用例。 - Mike Brant
存在复杂性,例如可能在某个时间改变的未知字段。使用 NoSQL 的正确方式是什么? - Sergey Tsibel
听起来你已经遇到了一些 NoSQL 的限制。但是,如果像你所说的那样,个别记录没有固定的模式,它仍然可能是你最好的解决方案。我将在下面写出答案。 - Mike Brant
1个回答

2

既然您需要在客户端之外(例如,用于汇总报告)查询支付数据,我建议不要将每个单独的付款项添加到客户集合对象中。

我会创建一个支付对象集合,并在每个支付对象中引用客户对象的键以及在每个客户对象中引用支付对象的键,这样您就能够明确地以任何方向关联两者之间的关系,或者创建第三个集合将客户与支付对应起来。

这里的偏好可能真的取决于您的访问模式。例如,如果查找始终只是单向的,则甚至不需要在两组对象上都使用“外键”。


如果我在聚合期间无法访问“外键”(DBRef)链接的两个集合文档,那么使用它们有什么目的? - Sergey Tsibel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接