【问题标题】:Querying relational data in GraphQL (NoSQL v RDS)在 GraphQL (NoSQL v RDS) 中查询关系数据
【发布时间】:2020-10-15 03:45:51
【问题描述】:

我正在编写一个应用程序,其中包含具有一些明显关系的整体数据模型。我开始使用 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 和 @ResolveField 之类的东西来获取您需要的任何内容,我想我无法理解为什么 MongoDB 本质上是关系数据的错误选择。在这种情况下,由 GraphQL 支持的 RDS 的成功实施会是什么样子?

【问题讨论】:

    标签: database orm graphql nestjs typeorm


    【解决方案1】:

    这是一个很好的问题,尽管我认为它会得到一些固执且不确定的答案。在使用多个生产 GraphQL 服务器与 SQL 和 NoSQL 数据库通信后,我的个人经验和建议如下:

    如果您要通过 Postgres 等关系数据库公开 GraphQL,并且您正在使用 NestJS不要手动编写 GraphQL 层

    非常耗时且容易出错,而且您会遇到与 N+1 和性能相关的各种问题,同时牺牲大量最初使用 RDS 获得的功能地方(比如你正在谈论的连接)。作为曾经走过这条路的人,请不要

    有许多极其强大的技术可以让您在 RDS 之上生成 GraphQL API。这些技术解析 GraphQL AST 并将其转换为优化的单个 SQL 查询。我强烈建议您查看HasuraPostGraphile。这两者都会让你大吃一惊。在 SQL 关系之上手动编写解析器只是浪费时间

    然后可以将这些工具集成到您的 NestJS 应用程序中。如果你特别对 Hasura 感兴趣,我维护的开源包可以帮助你integrate it nicely with NestJS

    【讨论】:

    • 我在写完这篇文章后不久就开始看到 N+1 的性能问题,所以我采纳了你的建议并给 Hasura 看了一下。到目前为止,重写我的应用程序是一场爆炸,我无法相信我现在能够以多快的速度制作原型。谢谢,杰西!
    猜你喜欢
    • 1970-01-01
    • 2019-10-30
    • 2016-02-17
    • 2019-01-31
    • 1970-01-01
    • 2011-05-08
    • 2019-03-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多