规范化 MongoDB/Mongoose,以简化 GraphQL Schema?

Posted

技术标签:

【中文标题】规范化 MongoDB/Mongoose,以简化 GraphQL Schema?【英文标题】:To normalise MongoDB/Mongoose, in order to simplify GraphQL Schema? 【发布时间】:2020-06-17 20:11:00 【问题描述】:

假设卖方架构具有 60 多个嵌入字段,表示 1:1 和 1:M 关系以及嵌入文档和文档引用的混合,例如“director”、“addresses”和“bankAccounts”。我们绝对不会存储任何超过 16MB 文档限制的大文件)。您基本上拥有一个典型的、最佳实践的、非规范化的 NoSQL 模式设计。

一位朋友建议我们应该将之前嵌入的“director”、“addresses”和“bankAccounts”字段拆分为它们自己的架构和集合。每个都有一个添加的“sellerId”字段来指向它的创建所有者/卖家。

我朋友的论点是,通过这样做,我们的 GraphQL 类型和输入模式定义变得更容易定义和管理 - 考虑到卖方的 60 多个字段?因此,他现在可以将“directors”、“addresses”和“bankAccounts”分解为自己的类型和输入定义,而不是在我们的 GraphQL Schema 中创建一个单一的、庞大的 60 多个字段“类型”和“输入类型”定义

第一季度。这有什么有效的逻辑吗?规范化 MongoDB 以简化 GraphQL 模式类型和输入处理?

第二季度。假设我们确实打破了上述那些以前嵌入的字段,无论如何这些字段大多是陈旧且不经常查询的数据,那么这样做并在 MongoDB 中进行规范化真的有那么糟糕吗?

是的,我知道如果你规范化太多,为什么不使用 RDB/SQL?我猜是因为拥有 javascript 知识、使用 JSON 和 Mongoose ORM、资源有限,这使它成为一个有吸引力的数据存储。

【问题讨论】:

【参考方案1】:

底层数据源不应驱动您的架构设计 - 使用您的 API 的客户端的需求应该驱动。

除此之外,无论您是查询嵌入文档还是使用populate/$lookup 拉入引用的文档,返回的数据都将具有相同的形状,因此尚不清楚这种差异与您的 GraphQL 架构。此外,您的数据源返回的数据的形状不需要与您的架构相匹配。即使你有一个扁平的数据结构,比如:


  "name": "...",
  "addressLine: "...",
  "city": "...",
  "state": "...",
  "zipCode": "...",

您的 GraphQL 类型可能如下所示:

type User 
  name: String
  address: Address

同样,您的数据源可以返回嵌套数据,并且您的架构可以更扁平。在这两种情况下,您只需要提供适当的解析器(如上例中地址字段的解析器)。

在您决定对数据进行规范化还是非规范化时,可能存在性能和成本方面的问题——或者您是否应该完全放弃 MongoDB。但是您的架构根本不应该是一个因素。

【讨论】:

感谢您的回复,我将在单独的答案中提供更多上下文。 @JohnPham 您应该编辑您的问题,而不是发布答案。无论如何,我不确定这会增加我的回复。同样,我的回答的重点是,无论您在 MongoDB 中如何组织数据,都与您的架构无关。没有任何一种方法可以使您的 GraphQL 架构“更加模块化”或“更易于管理”。

以上是关于规范化 MongoDB/Mongoose,以简化 GraphQL Schema?的主要内容,如果未能解决你的问题,请参考以下文章

MongoDB / Mongoose 有很多关系

GraphQL、Relay 和 Mongodb (mongoose) 如何获取数组

Mongodb/Mongoose:为用户帐户创建两种类型的模型

node.js + express.js:使用 mongodb/mongoose 处理会话

Node.js - Mongodb - Mongoose / 无法将数组字符串传递到 $push feild

MongoDB Mongoose Schema 嵌套文档结构和关系