Kento
Prismaテーブル作成とリレーション
2026年08月12日
見出しはありません
要約を生成中...
Prismaを使ってテーブル作成をしたので、自分メモ用に残しておきます。 ドキュメントや記事を参考にしています。 間違いなどのコメントも大歓迎! むしろ教えて欲しいです笑
概要
背景
DB設計
テーブル作成
リレーション
おわり
簡易的なWEBアプリを作成しようと思い、今回Prismaを採用しました。 エラーログナレッジ管理アプリ。 シンプルに、エラーログをメモで残すように管理するアプリです! ユーザーが、開発中に遭遇したエラーをログとして、以下の内容を入力して投稿する。
タイトル
エラーログの内容
ステータス(解決済み?未解決?)
使用技術をタグで付与
開発環境(OS, フレームワークバージョン、フレームワーク)
エラーの原因・解決方法
今回のアプリでのリレーションを整理。
1人のユーザーが1件または複数のエラーログを投稿・編集できる(1対多)
1件のErrorLogの投稿者は、1人のUserである。(1対多)
①ユーザー
├── ①エラーログ
├── ②エラーログ
├── ③エラーログ
①エラーログ
├── ①ユーザー
②エラーログ
├── ②ユーザー
1つのTagが複数のエラーログに付与できる。(多対多)
1件のエラーログに、複数のタグを付与できる。(多対多)
①タグ(React)
├── ①エラーログ
├── ②エラーログ
├── ③エラーログ
①エラーログ
├── ①タグ(React)
├── ②タグ(Next.js)
├── ③タグ(TypeScript)
多対多は、お互い関連するテーブルのidを複数お互い持っていること。 多対多の問題点として、DBテーブルの一つのカラムには、一つの情報しか入れられない。

これを解消するために、中間テーブルを設ける必要がある。 中間テーブルにTagとErrorLogのそれぞれの外部キーを持たせることで、「どのErrorLogにどのTagがついているのか」という関係を保存するため。
Prismaでは、schema.prismaというファイルで、テーブル作成をします。
// schema.prisma
generator client {
provider = "prisma-client"
output = "../src/generated/prisma"
}
datasource db {
provider = "postgresql"
}
model User {
id String @id @default(uuid())
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
userName String @db.VarChar(255)
profileIcon String @db.Text
xUrl String @db.Text
instagramUrl String @db.Text
githubUrl String @db.Text
email String @db.VarChar(255)
password_hash String @db.VarChar(255)
errorLog ErrorLog[]
}
enum ResolutionStatus {
RESOLVED
UNRESOLVED
}
model ErrorLog {
id String @id @default(uuid())
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
title String @db.VarChar(255)
status ResolutionStatus @default(UNRESOLVED)
os String @db.VarChar(255)
framework_version String @db.VarChar(255)
framework String @db.VarChar(255)
solution String? @db.Text
cause String @db.Text
error_message String @db.Text
userId String
user User @relation(fields: [userId], references: [id])
errorLogTag ErrorLogTag[]
}
model Tag {
id String @id @default(uuid())
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
tag_name String @db.VarChar(100)
errorLogTag ErrorLogTag[]
}
model ErrorLogTag {
id String @id @default(uuid())
errorLogId String
tagId String
errorlog ErrorLog @relation(fields: [errorLogId], references: [id])
tag Tag @relation(fields: [tagId], references: [id])
@@unique([errorLogId, tagId])
}
作成したテーブル構造をもとに、何かを自動生成するもの
prisma generateコマンド実行時にどのジェネレータを使って、生成するかを指定
prisma-clientで生成したファイルの出力先
Prismaをデータベースを接続するための設定。 postgresqlを指定しています。
Prisma ORM v7からの変更点で、データベースの接続先のurlは、prisma.config.tsで設定する必要がある。
import "dotenv/config";
import { defineConfig } from "prisma/config";
export default defineConfig({
schema: "prisma/schema.prisma",
migrations: {
path: "prisma/migrations",
},
datasource: {
url: process.env.DATABASE_URL,
},
});
Prismaのモデ定義する際は、モデル名は複数形ではなく単数形にするルールがあります。
model Users ❌ → model User ✅
モデルのカラム定義は、左から順番に「カラム名 + データ型 + 属性」で記載していきます。
下のモデルで言うと、カラム名:id, データ型:String, 属性:@id @default(uuid())となります。
model User {
id String @id @default(uuid())
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
userName String @db.VarChar(255)
profileIcon String @db.Text
xUrl String @db.Text
instagramUrl String @db.Text
githubUrl String @db.Text
email String @db.VarChar(255)
password_hash String @db.VarChar(255)
errorLog ErrorLog[] // 1 User : 多 ErrorLog
}
データ型や属性については、以下の公式ドキュメントをご覧ください。
https://www.prisma.io/docs/orm/reference/prisma-schema-reference
1対多のリレーションの場合は、以下の通りに書きます。
1個のモデル: 子モデルの型名に[]を加える。Userが複数のErrorLog投稿ができるため)
多のモデル: 親のidと一致する外部キー用意し、@relation(fields: [外部キー], references: [親のID])を付与する。

model User {
id String @id @default(uuid())
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
userName String @db.VarChar(255)
profileIcon String @default("")
xUrl String @default("")
instagramUrl String @default("")
githubUrl String @default("")
email String @db.VarChar(255)
password_hash String @db.VarChar(255)
errorLog ErrorLog[]
}
enum ResolutionStatus {
RESOLVED
UNRESOLVED
}
model ErrorLog {
id String @id @default(uuid())
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
title String @db.VarChar(255)
status ResolutionStatus @default(UNRESOLVED)
os String @db.VarChar(255)
framework_version String @db.VarChar(255)
framework String @db.VarChar(255)
solution String? @db.Text
cause String @db.Text
error_message String @db.Text
userId String
user User @relation(fields: [userId], references: [id])
errorLogTag ErrorLogTag[]
}
ErrorLogモデルとTagモデルは、多対多のリレーション(関係)。
1つのTagが複数のエラーログに付与できる。(多対多)
1件のエラーログに、複数のタグを付与できる。(多対多)
なので、中間テーブルを設けて「どのErrorLogにどのTagがついているのか」という関係を保存する。
両親のモデル: 中間モデルの型名に [] を加える。(1つの親が複数の中間データを持てるため)
中間モデル: 2つの親のidと一致する外部キーをそれぞれ用意し、@relation をそれぞれに付与する。さらに @@unique([外部キー①, 外部キー②]) で複合主キーを設定して重複を防ぐ。
Prismaで複合キーを使う場合は、@@uniqueを使う。

model ErrorLog {
id String @id @default(uuid())
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
title String @db.VarChar(255)
status ResolutionStatus @default(UNRESOLVED)
os String @db.VarChar(255)
framework_version String @db.VarChar(255)
framework String @db.VarChar(255)
solution String? @db.Text
cause String @db.Text
error_message String @db.Text
userId String
user User @relation(fields: [userId], references: [id])
errorLogTag ErrorLogTag[]
}
model Tag {
id String @id @default(uuid())
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
tag_name String @db.VarChar(100)
errorLogTag ErrorLogTag[]
}
model ErrorLogTag {
id String @id @default(uuid())
errorLogId String
tagId String
errorlog ErrorLog @relation(fields: [errorLogId], references: [id])
tag Tag @relation(fields: [tagId], references: [id])
@@unique([errorLogId, tagId])
}今回は、Prismaを使ったテーブル作成とリレーションについてメモ程度に残しただけなので、参考になっていただけたら幸いです。
要約
コメント
まだコメントはありません。