Prisma多対多リレーションからSQLジョインテーブルへの変換

Prismaの暗黙的および明示的な多対多リレーションが複合主キーと外部キー制約を持つSQLジョインテーブルに変換される方法を学びます。

Relations

詳細な説明

多対多リレーションの変換

Prismaの多対多リレーションは暗黙的(Prismaがジョインテーブルを管理)または明示的(ジョインテーブルモデルを自分で定義)のいずれかです。SQLに変換する場合、常に明示的なジョインテーブルが必要です。

明示的な多対多(SQL変換に推奨)

model Student {
  id          Int           @id @default(autoincrement())
  name        String
  enrollments Enrollment[]

  @@map("students")
}

model Course {
  id          Int           @id @default(autoincrement())
  title       String
  enrollments Enrollment[]

  @@map("courses")
}

model Enrollment {
  studentId  Int      @map("student_id")
  courseId    Int      @map("course_id")
  enrolledAt DateTime @default(now()) @map("enrolled_at")
  student    Student  @relation(fields: [studentId], references: [id])
  course     Course   @relation(fields: [courseId], references: [id])

  @@id([studentId, courseId])
  @@map("enrollments")
}

生成されるSQL

CREATE TABLE students (
  id SERIAL PRIMARY KEY,
  name VARCHAR(255) NOT NULL
);

CREATE TABLE courses (
  id SERIAL PRIMARY KEY,
  title VARCHAR(255) NOT NULL
);

CREATE TABLE enrollments (
  student_id INTEGER NOT NULL,
  course_id INTEGER NOT NULL,
  enrolled_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  FOREIGN KEY (student_id) REFERENCES students (id),
  FOREIGN KEY (course_id) REFERENCES courses (id),
  PRIMARY KEY (student_id, course_id)
);

複合主キー

Prismaの@@id([studentId, courseId])PRIMARY KEY (student_id, course_id)制約を生成します。これにより各学生-コースの組み合わせがユニークであり、テーブルの主キーとして機能します。

暗黙的な多対多

Prismaはジョインモデルなしで両側に配列フィールドを使用する暗黙的な多対多もサポートしています。しかし、このアプローチはPrismaが内部的に管理する隠れた_ModelAToModelBジョインテーブルを作成します。SQL出力を完全に制御する必要がある場合は、常に明示的なジョインモデルを使用してください。

ジョインテーブルの追加カラム

明示的なジョインテーブルの大きな利点は、enrolledAtrolestatusなどの追加カラムを追加できることです。これらのカラムはSQL出力でジョインテーブルの通常のカラムとして表示されます。

ユースケース

学生が複数のコースに登録でき、各登録レコードにタイムスタンプが必要な大学の登録システムを構築しており、正しいジョインテーブル構造でデータベースを設定するためのSQLスキーマが必要です。

試してみる — Prisma to SQL Schema

フルツールを開く