DM機能のDB設計でハマった話
現在、内定者インターンに向けてタスク管理アプリを開発しています。
その中でDM機能のデータベース設計にかなり苦戦しました。
最初はシンプルに設計したつもりでしたが、途中で「これ拡張できなくないか?」と気づき、最終的に設計を大きく見直すことになりました。
この記事では、その試行錯誤と学びをまとめており、特にDMの設計にフォーカスしております。
データベース設計を自力でやってみた
最初にDB設計を自力でやってみました。
以下、最初の設計になります。
メモ書きなので書き方はお気になさらず...
Project
project_id PK uuid
title string
created_at Date
updated_at Date
started_at Date
deadline Date
Task
task_id PK uuid
title string
state enum(pending,running,finished)
created_at Date
updated_at Date
project_id uuid FK
user_id FK
User
email PK uuid
password
family_name string
given_name string
created_at Date
Room
id PK uuid
send_user_id string
recive_user_id string
created_at Date
Message
id PK uuid
room_id FK
send_user_id string
recive_user_id string
created_at Date
感想
今見るとかなり酷いところがありますね。
世に出していいのか...
しっかり改善していきます。
改善点
ChatGPTによる添削を受けました。
今回は特に多対多の扱いの改善をメインに行いました。
(他の修正については説明省略)
多対多の扱い
今回一番難しかったのが、DMの設計でした。
始めのDM設計
まず、初めは中間テーブルを用意していませんでした。
これでは以下の問題があります。
- 同じユーザー同士の会話がバラバラに保存される
- 「会話」という単位でデータを扱えない
- 将来的にグループチャットに対応できない
ということで、Roomテーブルが必要ということで作りました。
Roomテーブル付き
これはRoomテーブルがあることで以下の利点があります。
Roomテーブルを導入することで、「メッセージ」ではなく「会話」という単位でデータを扱えるようになります。
さらに中間テーブルを追加
中間テーブルとしてroom_usersテーブルを追加します。
こうすることで、
- グループ実装がしやすい
- ユーザーとRoomの関係は「多対多」になるため、中間テーブルを用意することで正しく表現
- 設計の柔軟性up
という利点があります。
これで完成です!
JOINが必要になるためクエリは複雑になりますが、その分データ構造としては正規化され、拡張性の高い設計になります。
その他修正点
軽く書いておきます。
不足カラム
最初はupdated_atをつけていませんでした。
しかし、例えばもしバグが起こった時などに備え、ログをきちんと残すべきでした。
フロントばかりを学習してきていたので、UIとして必要かで判断してしまっている節がありました。
命名の統一
id と xxx_id が混在していました。
ルール決めて統一する必要がありました。
論理削除
deleted_at を入れるか迷い、ChatGPTと議論しました。
結局今回は不要と判断し、省きました。
気づき
- 「とりあえず作る」だと破綻する
- DM機能のような「関係性」が重要な機能では、最初からデータ構造を意識することが重要
- DM設計などのメジャーな実装はネットを探すと記事があるので、参考にするといい
完成したDB
ということで完成したER図がこちら。
まだまだ改善点はあるかと思いますが、今回はこれにて終了。
もし改善点があればコメントいただけますと幸いです。
参照
今回こちらの記事を参照させていただきました。



