YASD-TECH
YASD TECH
# Prisma

リレーション入門

投稿日:2026/4/26

更新日:2026/4/26

ttitleImage

前提:DBとPrismaの役割分担

役割 担当
実際のデータを保持する データベース(PostgreSQL)
コードからDBを操作する Prisma Client

Prismaのスキーマには「DBのカラム」と「Prisma専用の仮想フィールド」の2種類が混在しています。


わかりやすい例:投稿(Post)と著者(User)

DBのテーブルイメージ

users テーブル

id name
1 Alice
2 Bob

posts テーブル

id title author_id
10 記事A 1
11 記事B 2

author_id が外部キーで、users.id を参照しています。


Prismaスキーマの書き方

model User {
  id    Int    @id @default(autoincrement())
  name  String

  posts Post[] // ← 仮想フィールド(DBには存在しない)
}

model Post {
  id       Int    @id @default(autoincrement())
  title    String

  authorId Int    @map("author_id")           // ← DBの実カラム(author_id)
  author   User   @relation(fields: [authorId], references: [id])  // ← 仮想フィールド
}

2行の意味を詳しく解説

1行目:authorId(実カラム)

authorId Int @map("author_id")
  • DBに実際に存在するカラム
  • @map("author_id") でDB上のカラム名(スネークケース)とPrismaの名前(キャメルケース)をマッピング
  • この値を使うと IDの数値だけ取得できる
const post = await prisma.post.findUnique({ where: { id: 10 } });
console.log(post.authorId); // → 1(数値のIDだけ)
console.log(post.author);   // → undefined(仮想フィールドは別途取得が必要)

2行目:author(仮想フィールド)

author User @relation(fields: [authorId], references: [id])
  • DBには存在しない Prisma専用の仮想フィールド
  • fields: [authorId] → Postモデルの authorId を使って結合
  • references: [id] → Userモデルの id と照合する
  • include を使ってJOINすることで、リレーション先のオブジェクトを取得できる
const post = await prisma.post.findUnique({
  where: { id: 10 },
  include: { author: true }, // ← ここで初めてauthorが取得される
});
console.log(post.authorId);    // → 1
console.log(post.author.name); // → "Alice"

あるとないとで何が変わるか

authorId だけある場合

// IDしか取れない
const post = await prisma.post.findUnique({ where: { id: 10 } });
post.authorId; // ✅ 1
post.author;   // ❌ 型エラー(フィールドが存在しない)

author も定義した場合

// includeを使えばオブジェクトごと取得できる
const post = await prisma.post.findUnique({
  where: { id: 10 },
  include: { author: true },
});
post.authorId;    // ✅ 1
post.author.name; // ✅ "Alice"

元のコードに当てはめると

// 解説講義動画
lectureVideoId String?       @map("lecture_video_id") @db.Uuid
//  ↑ DBの実カラム。UUIDの値(文字列)だけを保持する

lectureVideo   LectureVideo? @relation(fields: [lectureVideoId], references: [lectureVideoId])
//  ↑ 仮想フィールド。includeすることでLectureVideoオブジェクト全体を取得できる
// lectureVideoId だけ欲しい場合
const item = await prisma.someModel.findUnique({ where: { id } });
item.lectureVideoId; // "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"

// lectureVideo の詳細情報も欲しい場合
const item = await prisma.someModel.findUnique({
  where: { id },
  include: { lectureVideo: true },
});
item.lectureVideo.title; // "第1回 基礎講義"

まとめ

フィールド DBに存在 取得できる値 用途
authorId ✅ 実カラム IDの値のみ 外部キーとして結合に使う
author ❌ 仮想 オブジェクト全体 include でJOINして詳細取得

2行セットで定義することで「IDも使えて、オブジェクトごとも取得できる」という柔軟性を持たせているのがPrismaのリレーション設計です。

Index

  • 前提:DBとPrismaの役割分担
  • わかりやすい例:投稿(Post)と著者(User)
  • DBのテーブルイメージ
  • Prismaスキーマの書き方
  • 2行の意味を詳しく解説
  • 1行目:authorId(実カラム)
  • 2行目:author(仮想フィールド)
  • あるとないとで何が変わるか
  • authorId だけある場合
  • author も定義した場合
  • 元のコードに当てはめると
  • まとめ