为什么要用 Prisma?

3,368

这是一篇译文,原文在此:www.prisma.io/docs/unders…

概述

这篇文章将阐述我们开发 Prisma 的动机,以及与其他数据库工具(如 ORM 和 SQL 构造器)相比 Prisma 有什么优点。

Web 应用的开发过程中,需要花费大量时间与关系型数据库打交道,你可能需要花费数小时来调试 SQL 查询语句或者复杂的 ORM 对象模型。

Prisma 则提供一套简洁的 API,使你更加方便地操作数据库和理解查询语句。Prisma 的 API 是类型安全的,返回的数据是普通的 JS 对象(plain old JavaScript objects)。



SQL、ORM等数据库工具的问题

现存于 Node.js 和 TypeScript 生态环境中的数据库工具的主要问题是:无法很好的权衡生产力和控制力。


image.png


手写 SQL:控制力极强,生产力弱

自己手写 SQL(比如使用 pg 和 mysql 这样的 Node.js 数据库驱动)当然可以完全控制数据库操作,但是,生产力却不高,而且会遇到很多细碎的事情(如手动处理链接、操作模板)。这种方式的另一个问题在于你获取的查询结果时不是类型安全的。你可能会手动书写这些查询结果的类型,但这会花费大量的时间;另外,如果你对数据库进行了改动,你的类型文件也需要保持一致才行,这也会花费大量时间。

此外,手动构造 SQL 字符串的时候,编辑器没法给你任何提示(只能提示一些 SQL 关键字),效率极差。


SQL 构造器:控制力强,生产力一般

有不少人用的解决方案是使用 SQL 构造器(如 knext.js)以提高生产力。这种工具为构建 SQL 语句提供了封装层次较高的 API。但最大的问题在于这种工具需要开发者从 SQL 的角度来对待数据,但应用数据往往是关系型的对象,这就会导致了数据在认知层面与实际层面的差异。开发者不得不经常切换思维模型才能写好 SQL 语句。

另外一个问题是,如果开发者对 SQL 的掌握如果不够好,经常会搬起石头砸自己的脚。

ORM:控制力弱,生产力不错

ORM 可以让开发者将所有数据定义为 class,一个 class 就是一个数据表,开发者不需要对 SQL 有那么深的理解了。

你可以通过 class 的方法来对数据库进行读写,非常方便,而且也非常接近开发者的心智模型。

那么缺点是什么呢?

ORM 像一个泥沼,一开始还是平地,但是随着时间的推移,它越来越复杂,不久之后就将其用户陷于一个没有明确分界点、没有明确获胜条件、也没有明确退出策略的承诺中——The Vietnam of Computer Science

开发者将数据理解为一个一个的对象集合,但实际上这些数据是一个一个的表。


这种认知上的差异会导致「对象关系阻抗不匹配(Object-relational impedance mismatch)」,这种不匹配正是很多开发者不喜欢传统 ORM 的原因。

举例来说,两种认知到对象关系的处理是不一样的:

  • 关系型数据库认为数据都是平的(flat),使用外键来链接不同的实体,如果想要体现两个实体的关系,就需要用 JOIN 语句。
  • 面向对象认为对象是可以嵌套的(nested),通过点符合就能访问到与实体相连的另一个实体。

这个例子揭露了 ORM 的一个大陷阱:使用 ORM 表面上可以通过点符合来访问另一个实体,但是私底下却会构造 SQL JOIN 语句,这些 JOIN 是有性能陷阱的,很可能把你的应用拖得很慢,比如著名的 n+1 问题


总之,ORM的优点是抽象出关系模型并仅根据对象来操作数据。但是问题在于,关系型数据表并不能轻松地映射到对象,这会带来很多复杂性,从而引发陷阱。

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

1970年代出生的 SQL 是一门久经考验的语言,但随着开发工具的发展,我们不禁要问,SQL 真的是数据的最好抽象方式吗?

毕竟,开发者实现需求时,只需要关心其涉及到的数据,而不是花时间弄清复杂的 SQL 查询,还要对查询结果的结构进行调整,才能去做需求。

还有一个对 SQL 的争议,如果你精通 SQL,那么 SQL 是一个强大的工具;但是 SQL 的学习曲线是很陡峭的,很多经验丰富的 SQL 使用者都会不小心用错 SQL 踩到坑,造成应用的性能损失,还要花大量的时间来调试。

开发者需要一个工具来获取他/她需要的数据,同时不用担心自己用错了 SQL。他/她们需要一个工具帮他们做出对的选择,这意味着需要有一个「健康的约束」来防止出错(译者注:就好像人类为了健康,要少吃油腻食品一样,少吃油腻食品就是健康的约束)。


Prisma 让开发者更有生产力

Prisma 的主要目标就是让开发者在处理数据库是更具生产力,为了达到这个目的,Prisma 做出了以下努力:

  • 用对象来思考,而不是在大脑中映射关系型数据库
  • 查询不是类,以避免复杂的数据模型
  • 单一真理来源,数据库和数据模型来自同一个地方
  • 健康的约束,用来防止常见的陷阱和反模式
  • 使做正确的事情变得容易(“成功之道”)
  • 查询结果类型安全
  • 少用模板,这样开发者可以关注于业务
  • 编辑器自动补全

再次回到之前的那张图,Prisma 在图中的位置是这样的


image.png


控制力高于 SQL 构造器,低于手写 SQL;

但生产力最高!