为什么选择 Prisma ORM?
在本页中,您将了解 Prisma ORM 的动机以及它与其他数据库工具(如传统 ORM 和 SQL 查询构建器)的比较。
使用关系数据库是应用程序开发中的一个主要瓶颈。调试 SQL 查询或复杂的 ORM 对象通常会消耗数小时的开发时间。
Prisma ORM 通过提供一个干净且类型安全的 API 来提交数据库查询(返回普通的旧 JavaScript 对象),使开发人员能够轻松地理解他们的数据库查询。
TLDR
Prisma ORM 的主要目标是提高应用程序开发人员在使用数据库时的生产力。以下是 Prisma ORM 如何实现这一点的几个示例
- 以对象的方式思考,而不是映射关系数据
- 查询而不是类,以避免复杂的模型对象
- 数据库和应用程序模型的单一事实来源
- 健康的约束,防止常见的陷阱和反模式
- 一种使正确的事情变得容易的抽象(“成功的陷阱”)
- 类型安全的数据库查询,可以在编译时进行验证
- 更少的样板代码,使开发人员能够专注于应用程序的重要部分
- 代码编辑器中的自动完成,无需查阅文档
本页的其余部分将讨论 Prisma ORM 如何与现有的数据库工具进行比较。
SQL、传统 ORM 和其他数据库工具的问题
当前在 Node.js 和 TypeScript 生态系统中存在的数据库工具的主要问题是,它们需要在生产力和控制之间进行重大权衡。
原始 SQL:完全控制,生产力低
使用原始 SQL(例如,使用本机 pg
或 mysql
Node.js 数据库驱动程序),您可以完全控制数据库操作。但是,生产力会下降,因为向数据库发送纯 SQL 字符串既繁琐又会带来很多开销(手动连接处理、重复的样板代码等)。
此方法的另一个主要问题是您不会为查询结果获得任何类型安全。当然,您可以手动对结果进行类型化,但这需要大量工作,并且每次更改数据库架构或查询时都需要进行重大重构,以保持类型同步。
此外,将 SQL 查询作为纯字符串提交意味着您在编辑器中无法获得任何自动完成。
SQL 查询构建器:高度控制,中等生产力
一种常见的解决方案是使用 SQL 查询构建器(例如 knex.js),这些工具提供了一个编程抽象来构建 SQL 查询。
SQL 查询构建器最大的缺点是应用程序开发人员仍然需要从 SQL 的角度来思考数据。这会带来将关系数据转换为对象的认知和实践成本。另一个问题是,如果您不确切知道自己在 SQL 查询中做什么,那么很容易让自己陷入困境。
传统 ORM:控制较少,生产力更高
传统 ORM 通过让您将应用程序模型定义为类来抽象掉 SQL,这些类映射到数据库中的表。
“对象关系映射器”(ORM)旨在弥合程序员的朋友(对象)和数据库的基元(关系)之间的差距。这些不同模型的原因既有文化方面,也有功能方面:程序员喜欢对象,因为它们将运行程序中单个事物的状态封装起来。数据库喜欢关系,因为它们更适合整个数据集的约束和整个数据集的有效访问模式。
然后,您可以通过调用模型类实例的方法来读取和写入数据。
这更方便,并且更接近开发人员在思考数据时所拥有的思维模型。那么,问题是什么呢?
ORM 代表着一个泥潭,它开始时很好,随着时间的推移变得更加复杂,很快就会让它的用户陷入一种承诺之中,这种承诺没有明确的界定点,没有明确的获胜条件,也没有明确的退出策略。
作为应用程序开发人员,您对数据的思维模型是对象。另一方面,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 的定位如下: