为什么选择 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 的主要原因。
作为一个例子,考虑一下每种方法如何组织数据和处理关系
- 关系数据库:数据通常是规范化(扁平化)的,并使用外键来跨实体链接。然后需要 JOIN 这些实体以体现实际的关系。
- 面向对象:对象可以是深度嵌套的结构,你可以通过简单地使用点表示法来遍历关系。
这暗示了传统 ORM 的主要缺陷之一:虽然它们看起来你可以简单地使用熟悉的点表示法来遍历关系,但在底层,ORM 会生成昂贵的 SQL JOIN,这可能会大大降低应用程序的速度(其中一个症状是 n+1 问题)。
总结:传统 ORM 的吸引力在于抽象出关系模型并纯粹以对象的角度思考数据的前提。虽然这个前提很棒,但它是基于关系数据可以轻松映射到对象的错误假设之上的,这会导致许多复杂性和陷阱。
应用程序开发人员应该关心数据——而不是 SQL
尽管 SQL 是在 1970 年代开发的 (!),但它以令人印象深刻的方式经受住了时间的考验。然而,随着开发者工具的进步和现代化,值得问一下 SQL 是否真的是应用程序开发人员使用的最佳抽象?
毕竟,开发人员应该只关心他们实现功能所需的数据,而不是花费时间弄清楚复杂的 SQL 查询或调整查询结果以满足他们的需求。
还有另一个反对在应用程序开发中使用 SQL 的论点。如果你确切知道自己在做什么,SQL 的强大功能可能是一种祝福,但其复杂性可能是一种诅咒。即使是经验丰富的 SQL 用户也很难预料到许多 反模式 和陷阱,这通常以性能和数小时的调试时间为代价。
开发人员应该能够索取他们需要的数据,而不必担心在 SQL 查询中“做正确的事”。他们应该使用一种为他们做出正确决定的抽象。这可能意味着抽象施加某些“健康的”约束,以防止开发人员犯错误。
Prisma ORM 使开发人员高效
Prisma ORM 的主要目标是使应用程序开发人员在使用数据库时更高效。再次考虑生产力和控制之间的权衡,这就是 Prisma ORM 的定位