一人前エンジニア道場

データベース設計 / 約30分

要件からテーブルを設計する

なぜこれを学ぶか

DB設計は「後から直せない」システムの骨格です。設計ミスは数年単位でチームを苦しめます。逆に言えば、ここで価値を出せるエンジニアは重宝されます。

手順: ①登場人物(エンティティ)を洗い出す → ②関係(リレーション)を定義する → ③属性を各テーブルに配置する。「注文」には誰が・何を・いつ・いくらで、が必要です。

正規化 の基本は「同じ情報を1か所にのみ持つ」こと。ユーザーの名前を注文テーブルにもコピーすると、改名した時に不整合が起きます。

ただし正規化しすぎも問題です。注文時の 商品価格は注文テーブルにコピーする のが正解。商品マスタの価格が後で変わっても、過去の注文金額は変わってはいけないからです。これを「スナップショット」と呼びます。

status を文字列で持つか、フラグで持つかも重要な設計判断です。「有効/無効」の2値で将来足りるか? 「休止中」が後から追加される可能性は? enum的な状態遷移は最初に設計 しましょう。

削除は 論理削除(deleted_atフラグ)か 物理削除(本当に消す)か。監査要件・復元可能性・パフォーマンスのトレードオフで決めます。

重要ポイント

  • 同じ情報は1か所に(正規化)
  • 注文時価格など「その時点の値」はスナップショット保存
  • 状態遷移は将来の拡張を見越して設計

理解度チェック

選ぶと即座に解説が表示されます。

ECサイトで「注文時の商品価格」を保存する正しい設計は?

ヒントを見る

「商品価格は将来変わるか?」を考えてみましょう。変わるなら、注文と価格をどう結びつけると「過去の注文金額」が壊れずに済むでしょうか。

SQL演習ブラウザ内SQLite

ユーザーごとの注文合計金額を求めるSQLを書いてください。要件: ユーザー名(name)と注文合計(total)を、合計金額の大きい順に取得します。users テーブルと orders テーブルを JOIN し、GROUP BY でユーザーごとに集計してください。

テーブル定義と初期データを見る
CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT);
CREATE TABLE orders (id INTEGER PRIMARY KEY, user_id INTEGER, amount INTEGER);
INSERT INTO users VALUES (1, '田中'), (2, '佐藤'), (3, '鈴木');
INSERT INTO orders VALUES (1, 1, 3000), (2, 2, 1500), (3, 1, 2000), (4, 2, 4500), (5, 3, 800);

スキルセルフチェック

このレッスンの内容をどの程度理解できましたか?