這是一篇譯文,原文在此:www.prisma.io/docs/unders…mysql
這篇文章將闡述咱們開發 Prisma 的動機,以及與其餘數據庫工具(如 ORM 和 SQL 構造器)相比 Prisma 有什麼優勢。sql
Web 應用的開發過程當中,須要花費大量時間與關係型數據庫打交道,你可能須要花費數小時來調試 SQL 查詢語句或者複雜的 ORM 對象模型。數據庫
Prisma 則提供一套簡潔的 API,使你更加方便地操做數據庫和理解查詢語句。Prisma 的 API 是類型安全的,返回的數據是普通的 JS 對象(plain old JavaScript objects)。安全
現存於 Node.js 和 TypeScript 生態環境中的數據庫工具的主要問題是:沒法很好的權衡生產力和控制力。app
本身手寫 SQL(好比使用 pg 和 mysql 這樣的 Node.js 數據庫驅動)固然能夠徹底控制數據庫操做,可是,生產力卻不高,並且會遇到不少細碎的事情(如手動處理連接、操做模板)。這種方式的另外一個問題在於你獲取的查詢結果時不是類型安全的。你可能會手動書寫這些查詢結果的類型,但這會花費大量的時間;另外,若是你對數據庫進行了改動,你的類型文件也須要保持一致才行,這也會花費大量時間。編輯器
此外,手動構造 SQL 字符串的時候,編輯器無法給你任何提示(只能提示一些 SQL 關鍵字),效率極差。工具
有很多人用的解決方案是使用 SQL 構造器(如 knext.js)以提升生產力。這種工具爲構建 SQL 語句提供了封裝層次較高的 API。但最大的問題在於這種工具須要開發者從 SQL 的角度來對待數據,但應用數據每每是關係型的對象,這就會致使了數據在認知層面與實際層面的差別。開發者不得不常常切換思惟模型才能寫好 SQL 語句。post
另一個問題是,若是開發者對 SQL 的掌握若是不夠好,常常會搬起石頭砸本身的腳。性能
ORM 可讓開發者將全部數據定義爲 class,一個 class 就是一個數據表,開發者不須要對 SQL 有那麼深的理解了。學習
你能夠經過 class 的方法來對數據庫進行讀寫,很是方便,並且也很是接近開發者的心智模型。
那麼缺點是什麼呢?
ORM 像一個泥沼,一開始仍是平地,可是隨着時間的推移,它愈來愈複雜,不久以後就將其用戶陷於一個沒有明確分界點、沒有明確獲勝條件、也沒有明確退出策略的承諾中——The Vietnam of Computer Science
開發者將數據理解爲一個一個的對象集合,但實際上這些數據是一個一個的表。
這種認知上的差別會致使「對象關係阻抗不匹配(Object-relational impedance mismatch)」,這種不匹配正是不少開發者不喜歡傳統 ORM 的緣由。
舉例來講,兩種認知到對象關係的處理是不同的:
這個例子揭露了 ORM 的一個大陷阱:使用 ORM 表面上能夠經過點符合來訪問另外一個實體,可是私底下卻會構造 SQL JOIN 語句,這些 JOIN 是有性能陷阱的,極可能把你的應用拖得很慢,好比著名的 n+1 問題。
總之,ORM的優勢是抽象出關系模型並僅根據對象來操做數據。可是問題在於,關係型數據表並不能輕鬆地映射到對象,這會帶來不少複雜性,從而引起陷阱。
1970年代出生的 SQL 是一門久經考驗的語言,但隨着開發工具的發展,咱們不由要問,SQL 真的是數據的最好抽象方式嗎?
畢竟,開發者實現需求時,只須要關心其涉及到的數據,而不是花時間弄清複雜的 SQL 查詢,還要對查詢結果的結構進行調整,才能去作需求。
還有一個對 SQL 的爭議,若是你精通 SQL,那麼 SQL 是一個強大的工具;可是 SQL 的學習曲線是很陡峭的,不少經驗豐富的 SQL 使用者都會不當心用錯 SQL 踩到坑,形成應用的性能損失,還要花大量的時間來調試。
開發者須要一個工具來獲取他/她須要的數據,同時不用擔憂本身用錯了 SQL。他/她們須要一個工具幫他們作出對的選擇,這意味着須要有一個「健康的約束」來防止出錯(譯者注:就好像人類爲了健康,要少吃油膩食品同樣,少吃油膩食品就是健康的約束)。
Prisma 的主要目標就是讓開發者在處理數據庫是更具生產力,爲了達到這個目的,Prisma 作出瞭如下努力:
再次回到以前的那張圖,Prisma 在圖中的位置是這樣的
控制力高於 SQL 構造器,低於手寫 SQL;
但生產力最高!