跳至主要内容

为什么选择 Prisma ORM?

在本页中,您将了解 Prisma ORM 的动机以及它与其他数据库工具(如传统 ORM 和 SQL 查询构建器)的比较。

处理关系数据库是应用程序开发中的一个主要瓶颈。调试 SQL 查询或复杂的 ORM 对象通常会消耗数小时的开发时间。

Prisma ORM 通过提供一个干净且类型安全的 API 来提交数据库查询并返回普通 JavaScript 对象,从而使开发人员能够轻松地理解其数据库查询。

TLDR

Prisma ORM 的主要目标是提高应用程序开发人员在处理数据库时的生产力。以下是一些 Prisma ORM 如何实现此目标的示例

  • 用对象思考而不是映射关系数据
  • 查询而非类以避免复杂模型对象
  • 数据库和应用程序模型的单一事实来源
  • 健康的约束,可防止常见的陷阱和反模式
  • 使正确的事情变得容易的抽象(“成功的陷阱”)
  • 类型安全的数据库查询,可以在编译时进行验证
  • 更少的样板代码,以便开发人员可以专注于应用程序的重要部分
  • 代码编辑器中的自动完成功能,而无需查找文档

本页的其余部分讨论了 Prisma ORM 与现有数据库工具的比较。

SQL、传统 ORM 和其他数据库工具的问题

Node.js 和 TypeScript 生态系统中当前存在的数据库工具的主要问题是,它们需要在生产力控制力之间进行重大权衡。

Productivity vs Control in ORMs, SQL query builders, and SQL

原始 SQL:完全控制,低生产力

使用原始 SQL(例如,使用原生pgmysql Node.js 数据库驱动程序)时,您可以完全控制数据库操作。但是,由于将纯 SQL 字符串发送到数据库既麻烦又会带来很多开销(手动连接处理、重复的样板代码等),因此生产力会受到影响。

这种方法的另一个主要问题是,您无法获得查询结果的任何类型安全。当然,您可以手动键入结果,但这需要大量工作,并且每次更改数据库模式或查询以保持键入同步时都需要进行重大重构。

此外,将 SQL 查询作为纯字符串提交意味着您在编辑器中无法获得任何自动完成功能。

SQL 查询构建器:高控制,中等生产力

一种保持高控制水平并提供更高生产力的常见解决方案是使用 SQL 查询构建器(例如knex.js)。这些工具提供了一种程序化抽象来构建 SQL 查询。

SQL 查询构建器最大的缺点是应用程序开发人员仍然需要从 SQL 的角度考虑其数据。这会带来将关系数据转换为对象的认知和实践成本。另一个问题是,如果您不确切知道 SQL 查询中在做什么,很容易出错。

传统 ORM:低控制,高生产力

传统 ORM 通过让您将应用程序模型定义为类来抽象 SQL,这些类映射到数据库中的表。

“对象关系映射器”(ORM)存在于程序员的朋友(对象)和数据库的基元(关系)之间架起桥梁。这些不同模型的原因既有文化上的也有功能上的:程序员喜欢对象,因为它们将运行程序中单个事物的状态封装起来。数据库喜欢关系,因为它们更适合整个数据集的约束和整个数据集的有效访问模式。

令人烦恼的 Active Record 模式,Cal Paterson(2020)

然后,您可以通过调用模型类实例上的方法来读取和写入数据。

这更加方便,并且更接近开发人员在思考数据时的思维模型。那么,有什么陷阱呢?

ORM 代表着一个泥潭,它一开始很好,随着时间的推移变得越来越复杂,很快就会让其用户陷入一种承诺之中,这种承诺没有明确的界限点、没有明确的胜利条件,也没有明确的退出策略。

计算机科学的越南战争,Ted Neward(2006)

作为应用程序开发人员,您对数据的思维模型是对象。另一方面,SQL 中数据的思维模型是

这两种不同数据表示之间的鸿沟通常被称为对象关系阻抗不匹配。对象关系阻抗不匹配也是许多开发人员不喜欢使用传统 ORM 的主要原因。

例如,请考虑每种方法如何组织数据以及如何处理关系

  • 关系数据库:数据通常是规范化的(扁平的),并使用外键在实体之间链接。然后需要连接这些实体以体现实际的关系。
  • 面向对象:对象可以是深度嵌套的结构,您只需使用点表示法即可遍历关系。

这暗示了传统 ORM 的主要陷阱之一:虽然它们看起来您可以简单地使用熟悉的点表示法遍历关系,但在后台,ORM 会生成 SQL JOIN,这些 JOIN 非常昂贵,并且有可能极大地降低应用程序的速度(其中一个症状是n+1 问题)。

总结:传统 ORM 的吸引力在于其抽象关系模型的理念,让开发者可以纯粹从对象的视角思考数据。虽然这个理念很棒,但它基于一个错误的假设,即关系数据可以轻松地映射到对象,这导致了许多复杂性和陷阱。

应用开发者应该关注数据,而不是 SQL

尽管 SQL 开发于 1970 年代(!),但它以令人印象深刻的方式经受住了时间的考验。然而,随着开发者工具的进步和现代化,值得思考的是,SQL 真的还是应用开发者使用的最佳抽象吗?

毕竟,**开发者只需要关心实现功能所需的数据**,而不必花费时间去理解复杂的 SQL 查询或修改查询结果以满足其需求。

还有另一个反对在应用开发中使用 SQL 的论点。SQL 的强大功能如果知道自己在做什么,那将是一种福音,但其复杂性也可能成为一种诅咒。有很多反模式和陷阱,即使是经验丰富的 SQL 用户也很难预料,这常常会以性能下降和数小时的调试时间为代价。

开发者应该能够请求他们需要的数据,而不必担心在他们的 SQL 查询中“做正确的事情”。他们应该使用一种为他们做出正确决策的抽象。这意味着抽象可以施加某些“健康的”约束,以防止开发者犯错。

Prisma ORM 提升开发者效率

Prisma ORM 的主要目标是提高应用开发者在处理数据库时的效率。再次考虑效率和控制之间的权衡,这就是 Prisma ORM 的作用所在。

Prisma ORM makes developers productive