SQLのJSONおよびJSONBカラムをPrismaのJsonフィールドに変換する

SQLのJSONおよびJSONBカラムがPrismaのJsonスカラー型にどのように変換されるかを学びます。ユースケース、GINによるインデックス作成、TypeScriptでのJSONデータの型付けを解説します。

Field Types

詳細な説明

PrismaにおけるJSONカラム

PostgreSQL(JSONJSONB)と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型はスキーマレベルではJSONJSONBを区別しません。コンバーターは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フィールドにマッピングし、最適なクエリパフォーマンスのためにネイティブデータベースアノテーションを保持します。

試してみる — SQL to Prisma Schema

フルツールを開く