如何设计架构非规范化以处理数据更改?

时间:2019-03-30 01:10:04

标签: mongodb mongoose-schema

我正在为MongoDB设计一个架构,并继续遇到未来的更新可能会使我的缓存数据副本无效的情况。一个示例是“用户,订单和地址”。

const UserSchema = mongoose.Schema({
    addresses: [{ street: String, city: String, state: String, zip: String }]
});

const OrderSchema = mongoose.Schema({
    address: { street: String, city: String, state: String, zip: String }
});

这似乎是一种标准方法,因为MongoDB并非旨在成为关系数据库,因此可以在可能的情况下对数据进行非规范化。但是,以下情况使我感到困惑:

  1. 用户将地址添加到其用户文档中。
  2. 用户下订单并从其列表中选择一个地址 地址。
  3. 当订单被发送时,地址数据被复制到订单文档中 坚持。
  4. 在发货之前,用户发现他们输错了 地址。
  5. 用户在其用户文档中更改了不正确的地址。
  6. 订单对象中的地址也需要更改,否则 将被运送到无效地址。

这似乎表明需要使用mongoose.Schema.Types.ObjectId进行引用来模拟集合之间的关系结构。 (当然,在这种情况下,也将有一个Addresses集合。)但是,还有其他考虑因素,例如非规范化的历史方面。我想存储订单实际发送到的地址,即使该地址后来被删除或更改了。使用非规范化,这似乎比关系范式更容易。

我考虑过一种方法来创建一个Addresses集合,然后在删除它们(如果它们已在Order中被引用)的情况下将其记录标记为无效。修改它们后,我需要检查Orders集合以查看是否引用了该地址。如果已经以发货的顺序对其进行了引用,我将不得不保留它(出于历史目的),并使用新的更改创建一个附加的地址文档。与非规范化方法相比,所有这些听起来都有些复杂。

问题的下一部分与查询和报告有关。如果要列出在伊利诺伊州曾经有过地址的所有用户的列表,则需要遍历“地址”集合和“订单”以进行查找。因为他们可能有一个伊利诺伊州地址,所以在装运订单中使用了它,然后从“地址”集合中将其删除。

最聪明的MongoDB数据架构师如何处理这种情况?我是一位经验丰富的关系数据库架构师,但对NoSQL的概念框架有些困惑。谢谢!

0 个答案:

没有答案
相关问题