2024.1.28
PrismaのSelf-relationsを使ったテーブル設計
概要
データベースであるデータとあるデータが親子関係にあることを示すために、データ自体を管理するテーブルとそのデータの親子関係を管理するテーブルという2つのテーブルによって管理できそうですが、今回は単一のテーブルによってレコードの親子関係を表現できる設計パターンを試してみました。
状況によってはアンチパターンとなりうるので、データベース上で表現したいことと設計パターンが最適かどうかは都度判断が必要になりそうです。
PrismaのSelf-relations
今回はPrismaを使ったプロジェクトにおいて、PrismaのSelf-relationsを使って単一テーブルでレコードの親子関係を表現します。
Prisma - Self-relations
今回は Item
というmodelを作ってみます。(実際にこんな抽象的なmodelはなさそうですが)
prisma_____schema.prisma_____model Item {
id Int @id @default(autoincrement())
parentItemId Int?
name String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
parentItem Item? @relation("ParentAndChildren", fields: [parentItemId], references: [id])
item Item[] @relation("ParentAndChildren")
}
上記のようにItemというmodelを定義しました。parentItemId
にItemのidが入っていない場合は最上位のItemとなります。
また、findManyしてきたItem[]を以下のようにすることで親子関係がまとまります。
TypeScript_____organizeItems.ts_____export const organizeItems = (
items: Item[],
parentItemId: number | null = null,
): OrganizedItem[] => {
return items
.filter((v) => v.parentItemId === parentItemId)
.map((item) => ({
...item,
children: organizeItems(items, Number(item.id)),
}));
};
const organizedItems = organizeItems(items ?? []);
まとめ
今回は個人開発しているアプリケーションでSelf-relationsが適していそうだったため使ってみました。
テーブルの設計パターンのひとつとして覚えておければと思います。