跳至主要内容

为何选择 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 的主要原因。

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

  • 关系型数据库:数据通常是规范化的(扁平的),并使用外键在实体之间建立链接。然后需要 JOIN 这些实体以显示实际的关系。
  • 面向对象:对象可以是深度嵌套的结构,你可以简单地使用点符号遍历关系。

这暗示了传统 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

© . This site is unofficial and not affiliated with Prisma Data, Inc.