跳到主要内容

为什么选择 Prisma ORM?

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

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

Prisma ORM 通过提供一个简洁且类型安全的 API 来提交数据库查询,并返回 *简单的 JavaScript 对象*,使开发人员能够轻松地推理其数据库查询。

总结

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)的存在是为了弥合程序员的朋友(对象)和数据库的原语(关系)之间的差距。这些不同的模型的原因既有文化上的,也有功能上的:程序员喜欢对象,因为它们封装了运行程序中单个事物的状态。数据库喜欢关系,因为它们更适合整个数据集的约束和整个数据集的有效访问模式。

《麻烦的活动记录模式》,Cal Paterson (2020)

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

这更加方便,并且更接近开发人员在考虑其数据时的心理模型。那么,问题是什么?

ORM 代表了一个泥潭,它开始时很好,随着时间的推移变得越来越复杂,并且很快将用户困在一个没有明确分界点、没有明确获胜条件且没有明确退出策略的承诺中。

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

作为应用程序开发人员,您对数据的心理模型是一个*对象*。另一方面,SQL 中数据的心理模型是*表*。

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

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

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

这暗示了传统 ORM 的一个主要陷阱:虽然它们使您*看起来*可以使用熟悉的点表示法简单地遍历关系,但在底层,ORM 会生成 SQL JOIN,这既昂贵又有潜力大大减慢您的应用程序的速度(其中一种症状是n+1 问题)。

总而言之:传统 ORM 的吸引力在于抽象出关系模型并纯粹从对象的角度思考数据的前提。虽然这个前提很棒,但它是基于关系数据可以很容易地映射到对象的错误假设,这会导致很多复杂情况和陷阱。

应用程序开发人员应该关心数据——而不是 SQL

尽管 SQL 是在 1970 年代开发的(!),但它以令人印象深刻的方式经受住了时间的考验。然而,随着开发人员工具的进步和现代化,值得问一下 SQL 是否真的是应用程序开发人员的最佳抽象?

毕竟,开发人员应该只关心他们实现功能所需的 *数据*,而不是花时间研究复杂的 SQL 查询或整理查询结果以满足他们的需求。

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

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

Prisma ORM 使开发者更高效

Prisma ORM 的主要目标是使应用程序开发人员在处理数据库时更加高效。考虑到生产力与控制之间的权衡,这就是 Prisma ORM 的定位

Prisma ORM makes developers productive