メインコンテンツにスキップ

Drizzle

このページでは、Prisma ORMとDrizzleを比較します。

Drizzle vs Prisma ORM

Prisma ORMとDrizzleは同様の問題を解決しますが、その動作方法は大きく異なり、個別の長所と短所があります。どちらを選択するかは、プロジェクトのニーズと、プロジェクトにとって重要な正確なトレードオフによって異なります。

Drizzle は、JavaScript/TypeScript関数でSQLクエリを構成できる従来のSQLクエリビルダーです。データベースのクエリやマイグレーションの実行に使用できます。DrizzleはQueries APIも提供しており、SQLからより高度な抽象化を提供し、ネストされたリレーションの読み取りに使用できます。DrizzleスキーマはTypeScriptファイルで定義され、SQLマイグレーションを生成するために使用され、データベースに対して実行されます。

Prisma ORM は、肥大化したモデルインスタンス、ビジネスロジックとストレージロジックの混在、型安全性または遅延ロードなどによって引き起こされる予測不可能なクエリなど、従来のORMの多くの問題を軽減します。アプリケーションモデルを宣言的に定義するために、Prismaスキーマを使用します。Prisma Migrateは、PrismaスキーマからSQLマイグレーションを生成し、データベースに対して実行することを可能にします。CRUDクエリは、Node.jsとTypeScript用の軽量で完全に型安全なデータベースクライアントであるPrisma Clientによって提供されます。

型安全

Drizzleは完全には型安全ではありません。第三者によって行われたこの比較調査で引用されているように、「Drizzleは型安全の印象を与えます。ただし、クエリ結果のみが型情報を持っています。Drizzleで無効なクエリを記述できます。」

Prismaを使用すると、生成された型のおかげで完全な型安全性が得られます。これは、コードの記述やチームメンバーとの共同作業時のエラーの可能性が少ないことを意味します。

API設計と抽象化レベル

DrizzleとPrisma ORMは、異なる抽象化レベルで動作します。Drizzleの哲学は「SQLを知っていれば、Drizzle ORMを知っている」です。APIでSQLを反映していますが、Prisma Clientは、アプリケーション開発者の一般的なタスクを念頭に置いて設計された、より高レベルの抽象化を提供します。Prisma ORMのAPI設計は、正しいことを簡単にするという考え方に大きく依存しています。

Prisma Clientはより高レベルの抽象化で動作しますが、いつでもraw SQLにドロップダウンできます。ただし、Prisma ORMの完全な使用とアプリケーションの開発には、SQLの知識は必要ありません。Prisma ORMの目標は、開発者エクスペリエンスと生産性に焦点を当て、開発者になじみのあるクエリ構文を構築することです。詳細については、こちらをご覧ください:Why Prisma

Prisma Client APIで表現できない少数のクエリのために、Prisma ORMは、.sqlファイルを直接利用することにより、よりなじみやすく型安全なエクスペリエンスを提供するTypedSQLも提供しています。既存のSQLツールとワークフローは、Prisma Clientと連携して、必要な抽象化レベルを処理できます。

完全に型付けされたSQLクエリはTypedSQLを備えたPrisma ORMで利用できますが、以下のセクションでは、PrismaとDrizzleのAPIがどのように異なるか、およびこれらのケースにおけるPrisma ORMのAPI設計の理論的根拠のいくつかの例を調べます。

データモデリング

PrismaモデルはPrismaスキーマで定義されますが、Drizzleはテーブル定義にTypeScript関数を使用します。これらの関数はエクスポートされ、クエリで使用されます。

Prismaは、DataMapper ORMパターンに従って、Prismaスキーマで定義されたモデルのデータを読み書きするための、調整された完全に型安全なAPIを公開する軽量データベースクライアントを生成します。

Prisma ORMのデータモデリング用DSLは、無駄がなく、シンプルで、直感的に使用できます。VS Codeでデータをモデリングする場合、Prisma ORMの強力なVS Code拡張機能をさらに活用できます。これには、オートコンプリート、クイックフィックス、定義へのジャンプ、および開発者の生産性を向上させるその他の利点などの機能があります。一方、DrizzleのTypeScriptの使用は、追加の柔軟性(たとえば、再利用されたコードを介して)のためにTypeScriptの力を活用できることを意味します。

Prisma ORM
model User {
id Int @id @default(autoincrement())
name String?
email String @unique
posts Post[]
}

model Post {
id Int @id @default(autoincrement())
title String
content String?
published Boolean @default(false)
authorId Int?
author User? @relation(fields: [authorId], references: [id])
}
Drizzle
import {
boolean,
integer,
pgTable,
serial,
text,
uniqueIndex,
varchar,
} from 'drizzle-orm/pg-core'

export const users = pgTable('users', {
id: serial('id').primaryKey(),
name: varchar('name', { length: 256 }),
email: varchar('email', { length: 256 }).unique(),
})

export const posts = pgTable('posts', {
id: serial('id').primaryKey(),
title: varchar('title', { length: 256 }).notNull(),
content: text('content'),
published: boolean('published'),
authorId: integer('author_id').references(() => users.id),
})

マイグレーション

マイグレーションは、DrizzleとPrisma ORMの間で同様に機能します。どちらのツールも、提供されたモデル定義に基づいてSQLファイルを生成し、データベースに対して実行するためのCLIを提供するというアプローチに従います。SQLファイルは、マイグレーションが実行される前に変更できるため、カスタムデータベース操作はどちらのマイグレーションシステムでも実行できます。

クエリ

プレーンクエリは、DrizzleとPrisma ORMの両方で自然に構築できます。DrizzleのQueries APIを使用すると、2つのアプローチは非常に似ています

Prisma ORM
// find all users
const allUsers = await prisma.user.findMany()

// find a single user
const user = await prisma.user.findFirst({
where: { id: 27 },
})

// find a unique user
const user = await prisma.user.findUnique({
where: { email: 'nilu@prisma.io' },
})
Drizzle
import { eq } from 'drizzle-orm'

// find all users
const allUsers = await db.query.users.findMany()

// find a single user
const user = await db.query.users.findFirst({
where: eq(users.id, 1),
})

// find a unique post
const user = await db.query.users.findFirst({
where: eq(users.email, 'nilu@prisma.io'),
})

ミューテーション(createupdate、またはdelete)を実行する場合、Drizzle Queries APIは使用できません。これらの場合、DrizzleのSQLライクなAPIを使用する必要があります

Prisma ORM
// create a user
const user = await prisma.user.create({
data: {
name: 'Nilu',
email: 'nilu@prisma.io',
},
})

// update a user
const user = await prisma.user.update({
where: { email: 'nilu@prisma.io' },
data: { name: 'Another Nilu' },
})

// delete a user
const deletedUser = await prisma.user.delete({
where: { email: 'nilu@prisma.io' },
})
Drizzle
// create a user
const user = await db.insert(users).values({
name: 'Nilu',
email: 'nilu@prisma.io',
})

// update a user
const user = await db
.update(users)
.set({ name: 'Another Nilu' })
.where(eq(users.email, 'nilu@prisma.io'))
.returning()

// delete a user
const deletedUser = await db
.delete(users)
.where(eq(users.email, 'nilu@prisma.io'))
.returning()

リレーション

外部キーを介して接続されたレコードを操作すると、SQLで非常に複雑になる可能性があります。Prisma ORMの仮想リレーションフィールドの概念により、アプリケーション開発者は関連データを直感的かつ便利に操作できます。Prisma ORMのアプローチの利点は次のとおりです

  • fluent APIを介したリレーションシップのトラバース (ドキュメント)
  • 接続されたレコードの更新/作成を可能にするネストされた書き込み (ドキュメント)
  • 関連レコードへのフィルターの適用 (ドキュメント)
  • 基盤となるSQLを気にすることなく、ネストされたデータの簡単で型安全なクエリ (ドキュメント)
  • モデルとそのリレーションに基づくネストされたTypeScript型定義の作成 (ドキュメント)
  • リレーションフィールドを介したデータモデルでのリレーションの直感的なモデリング (ドキュメント)
  • リレーションテーブル(JOIN、リンク、ピボット、またはジャンクションテーブルとも呼ばれます)の暗黙的な処理 (ドキュメント)
Prisma ORM
const posts = await prisma.post.findMany({
include: {
author: true,
},
})
Drizzle
const posts = await db.query.posts.findMany({
with: {
author: true,
},
})

フィルタリング

Drizzleは、特定のSQLダイアレクトの基になるフィルターおよび条件演算子を公開します。一方、Prisma ORMは、より直感的に使用できる汎用的な演算子セットを提供します。

DrizzleとPrisma ORMのフィルタリングAPIがどのように異なるかの良い例は、stringフィルターを見ることです。Drizzleはlikeilikeのフィルターを提供しますが、Prisma ORMは、開発者が使用できるより具体的な演算子(例:containsstartsWithendsWith)を提供します。

Prisma ORM
// case sensitive filter
const posts = await prisma.post.findMany({
where: {
title: 'Hello World',
},
})

// case insensitive filter
const posts = await prisma.post.findMany({
where: {
title: 'Hello World',
mode: 'insensitive',
},
})
Drizzle
// case sensitive filter
const posts = await db
.select()
.from(posts)
.where(like(posts.title, 'Hello World'))

// case insensitive filter
const posts = await db
.select()
.from(posts)
.where(ilike(posts.title, 'Hello World'))
Prisma ORM
const posts = await prisma.post.findMany({
where: {
title: {
contains: 'Hello World',
},
},
})
Drizzle
const posts = await db
.select()
.from(posts)
.where(ilike(posts.title, '%Hello World%'))
Prisma ORM
const posts = await prisma.post.findMany({
where: {
title: {
startsWith: 'Hello World',
},
},
})
Drizzle
const posts = await db
.select()
.from(posts)
.where(ilike(posts.title, 'Hello World%'))
Prisma ORM
const posts = await prisma.post.findMany({
where: {
title: {
endsWith: 'Hello World',
},
},
})
Drizzle
const posts = await db
.select()
.from(posts)
.where(ilike(posts.title, '%Hello World'))

ページネーション

Drizzleはlimit-offsetページネーションのみを提供しますが、Prisma ORMはlimit-offsetとカーソルベースの両方の専用APIを便利に提供します。両方のアプローチの詳細については、ドキュメントのページネーションセクションを参照してください。

Prisma ORM
// limit-offset pagination
const postPage = await prisma.post.findMany({
where: {
title: 'Hello World',
},
skip: 6,
take: 3,
})

// cursor-based pagination
const postPage = await prisma.post.findMany({
where: {
title: 'Hello World',
},
cursor: { id: 7 },
take: 3,
})
Drizzle
// limit-offset pagination (cursor-based not currently possible)
const postPage = await db
.select()
.from(users)
.where(ilike(posts.title, 'Hello World%'))
.limit(3)
.offset(6)

可観測性

DrizzleとPrisma ORMの両方に、クエリと生成された基盤となるSQLをログに記録する機能があります。

Prisma ORMには、チームがデータ使用状況をよりよく理解するのに役立つ追加機能がクライアントに組み込まれています。メトリクストレースは、いつでも有効にでき、クエリごとの情報を提供する2つの機能です。この情報は、時間の経過に伴うパフォーマンスを追跡できるように、外部ツールと統合できます。

追加製品

DrizzleとPrismaはどちらも、ORMに加えて製品を提供しています。Prisma Studioは、ユーザーがGUIを介してデータベースを操作できるようにするためにリリースされ、チーム内での使用のための限定的なセルフホスティングも可能です。Drizzle Studioは、同じタスクを実行するためにリリースされました。

Prisma Studioに加えて、PrismaはPrisma Data Platformを介して商用製品を提供しています

  • Prisma Accelerate:Prisma ORMと統合された接続プーラーおよびグローバルキャッシュ。ユーザーは接続プーリングをすぐに利用でき、個々のクエリレベルでキャッシュを制御できます。
  • Prisma Optimize:深い洞察、実用的な推奨事項を提供し、Prisma AIと対話してさらなる洞察を得てデータベースクエリを最適化できるクエリ分析ツール。

これらの製品はPrisma ORMと連携して、包括的なデータツールを提供し、Data DXの原則に従って、データドリブンアプリケーションの構築を容易にします。

エコシステム

DrizzleとPrisma ORMの両方には、ユーザーがライブラリで直接サポートされていないことを実行したいケースがあります。Drizzleは、これらのケースを回避するためにSQLの表現力に依存していますが、Prisma ORMには、すべてのユーザーがPrisma Clientのインスタンスに追加の動作を追加できるようにするPrisma Client拡張機能があります。これらの拡張機能は共有可能でもあり、チームはプロジェクト全体で使用するため、または他のチームで使用するために開発できます。

Drizzleは比較的新しい製品ですが、Prisma ORMは2021年にリリースされ、JavaScript/TypeScriptスペースで十分に確立されています。実績があり、多くの企業がPrisma ORMを本番環境で信頼しています。

Prisma ORMは、AmplicationWaspRedwoodJSKeystoneJSRemix、およびt3 stackのような多くのメタフレームワークおよび開発プラットフォームで、データレイヤーツールとして選択されています。

その成熟度のおかげで、Prismaのコミュニティは、さまざまなPrismaワークフローに役立つ多数の便利なツールを開発しました。以下にいくつかのハイライトを示します

  • zenstack:Prismaスキーマのアクセス制御ポリシー、自動生成されたCRUD API、およびフロントエンドクエリフックでPrismaを拡張するツールキット。
  • prisma-erd-generator:Prismaスキーマをエンティティリレーションシップ図(ERD)として視覚化します。
  • prisma-zod-generator:PrismaスキーマからZodスキーマを生成します。
  • bridg:Prisma Clientを使用してフロントエンドからデータベースにアクセスできるようにします。
  • jest-prismaJestと統合されたPrismaテストの環境。
  • prisma-pothos-typesGraphQL Pothosを使用する場合に、Prismaモデルに基づいてGraphQL型を作成します。
  • prisma-trpc-generator:PrismaスキーマからtRPCルーターを作成します。
  • @cerbos/orm-prismaCerbosの認可ポリシーに基づいてデータをフィルタリングします。

データベースサポート

DrizzleとPrisma ORMはどちらも、複数の異なる種類のデータベースをサポートしています。Drizzleは、既存のサードパーティ製データベースドライバーと統合する、Drizzleによって作成されたドライバー実装を通じてこのサポートを実現します。

Prisma ORMは、サードパーティ製データベースドライバーのサポートを追加し始めていますが、主に基盤となるデータベースと通信するために組み込みドライバーを使用しています。Prismaは、セキュリティを向上させるTLSへの接続もデフォルトで設定しています。

さらに、Prisma ORMはCockroachDB、Microsoft SQL Server、およびMongoDBをサポートしていますが、Drizzleは現在サポートしていません。Prisma ORMは、リレーションモードも提供しており、Prisma ORMが外部キー制約をサポートしていないデータベースエンジンに対してエミュレートできるようにします。Drizzleは現在、Cloudflare D1、bun:sqlite、およびHTTPプロキシ経由のSQLiteをサポートしていますが、Prisma ORMは現在サポートしていません。

ベンチマーク

ORMを選択する際にパフォーマンスが重要な考慮事項であることを理解しています。さまざまなORMのパフォーマンスを比較するために、Vercelがホストするオープンソースのデータベースレイテンシベンチマークツールを使用できます。このツールを使用すると、さまざまなワークロードと構成の下で、さまざまなORMのレイテンシとスループットを評価できます。検討しているデータベースまたはデータベースプロバイダーに対してベンチマークを実行することにより、情報に基づいた意思決定を行うのに役立つ相対的なパフォーマンス特性を明確に把握できます。

または、Drizzleを含む一般的なTypeScript ORMを比較する、当社が構築したベンチマークツールの調査結果を確認することもできます。このベンチマークはオープンソースであり、Node.jsおよびTypeScriptエコシステムにおけるデータベースプロバイダーとORMライブラリ全体のデータベースクエリレイテンシの公平な比較を目的としています。

結論

Drizzle ORMとPrisma ORMはどちらも、データアクセスとマイグレーションのためのツールです。DrizzleはSQLライクな構文のシンラッパーであることに重点を置いていますが、Prismaは便利で表現力豊かなAPIに重点を置いています。その他の重要な違いには、Prisma ORMのMSSQLおよびMongoDBのサポート、Prisma Client拡張機能による追加機能のサポート、追加のクラウド対応製品、および堅牢なエコシステムが含まれます。

一方、データベースの経験レベルが異なる開発者(フロントエンド、バックエンド、およびフルスタック)の混成チームの場合、Prisma ORMは、データアクセスとデータベーススキーマの管理のための包括的で習得しやすいアプローチを提供します。


Prismaとのつながりを保ちましょう

以下とつながることで、Prismaの旅を続けましょう アクティブなコミュニティ。最新情報を入手し、参加し、他の開発者と協力しましょう

私たちはあなたの参加を心から大切にし、あなたが私たちのコミュニティの一員になることを楽しみにしています!