本文へスキップ
BecomeCoder

SQL テーブル設計 (DDL)コース · 第7章 実務へ · レッスン23

データモデリングと ER 図 ― 設計の地図を描く

ブラウザで完結

導入

ここまでは「用意された表」や「例として作る表」を扱ってきました。実務では、まだ何もないところから「どんな表を、どうつなげて持つか」を自分で決めます。この設計作業を データモデリング、その結果を図にしたものを ER 図(Entity-Relationship Diagram/実体関連図) と呼びます。設計は SQL を書く前の、いちばん大事な工程です。

説明

DB 設計は、ふつう3段階で「抽象 → 具体」へ降りていきます。

flowchart LR
  R["要件<br/>「会員が商品を注文する<br/>ショップを作りたい」"] --> C["概念設計<br/>登場する“モノ”を洗い出す<br/>会員・商品・注文…"]
  C --> L["論理設計<br/>表・列・キー・関係を決める<br/>(ER図・正規化)"]
  L --> P["物理設計<br/>型・制約・索引を決めて<br/>CREATE TABLE に落とす"]

ER 図の登場人物は3つだけです。

  • エンティティ(実体)… 管理したい“モノ”。だいたい1エンティティ=1テーブル(会員、商品、注文)。
  • 属性… そのモノが持つ項目=列(会員の名前、年齢…)。
  • リレーション(関連)… エンティティ間のつながり。1対多・多対多の「線」(関係を JOIN でたどる方法は姉妹コース「SQL データ操作(DML)」で学びます)。線の両端に付く「1」「多(N)」を カーディナリティ(多重度) といいます。

このコースのショップ DB を ER 図ふうに描くと、こうなります(このコースの mermaid では、実体を四角、関連を矢印+多重度ラベルで表します)。

flowchart LR
  U["users(会員)<br/>id, name, age, city"]
  O["orders(注文)<br/>id, user_id, ordered_at"]
  OI["order_items(注文明細)<br/>id, order_id, product_id, quantity"]
  P["products(商品)<br/>id, name, price, category_id"]
  C["categories(カテゴリ)<br/>id, name"]
  U -->|"1 … N"| O
  O -->|"1 … N"| OI
  P -->|"1 … N"| OI
  C -->|"1 … N"| P

この1枚が、DB 全体の「地図」です。設計の良し悪しは、たいていこの図の段階で決まります。多対多を見つけたら中間テーブルを挟むordersproducts の間の order_items)、繰り返し・重複を見つけたら正規化で分ける――この章までに学んだ正規化と外部キーが、そのまま設計の判断基準になります。図ができたら、各エンティティを CREATE TABLE、リレーションを FOREIGN KEY に落とせば、実装の骨格は完成です。

やってみよう

初期表示のクエリで、このショップ DB の全テーブル名を確認しましょう。そのうえで、上の ER 図と見比べてください。「5つの四角(エンティティ)が、4本の線(リレーション)でつながっている」――このコースで手を動かしてきた対象の全体像が、1枚の地図として頭に入るはずです。

演習

「ブログ」を作るとします。posts(記事: id, title, body)というテーブルを1つ、CREATE TABLE で作ってください(次のレッスンで、これに comments をつなげます)。

ヒント1を見る

CREATE TABLE posts (id INTEGER PRIMARY KEY, title TEXT NOT NULL, body TEXT);

ヒント2を見る

記事を管理する“エンティティ”を1つの表にする、という発想です。

実際に動かしてみよう

下のエディタにクエリを書いて「実行」を押すと、ブラウザ内のSQLiteで結果が表示されます。本文の例をそのまま試したり、書き換えたりしてみましょう。

SQL — ブラウザ内で実行(SQLite)

ブラウザ内でSQLを動かす環境(SQLite)を読み込みます(初回のみ一瞬)。
スクロールして表示された時点でも自動で読み込まれます。