database - 在 GraphQL (NoSQL v RDS) 中查询关系数据
问题描述
我正在编写一个包含具有一些明显关系的整体数据模型的应用程序。我开始使用 MongoDB 编写应用程序,但决定尝试过渡到 Postgres,因为我的数据有大量“外键”。为简单起见,让我们考虑以下模型:
class GameBase {
id: string
entryIds: string[]
submissionIds: string[]
}
class EntryBase {
id: string
description: string
gameId: string
userId: string // id of user who supplied entry
submissionIds: string[] // submissions where entry is covered
}
class SubmissionBase {
id: string
url: string
gameId: string
userId: string // id of user who submitted
entryIds: string[] // entries covered by submission
}
现在我明白了,如果我使用像 TypeOrm 这样的工具,我可以通过以下方式检索这些关系:
const games = await gameRepository.find({ relations: ["entryIds", "submissionIds"] });
但我不确定这与 GraphQL 有何关系。到目前为止,我一直在做的是@ResolveField
在我的解析器中添加并编写类似的东西
// game.resolver.ts
@ResolveField(() => [SubmissionBase], { nullable: true })
submissions(@Parent() game: GameBase) {
return this.submissionService.getManySubmissions(game.submissionIds)
}
并在服务中
// game.service.ts
async getManySubmissions(submissionIds: string[]): Promise<SubmissionBase[]> {
if (!submissionIds) return []
return await this.submissionRepository.find({
where: {
id: { $in: submissionIds },
},
})
}
所以这对我来说很有意义并且一直工作得很好,我只是好奇如果我切换到关系数据库是否会看到切实的速度/性能改进。例如,如果.find
您在我的服务中看到的相同方法由 Postgres 而不是 MongoDB 支持,并且建立了适当的外键关系,我可以合理地期望速度提高吗?我想我不会,因为它只是一个没有连接的简单获取。此外,虽然 submitIds 是一个伪外键(因为 MongoDB),但在此设置中它仍然充当一个伪外键。如果您可以使用 GraphQL 之类的东西,我想我无法理解为什么 MongoDB 本质上是关系数据的错误选择@ResolveField
抓住你需要的任何东西。在这种情况下,由 GraphQL 支持的 RDS 的成功实现会是什么样子?
解决方案
这是一个很好的问题,尽管我认为它会得到一些固执己见和不确定的答案。在使用多个生产 GraphQL 服务器与 SQL 和 NoSQL 数据库通信后,我的个人经验和建议是:
如果您要通过 Postgres 等关系数据库公开 GraphQL,并且您使用的是 NestJS ,请不要手动编写 GraphQL 层
它非常耗时且容易出错,而且您将遇到与 N+1 和性能相关的各种问题,同时牺牲大量使用 RDS 获得的功能(例如您正在谈论的连接) )。作为曾经走过这条路的人,请不要
有许多非常强大的技术可以让您在 RDS 之上生成 GraphQL API。这些技术解析 GraphQL AST 并将其转换为优化的单个 SQL 查询。我强烈建议您查看Hasura和PostGraphile。这两者都会让你大吃一惊。在 SQL 关系之上手动编写解析器只是浪费时间
然后可以将这些工具集成到您的 NestJS 应用程序中并与之一起使用。如果你特别对 Hasura 感兴趣,我会维护开源包,可以帮助你将它与 NestJS 很好地集成
推荐阅读
- php - 如何在 PHP 上正确计算 XML
- c++ - 有没有办法列出所有支持的语言环境,无论是 C 还是 C++ 运行时?
- flutter - 即使我在提示文本上使用 AutoSizeText 小部件,为什么我的下拉菜单会溢出?
- python - 为一维 numpy 数组创建成对二维数组的更有效方法是什么?
- javascript - 如何在Javascript es6中过滤对象数组
- google-apps-script - 如何使用它们的索引选择两列 - GetRangeList
- python - 如何在 y 轴上绘制高斯分布?
- javascript - 一个在相等数量的真或假值之间进行排序的函数
- python - 使用python在y轴上绘制三个不同的列
- hubspot - 在 hubspot 中添加过滤器