Prisma ORM が選ばれる理由
このページでは、Prisma ORM の動機と、従来の ORM や SQL クエリビルダーなどの他のデータベースツールとの比較について説明します。
リレーショナルデータベースの操作は、アプリケーション開発における大きなボトルネックです。SQL クエリや複雑な ORM オブジェクトのデバッグは、開発時間を何時間も費やすことがよくあります。
Prisma ORM は、データベースクエリを送信するための明確で型安全な API を提供することにより、開発者がデータベースクエリについて推論しやすくします。この API は、プレーンな古い JavaScript オブジェクトを返します。
TLDR
Prisma ORM の主な目標は、データベースを操作する際のアプリケーション開発者の生産性を向上させることです。Prisma ORM がこれを実現する方法の例を以下に示します。
- リレーショナルデータをマッピングするのではなく、オブジェクトで考える
- 複雑なモデルオブジェクトを避けるためのクラスではなくクエリ
- データベースとアプリケーションモデルの単一の真実の情報源
- 一般的な落とし穴やアンチパターンを防ぐ健全な制約
- 正しいことを簡単にする抽象化(「成功の落とし穴」)
- コンパイル時に検証できる型安全なデータベースクエリ
- ボイラープレートの削減により、開発者はアプリの重要な部分に集中できます
- ドキュメントを調べる必要がなく、コードエディターでのオートコンプリート
このページの残りの部分では、Prisma ORM が既存のデータベースツールとどのように比較されるかについて説明します。
SQL、従来の ORM、およびその他のデータベースツールの問題点
現在 Node.js および TypeScript エコシステムに存在するデータベースツールの主な問題は、生産性と制御の間で大きなトレードオフが必要になることです。
生の SQL:完全な制御、低い生産性
生の SQL(たとえば、ネイティブの pg
または mysql
Node.js データベースドライバーを使用)を使用すると、データベース操作を完全に制御できます。ただし、プレーンな SQL 文字列をデータベースに送信するのは面倒で、多くのオーバーヘッド(手動接続処理、反復的なボイラープレートなど)が伴うため、生産性が低下します。
このアプローチのもう 1 つの大きな問題は、クエリ結果の型安全性が得られないことです。もちろん、結果を手動で型付けすることはできますが、これは非常に手間がかかり、データベーススキーマまたはクエリを変更するたびに、型付けを同期させるために大規模なリファクタリングが必要になります。
さらに、SQL クエリをプレーンな文字列として送信することは、エディターでオートコンプリートを取得できないことを意味します。
SQL クエリビルダー:高い制御性、中程度の生産性
高いレベルの制御を維持し、より優れた生産性を提供する一般的なソリューションは、SQL クエリビルダー(例:knex.js)を使用することです。これらのツールは、SQL クエリを構築するためのプログラムによる抽象化を提供します。
SQL クエリビルダーの最大の欠点は、アプリケーション開発者が依然として SQL の観点からデータを考える必要があることです。これにより、リレーショナルデータをオブジェクトに変換するという認知的および実際的なコストが発生します。もう 1 つの問題は、SQL クエリで何をしようとしているのか正確に理解していない場合、自分で自分の足を撃ち抜くのが簡単すぎることです。
従来の ORM:低い制御性、より良い生産性
従来の ORM は、アプリケーションモデルをクラスとして定義できるようにすることで、SQL から抽象化します。これらのクラスは、データベース内のテーブルにマッピングされます。
「オブジェクトリレーショナルマッパー」(ORM)は、プログラマーの友(オブジェクト)とデータベースのプリミティブ(リレーション)の間のギャップを埋めるために存在します。これらの異なるモデルの理由は、機能的な理由と同じくらい文化的な理由です。プログラマーは、実行中のプログラムで単一のものの状態をカプセル化するため、オブジェクトが好きです。データベースは、データセット全体の制約とデータセット全体への効率的なアクセスパターンに適しているため、リレーションが好きです。
次に、モデルクラスのインスタンスでメソッドを呼び出すことにより、データを読み書きできます。
これははるかに便利であり、開発者がデータについて考えるときのメンタルモデルに近づきます。では、落とし穴は何ですか?
ORM は、最初はうまくいき、時間が経つにつれて複雑になり、まもなくユーザーを明確な区切り点、明確な勝利条件、明確な出口戦略のないコミットメントに陥らせる泥沼を表しています。
アプリケーション開発者としてのデータのメンタルモデルはオブジェクトのそれです。一方、SQL のデータのメンタルモデルはテーブルです。
データのこれら 2 つの異なる表現の間の隔たりは、多くの場合、オブジェクト-リレーショナルインピーダンスミスマッチと呼ばれています。オブジェクト-リレーショナルインピーダンスミスマッチも、多くの開発者が従来の ORM での作業を好まない主な理由です。
例として、各アプローチでデータがどのように整理され、関係が処理されるかを考えてみましょう。
- リレーショナルデータベース:データは通常、正規化(フラット)されており、外部キーを使用してエンティティ間でリンクします。次に、エンティティを JOIN して、実際のリレーションシップを具体化する必要があります。
- オブジェクト指向:オブジェクトは、ドット表記法を使用するだけでリレーションシップをトラバースできる深くネストされた構造にすることができます。
これは、従来の ORM の主な落とし穴の 1 つを示唆しています。従来の ORM は、おなじみのドット表記法を使用してリレーションシップを簡単にトラバースできるように見せかけますが、内部的には ORM は高価でアプリケーションを大幅に遅くする可能性のある SQL JOIN を生成します(この症状の 1 つは、n+1 問題です)。
結論として:従来の ORM の魅力は、リレーショナルモデルを抽象化し、データを純粋にオブジェクトの観点から考えるという前提です。前提は素晴らしいですが、リレーショナルデータをオブジェクトに簡単にマッピングできるという誤った仮定に基づいており、多くの複雑さと落とし穴につながります。
アプリケーション開発者は SQL ではなくデータに関心を持つべきです
1970 年代 (!) に開発されたにもかかわらず、SQL は印象的な方法で時の試練に耐えてきました。ただし、開発者ツールの進歩と近代化に伴い、SQL はアプリケーション開発者が操作するのに最適な抽象化であるかどうかを尋ねる価値はありますか?
結局のところ、開発者は機能実装に必要なデータのみに関心を持つ必要があり、複雑な SQL クエリを考え出したり、ニーズに合わせてクエリ結果をマッサージしたりするのに時間を費やす必要はありません。
アプリケーション開発における SQL に対するもう 1 つの議論があります。SQL の力は、自分が何をしているのかを正確に知っていれば恩恵になる可能性がありますが、その複雑さは呪いになる可能性があります。経験豊富な SQL ユーザーでさえ予測に苦労する アンチパターンと落とし穴が数多くあり、多くの場合、パフォーマンスの低下と何時間ものデバッグ時間のコストがかかります。
開発者は、SQL クエリで「正しいことをする」ことを心配するのではなく、必要なデータを要求できるようにする必要があります。彼らは、彼らのために正しい決定を下す抽象化を使用する必要があります。これは、抽象化が開発者が間違いを犯すのを防ぐ特定の「健全な」制約を課すことを意味する可能性があります。
Prisma ORM は開発者の生産性を向上させます
Prisma ORM の主な目標は、データベースを操作する際のアプリケーション開発者の生産性を向上させることです。生産性と制御の間のトレードオフを再度考慮すると、Prisma ORM は次のように適合します。