0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ER図を描き始める前に整理すべきポイントまとめ 〜手戻りしないDB設計のために〜

0
Posted at

ER図は「描き始めてから考える」と、ほぼ確実に手戻りが発生します。
テーブルを置いて線を引くこと自体は簡単ですが、その前段の業務の整理が曖昧なままだと、設計の途中で「そもそもこのエンティティって何だっけ?」となり、図を何度も描き直すことになります。

この記事では、ER図を作成する前に整理しておくべきポイントを、実務での手順に沿って詳しくまとめます。

1. ER図の「目的」と「レベル」を決める

最初に決めるべきは、これから描くER図が誰のための・何のための図かです。ER図には大きく3つのレベルがあり、目的によって描く粒度がまったく変わります。

レベル 内容 主な読者
概念モデル 業務上の概念と関係だけを表す。属性は最小限 業務担当者・企画
論理モデル エンティティ・属性・キー・正規化まで行う。DBMS非依存 設計者・開発者
物理モデル データ型・インデックス・制約などDBMS依存の情報まで含む 開発者・DBA

ありがちな失敗が、要件定義の段階でいきなり物理モデルを描き始めることです。業務担当者と認識合わせをしたい段階で VARCHAR(255) や インデックスの話をしても議論が発散するだけです。逆に、実装直前なのに概念モデルレベルの曖昧な図しかないと、開発者ごとに解釈がブレます。

整理すべきこと

  • この図は誰と認識合わせするためのものか
  • 概念 / 論理 / 物理 のどのレベルで描くか
  • 最終的に物理モデルまで落とすなら、対象のDBMS(MySQL / PostgreSQL など)は何か

2. 業務フローと「管理したい情報」を洗い出す

ER図はシステムの都合ではなく、業務で管理したい情報から導くのが基本です。テーブルから考え始めると、画面や帳票の形にひきずられた歪んだモデルになりがちです。

具体的には次のような資料・情報を集めます。

  • 業務フロー図、ユースケース一覧
  • 現行の帳票・Excel台帳・画面
  • 「誰が・いつ・何を・どうする」を表す業務シナリオ

このとき有効なのが、業務の文章から名詞と動詞を抜き出す方法です。

顧客商品注文すると、倉庫担当者が在庫を引き当てて出荷する」

  • 名詞(顧客・商品・注文・在庫・出荷)→ エンティティ候補
  • 動詞(注文する・引き当てる・出荷する)→ リレーションやイベント系エンティティの候補

この段階では正規化やキー設計は考えず、「管理対象になりそうなもの」を漏れなく挙げることに集中します。

3. エンティティを「リソース系」と「イベント系」に分類する

洗い出した候補は、次の2種類に分類して整理すると見通しが良くなります。

  • リソース系(マスタ): 業務の登場人物やモノ。顧客、商品、社員、倉庫など。比較的静的で、業務が続く限り存在する
  • イベント系(トランザクション): 業務上の出来事。注文、入金、出荷、問い合わせなど。「〜した」という事実の記録で、日時を必ず持つ

この分類が重要な理由は、イベント系エンティティの見落としがER図の破綻に直結するからです。たとえば「注文」を顧客と商品の単なる多対多の関連として線1本で表してしまうと、注文日時・数量・金額といった情報の置き場所がなくなります。「1つのエンティティに日時項目が複数ある(受注日、出荷日、請求日…)」場合も、イベントが1テーブルに押し込まれているサインで、分割の検討が必要です。

整理すべきこと

  • 各エンティティはリソース系かイベント系か
  • イベント系には「いつ起きたか」を表す日時があるか
  • 多対多の関係の中に、実は属性を持つ「イベント」が隠れていないか

4. 用語を統一する(データディクショナリの作成)

設計に入る前に、用語の定義合わせをしておきます。これを飛ばすと、同じものを指す複数の名前(顧客/取引先/クライアント)や、同じ名前で意味が違うもの(「ユーザー」がエンドユーザーを指す部署と管理者を指す部署がある、など)が混入し、後から発覚するほど修正コストが膨らみます。

最低限、次の対応表(データディクショナリ)を作っておくと効果的です。

論理名(業務用語) 物理名 意味・定義
顧客 customer 商品を購入する法人・個人。見込み客は含まない
注文 order 顧客からの購買依頼。確定前の見積は含まない

ポイントは「〜は含まない」という境界の定義まで書くことです。エンティティの範囲が曖昧だと、後で「見込み客はcustomerに入れるの?別テーブル?」という議論が蒸し返されます。

あわせて命名規約もこの時点で決めておきます。

  • 物理名は英語か、ローマ字か
  • 単数形(customer)か複数形(customers)か
  • ID列の名前は idcustomer_id
  • 日時列のサフィックスは _at_date

5. 識別子(キー)の方針を決める

各エンティティを一意に識別する方法を、個別のテーブル設計に入る前に全体方針として決めます。

  • ナチュラルキー(社員番号、商品コードなど業務上の番号)を主キーにするか
  • サロゲートキー(連番やUUID)を主キーにし、業務コードはユニーク制約で守るか

実務ではサロゲートキーを基本にすることが多いですが、その場合でも「業務上何が一意であるべきか」の整理は必須です。サロゲートキーだけ決めて業務キーのユニーク制約を忘れると、「同じ商品コードの商品が2件登録できてしまう」バグの温床になります。

整理すべきこと

  • 主キー方針(ナチュラル / サロゲート、連番 / UUID)
  • 各エンティティで業務上一意になるべき項目(ユニーク制約の候補)
  • 業務コードは将来変わりうるか(変わりうるなら主キーにしない)

6. リレーションの多重度と依存関係を言葉で確認する

線を引く前に、エンティティ間の関係を日本語の文章で確認します。

  • 「1人の顧客は複数の注文を持てるか?」 → Yes(1対多)
  • 「注文は顧客なしで存在できるか?」 → No(必須 = 多重度1)/ Yes(任意 = 0..1)
  • 「1つの注文に複数の商品を含められるか?」 → Yes → 多対多 → 注文明細という中間エンティティが必要

特に注意して整理すべきポイントは次の3つです。

(1) 多対多は中間テーブルに分解する前提で洗い出す
多対多の関係はRDBでは直接表現できないため、必ず中間エンティティに分解します。前述の通り、中間エンティティは単なる対応表ではなく数量や日時などの属性を持つ「イベント」であることが多いです。

(2) 0を許すかどうか(オプショナリティ)を確認する
「1対多」で済ませず、「0件もありうるのか」「必ず1件以上なのか」まで確認します。これはNOT NULL制約や外部キーの設計に直結します。

(3) 親が消えたら子はどうなるかを決める
顧客を削除したら注文はどうするか。物理削除して良いのか(ON DELETE CASCADE)、削除を禁止するのか(RESTRICT)、そもそも論理削除にするのか。これは業務ルールの問題なので、実装段階ではなく整理段階で業務側と決めておくべき項目です。

7. 履歴・時系列の要件を確認する

ER図の手戻りで最も痛いのが、履歴要件の後出しです。

  • 商品の価格が変わったら、過去の注文の金額表示も変わってしまって良いか?
  • 社員が異動したら、異動前の所属で出した申請書の表示はどうなるか?
  • 「その時点の状態」を再現する必要があるか(監査・帳票再発行など)?

「過去のデータはその時点の内容で保持したい」という要件があるなら、履歴テーブルの追加や、イベント側への値のコピー(注文明細に単価を持たせる等)が必要になり、モデルの形が大きく変わります。これは後から対応すると既存データの移行まで発生するため、必ず描き始める前に確認します。

8. データ量とライフサイクルを見積もる

物理モデルまで見据えるなら、主要なエンティティについて次を概算しておきます。

  • 初期データ件数と年間増加件数(注文が年間10万件なのか1億件なのか)
  • 保持期間(ログ系は1年で消すのか、永久保存か)
  • 参照頻度の高いアクセスパターン(「顧客IDで注文履歴を引く」など)

件数の桁がわかっていれば、「このテーブルはパーティション分割が要りそう」「この検索にはインデックスが必須」といった判断を設計に織り込めます。逆にここが不明なまま物理設計に入ると、リリース後の性能問題として跳ね返ってきます。

9. スコープ(描かない範囲)を決める

最後に、意外と忘れがちなのが描かない範囲を決めることです。

  • 外部システム連携のデータは対象に含めるか(参照するだけなら対象外とし、図では注記に留める)
  • システム管理系テーブル(設定、バッチ管理など)は同じ図に含めるか
  • 全体を1枚に描くか、サブシステム・業務領域ごとに分割するか

テーブル数が数十を超える規模なら、最初から「ユーザー管理系」「注文・決済系」のように領域ごとに図を分ける前提で計画した方が、メンテナンス性の高いER図になります。

事前整理チェックリスト

ここまでの内容をチェックリストにまとめます。ER図を描き始める前に、以下が埋まっているか確認してみてください。

  • 図の目的・読者・レベル(概念/論理/物理)を決めた
  • 対象DBMSを決めた(物理まで描く場合)
  • 業務フローから管理対象(名詞)と出来事(動詞)を洗い出した
  • エンティティをリソース系/イベント系に分類した
  • 用語の定義と境界を決めた(データディクショナリ)
  • 命名規約(物理名・単複・ID・日時サフィックス)を決めた
  • 主キー方針と業務上のユニーク項目を整理した
  • 多重度・オプショナリティを日本語の文章で確認した
  • 多対多を中間エンティティに分解した
  • 親削除時の子の扱い(CASCADE/RESTRICT/論理削除)を決めた
  • 履歴・時点再現の要件を確認した
  • データ量・保持期間・主要アクセスパターンを概算した
  • 図のスコープと分割方針を決めた

整理できたらER図に落とす — Webツール「ERoo」の紹介

ここまでの整理ができたら、あとはER図に落とし込むだけです。最後に、私が開発したER図作成Webツール 「ERoo」 を紹介させてください。

ERoo
https://eroo.sukerou.com/

ERooはブラウザでURLを開くだけで使えるER図作成ツールです。インストール不要なので、この記事を読んで「ちょっとER図を描いてみよう」と思ったその場で始められます。

この記事で整理してきたポイントを、そのまま図に反映できる機能を備えています。

  • 物理名と論理名を分けて管理 — データディクショナリで整理した「業務用語(論理名)」と「物理名」を対応させたまま設計できます
  • 多重度・参照整合性の定義 — 1対1 / 0..1 / 1対多 / 0..多 の多重度に加え、ON DELETE / ON UPDATE(CASCADE / RESTRICT / NO ACTION / SET NULL)まで指定でき、「親が消えたら子はどうするか」の決定をそのまま図に残せます
  • 制約・インデックスの定義 — 主キー・ユニーク制約・インデックスをGUIで定義。整理した「業務上のユニーク項目」を確実に制約として表現できます
  • マルチタブで領域ごとに分割 — 「ユーザー管理系」「注文・決済系」のようにタブを分けて、大規模なモデルも整理して管理できます
  • 注釈図形 — 「この範囲はフェーズ2で追加予定」といった、スコープ整理の結果をメモとして図に書き込めます
  • DDL出力 — 設計が固まったら、MySQL・PostgreSQLなどに対応した CREATE TABLE 文(インデックス・外部キー込み)をそのまま生成できます。設計書とSQLの乖離を防げます

列定義はスプレッドシート形式で一覧編集でき、CSVのインポート/エクスポートにも対応しているので、事前整理でExcelにまとめた項目一覧をそのまま取り込むこともできます。

ER図は「描く前の整理」が9割です。この記事のチェックリストで整理したうえで、ぜひERooで実際にモデルを描いてみてください。フィードバックもお待ちしています。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?