演習: テーブル設計
タスク管理アプリを段階的に開発する想定で、各ステップの機能を実現するテーブル構造を設計してください。後のステップでは前のステップの設計を拡張していきます。
Step 1: 個人のタスク管理
Section titled “Step 1: 個人のタスク管理”最小構成として、個人が自分のタスクを管理するアプリを作ります。
このバージョンで実現したい機能:
- ユーザーはメールアドレスと名前でアカウントを作成する
- ユーザーはメールアドレスでログインする(同じメールアドレスで 2 アカウントは作れない)
- ユーザーはタイトル付きのタスクを作成できる
- タスクには「完了 / 未完了」の状態がある
- ユーザーは自分が作ったタスクの一覧を取得できる
この機能を実現するテーブルを設計してください。
ヒント
- エンティティは「ユーザー」と「タスク」の 2 つに分けて考える
- タスクは「誰のタスクか」を特定できる必要がある
- 一意性の保証は
UNIQUE、必須入力の保証はNOT NULL - タスクからユーザーへの参照は外部キー
Step 2: プロジェクト単位での管理
Section titled “Step 2: プロジェクト単位での管理”タスクを用途別にグループ化したいという要望が出ました。タスクを プロジェクト 単位でまとめる機能を追加します。
このバージョンで追加したい機能:
- ユーザーは名前付きのプロジェクトを作成できる
- プロジェクトには作成者(オーナー)がいる
- タスクはいずれかのプロジェクトに属する(プロジェクトに属さないタスクは作れない)
- プロジェクト単位でタスクの一覧を取得できる
この機能を実現するように、前のステップの設計を更新してください。
ヒント
- タスクの所属先は「ユーザー」から「プロジェクト」に変わる
- ユーザーとの関連は、プロジェクトを経由する形になる
- 同じテーブルから複数の役割で参照する場合は、列名に役割を込めると読みやすい(例:
owner_user_id)
Step 3: 複数メンバーで協業する
Section titled “Step 3: 複数メンバーで協業する”1 人で使うアプリから、チームで使うアプリに拡張します。
このバージョンで追加したい機能:
- プロジェクトには複数のユーザーがメンバーとして参加できる
- 1 人のユーザーは複数のプロジェクトに参加できる
- 同じユーザーが同じプロジェクトに 2 回登録されることはない
- タスクには担当者(メンバーの誰か 1 人)を割り当てられる
- 担当者が決まっていないタスクも作れる
この機能を実現するように、前のステップの設計を更新してください。
ヒント
- プロジェクトとメンバーの関連は何対何か
- 多対多の関連は 1 つのテーブルでは表せないため、間を取り持つ別のテーブル(中間テーブル)を用意する(
bookstoreのbook_tagsと同じパターン) - 中間テーブルの主キーをどう定義すれば「同じ組み合わせが 2 回登録できない」制約になるか
- 「担当者が決まっていない」は、外部キー列に NULL を許可することで表現できる
Step 4: タスクにコメント機能を追加する
Section titled “Step 4: タスクにコメント機能を追加する”チーム内でタスクについて議論や引き継ぎをできるよう、コメント機能を追加します。
このバージョンで追加したい機能:
- プロジェクトのメンバーはタスクにコメントを投稿できる
- 1 つのタスクに複数のコメントがつく
- 誰がいつ投稿したかを記録する
- コメントは長文になる可能性がある
この機能を実現するように、前のステップの設計を更新してください。
ヒント
- タスクとコメントは 1 対多
- コメント 1 件は「どのタスクへの」「誰の」投稿かを記録する必要がある
- 長文を想定する文字列は
TEXT型 - 投稿日時は
DEFAULT CURRENT_TIMESTAMPで自動記録できる
Step 5: タスクの属性を拡充する
Section titled “Step 5: タスクの属性を拡充する”進捗管理・優先度・期限を扱えるようにします。
このバージョンで追加したい機能:
- タスクの進捗状態を「未着手」「進行中」「完了」で管理する(Step 1 の完了フラグから拡張)
- タスクに優先度(低 / 中 / 高)を設定する
- タスクに期限(日付)を設定する
- タスクの作成日時と、最後に更新された日時を記録する
この機能を実現するように、前のステップの設計を更新してください。
ヒント
- 真偽値 1 つで表していた完了状態は、3 つ以上の値を取れる形に変える
- 「取りうる値が決まっている」列の表現には複数の方法がある
CHECK制約で値のリストに限定する(標準 SQL)ENUM型で列定義に選択肢を書く(MySQL 固有)- マスタテーブルに切り出して外部キーで参照する(選択肢の追加や、各選択肢に付加情報を持たせたい場合)
- 期限は日付のみなら
DATE型、時刻が必要ならDATETIME型 - 更新日時の自動更新は
ON UPDATE CURRENT_TIMESTAMP
Step 6: タグ機能を追加する
Section titled “Step 6: タグ機能を追加する”プロジェクト横断でタスクを分類できるよう、タグ機能を追加します。
このバージョンで追加したい機能:
- 1 つのタスクに複数のタグを付けられる
- タグは
#bug、#feature、#urgentのように自由に付けられる - 同じタグを複数のタスクに付けられる
- 同じタスクに同じタグを 2 回付けることはできない
この機能を実現するように、前のステップの設計を更新してください。
ヒント
- タスクとタグの関連は何対何か
- Step 3 でプロジェクトメンバーを表現したパターンが再利用できる
- タグ名の重複を防ぐ制約を考える