📌

Prisma の Attribute Functions の正しい使い分け

に公開

Prisma の Schema で使用する@default属性の中に出てくるautoincrement()uuid()といった関数をなんとなく使っており、実際にどんな値が生成されるのか、どう使い分けるべきなのか曖昧だったため整理しました。

本記事では、Prisma の Attribute Functions の具体的な生成値最適な使い分け方法を詳しく解説します。この記事を読めば、プロジェクトの要件に応じて適切な関数を選択できるようになります。

Attribute Functions とは何か

Attribute Functions は、Prisma Schema で@default属性と組み合わせて使用し、フィールドのデフォルト値を自動生成する関数群です。主に ID の生成やタイムスタンプの設定に使用されます。

公式ドキュメントはこちらです。

https://www.prisma.io/docs/orm/reference/prisma-schema-reference#attribute-functions

基本的な使用例

prisma
model User {
  id        Int      @id @default(autoincrement())  // 自動増分ID
  publicId  String   @unique @default(uuid())       // 公開用UUID
  createdAt DateTime @default(now())                // 作成日時
}

主要な Attribute Functions 一覧

Prisma では主要な Attribute Functions として、以下の 5 つがあります。

autoincrement():連番 ID 生成

生成される値: 1, 2, 3, 4...

prisma
model User {
  id    Int    @id @default(autoincrement())
  email String @unique
}

特徴

  • データベースレベルで管理される連番
  • 最小サイズ(4 バイト)で高速処理
  • 予測可能なため、セキュリティ面で注意が必要

⚠️ 使用を避けるべきケース

  • 外部公開 API で ID を直接露出する場合(ユーザー数の推測が可能)
  • 分散システムやマイクロサービス(ID の重複リスクあり)
  • セキュリティが重要なシステム(予測可能性による攻撃リスク)

uuid():グローバル一意識別子

生成される値: f47ac10b-58cc-4372-a567-0e02b2c3d479

prisma
model Post {
  id        String @id @default(uuid())
  title     String
}

特徴

  • 36 文字(ハイフン含む)
  • グローバル一意性を保証
  • 分散システムでの衝突リスクが極めて低い

⚠️ 使用を避けるべきケース

  • 極限的にパフォーマンスが重要なシステム(生成コストが高い)
  • ストレージ容量が厳しく制限されている場合(36 文字は比較的長い)
  • ユーザーが手入力する必要がある ID(長すぎて入力困難)

cuid():衝突耐性 ID

生成される値: cjld2cjxh0000qzrmn831i7rn

prisma
model Article {
  id   String @id @default(cuid())
  slug String @unique @default(cuid(2))  // より短いバージョン
}

特徴

  • 25 文字(cuid)/ 24 文字(cuid2)
  • 高い衝突耐性
  • 読みやすい文字セット

⚠️ 使用を避けるべきケース

  • 金融系など最高レベルのセキュリティが必要な場合(UUID の方が安全)
  • 時系列でのソートが重要なシステム(生成時刻による順序付けができない)
  • 大文字小文字を区別しないシステム(混在による識別問題)

ulid():時系列ソート可能 ID

生成される値: 01ARZ3NDEKTSV4RRFFQ69G5FAV

prisma
model Event {
  id        String   @id @default(ulid())
  type      String
  timestamp DateTime @default(now())
}

特徴

  • 26 文字、大文字のみ
  • 時系列でソート可能(最初 10 文字がタイムスタンプ)
  • 高パフォーマンス

⚠️ 使用を避けるべきケース

  • 生成時刻を隠したいシステム(タイムスタンプが含まれるため推測可能)
  • 完全にランダムな ID が必要な場合(時系列要素により予測可能性あり)
  • 小文字を含む ID が必要なシステム(大文字のみのため制約あり)

nanoid():短縮 ID

生成される値: V1StGXR8_Z5jdHi6B-myT (21 文字)

prisma
model Invitation {
  code      String   @id @default(nanoid(8))    // 短い招待コード
  email     String
  expiresAt DateTime
}

特徴

  • 長さ調整可能(2〜255 文字)
  • URL セーフ文字
  • 軽量・高速処理

⚠️ 使用を避けるべきケース

  • 分散システムでグローバル一意性が絶対必要な場合(短いほど衝突リスク増加)
  • 長期間保存するメインの ID として使用(将来的な衝突リスク)
  • デフォルト長(21 文字)でも長すぎる制約がある場合

用途別の適切な使い分け方法

企業内システム向け

prisma
model Employee {
  id           Int      @id @default(autoincrement())
  employeeCode String   @unique @default(nanoid(8))
  createdAt    DateTime @default(now())
}

理由: 内部使用のため効率性を重視し、外部公開用の短いコードも併用

公開 Web サービス向け

prisma
model User {
  id        String   @id @default(cuid())
  username  String   @unique
  createdAt DateTime @default(now())
}

model Post {
  id       String @id @default(uuid())
  slug     String @unique @default(nanoid(12))
  authorId String
}

理由: 推測困難性とグローバル一意性を重視

ログ・分析システム向け

prisma
model PageView {
  id        String   @id @default(ulid())
  url       String
  userId    String?
  timestamp DateTime @default(now())
}

理由: 時系列ソートが重要で、大量データの効率的な処理が必要

パフォーマンス・サイズ比較表

関数 サイズ 速度 衝突耐性 時系列ソート 推測困難
autoincrement() 4B ⭐⭐⭐⭐⭐
nanoid(8) 8 文字 ⭐⭐⭐⭐ ⭐⭐⭐ ⭐⭐⭐⭐
cuid() 25 文字 ⭐⭐⭐ ⭐⭐⭐⭐ ⭐⭐⭐⭐
ulid() 26 文字 ⭐⭐⭐⭐ ⭐⭐⭐⭐ ⭐⭐⭐⭐
uuid() 36 文字 ⭐⭐ ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐⭐

この比較表を参考に、プロジェクトの要件に応じて最適な関数を選択してください。

判断フロー

適切な Attribute Function の選択は以下のフローで判断できます

  1. 用途の確認: 内部システムならautoincrement()、外部公開なら次のステップへ
  2. 要件の整理: 時系列ソートが必要ならulid()、短い ID が必要ならnanoid()
  3. 安全性重視: 最高レベルの衝突耐性が必要ならuuid()、バランス重視ならcuid()
  4. 分散システム: 単一 DB ならautoincrement()も選択肢、分散システムなら String 系 ID 必須

まとめ

Prisma の Attribute Functions は、システムのスケーラビリティセキュリティパフォーマンスに直接影響する重要な選択です。

特に分散システムやマイクロサービスでは、グローバル一意性を保証する関数の選択が重要になります。プロジェクトの初期段階でこれらの選択を適切に行うことで、後々の運用・拡張における課題を未然に防ぐことができます。

この記事の比較表を参考に最適な選択を行ってください!

Discussion