SQLのJSONおよびJSONBカラムをPrismaのJsonフィールドに変換する
SQLのJSONおよびJSONBカラムがPrismaのJsonスカラー型にどのように変換されるかを学びます。ユースケース、GINによるインデックス作成、TypeScriptでのJSONデータの型付けを解説します。
詳細な説明
PrismaにおけるJSONカラム
PostgreSQL(JSON、JSONB)とMySQL(JSON)はどちらも構造化されたJSONデータをカラムに直接格納することをサポートしています。PrismaはこれらをJsonスカラー型にマッピングし、型付きリレーショナルデータと並んで柔軟なスキーマレスストレージを提供します。
SQLの例
CREATE TABLE products (
id SERIAL PRIMARY KEY,
name VARCHAR(255) NOT NULL,
metadata JSONB NOT NULL DEFAULT '{}',
settings JSON,
tags JSONB NOT NULL DEFAULT '[]'
);
CREATE INDEX idx_products_metadata ON products USING GIN (metadata);
生成されるPrismaスキーマ
model Product {
id Int @id @default(autoincrement())
name String
metadata Json @default("{}")
settings Json?
tags Json @default("[]")
@@map("products")
}
JSON vs JSONB
| 機能 | JSON | JSONB |
|---|---|---|
| ストレージ | テキスト(フォーマットを保持) | バイナリ(分解) |
| インデックス | インデックス不可 | GIN / GiSTインデックス |
| 演算子 | 基本的 | 豊富なクエリ演算子 |
| パフォーマンス | 書き込みが高速 | 読み取りとクエリが高速 |
PrismaのJson型はスキーマレベルではJSONとJSONBを区別しません。コンバーターはPostgreSQLをターゲットにする場合、@db.Jsonまたは@db.JsonBネイティブアノテーションを使用してこの区別を保持します。
TypeScriptでのJSON型付け
PrismaのJson型は生成されたクライアントでPrisma.JsonValueにマッピングされ、これはstring | number | boolean | null | JsonObject | JsonArrayです。型安全性のために、TypeScriptインターフェースを定義してキャストしてください:
interface ProductMetadata {
color?: string;
dimensions?: { width: number; height: number };
features?: string[];
}
const product = await prisma.product.findFirst();
const meta = product.metadata as ProductMetadata;
デフォルト値
PrismaにおけるJSONのデフォルトは文字列表現を使用します:
| SQLのデフォルト | Prismaのデフォルト |
|---|---|
DEFAULT '{}' |
@default("{}") |
DEFAULT '[]' |
@default("[]") |
| 複雑なデフォルト | @default(dbgenerated("'{\"key\": \"value\"}'")) |
JSONフィールドを使うべき場面
JSONカラムは以下に最適です:
- 可変属性 — カテゴリによって異なる商品メタデータ
- 設定オブジェクト — ユーザー設定、フィーチャーフラグ
- 非正規化スナップショット — APIレスポンスキャッシュ
頻繁にクエリ、フィルタリング、JOINが必要なデータにはJSONを避けてください。その場合は、適切なリレーショナルカラムに正規化してください。
GINインデックス
PostgreSQLのJSONBカラムに対するGINインデックスは、高速な包含クエリ(@>)を可能にします。コンバーターはこれらのインデックスを保持しますが、PrismaではJSONB演算子を使用するためにローSQLクエリが必要です。
ユースケース
各商品にGINインデックス付きのJSONBとして格納された可変メタデータを持つ商品カタログがある場合に、コンバーターがこれらをPrismaのJsonフィールドにマッピングし、最適なクエリパフォーマンスのためにネイティブデータベースアノテーションを保持します。