📖 テーマ設定
🔊 音声設定
1.2
1.0
1.0
▶️ 再生コントロール
🎵 BGM設定
0.3
🔔 効果音設定
0.3

内部設計とDBMS〜正規化の考え方

概要

  • 日程: Day 7 / セッション 1
  • 時間: [9:30-10:00]
  • 形式: 座学
  • ゴール: 内部設計の役割(外部設計をシステム内部でどう実現するか)とDBMSのメリット(アクセスの標準化・クエリによる高速化)を説明し、第一〜第三正規化の手順を例で示せる
  • 学習形式: 対話型解説、デモンストレーション

導入(5分)

昨日までに外部設計書(画面一覧・機能一覧・画面遷移図・画面仕様書)が完成しました。
ユーザから見える「外側」は決まった、ということです。

ここで少し考えてみてください。
画面で入力された会員情報や予約情報は、ボタンを押した後、どこへ行くのでしょうか?

答えは「システムの内部」です。
今日からの2日間は、その内部を設計します。

  • 外部設計: ユーザ・お客様から見える部分の設計(What を見せるか)
  • 内部設計: それをシステム内部でどう実現するかの設計(How で動かすか)

レストランに例えると、外部設計はメニューと客席のレイアウトです。
内部設計は厨房の設計です。
お客様からは見えませんが、厨房がぐちゃぐちゃだと料理は出てきません。

今日のテーマは、その厨房の心臓部「データの置き場所」の設計です。

本編(20分)

1. 内部設計とは〜要件を仕様に変換する

内部設計とは、外部設計をシステム内部でどのように実現するのかを仕様として定義する作業です。

  • 要件を仕様(設計書)に変換する
  • システムの具体的な動作を決める

外部設計と内部設計の違いを対比で確認しましょう。
「予約一覧画面に予約が日付順で表示される」は外部設計です。ユーザから見える振る舞いだからです。
「予約テーブルから予約日をキーに昇順で取得する」は内部設計です。ユーザからは見えない実現方法だからです。

本研修の内部設計で作る成果物は4つです。

flowchart LR A["テーブル定義書
(Day 7)"] --> B["ER図
(Day 7)"] B --> C["CRUD図
(Day 8)"] C --> D["機能設計書
(Day 8)"]

今日はこのうち前半の2つ、テーブル定義書とER図を作ります。
入力になるのは、Day 4で作った情報モデル定義書です。
タスクの関係を意識してください。前のタスクの成果物を必ず利用します。

ここがポイント

  • 内部設計は「外部設計で約束したことを、内部でどう実現するか」の設計
  • 外部設計に書いていないことを勝手に追加するのは要注意。逆に外部設計にあるのに内部設計で実現されないのは設計漏れ
  • 「ユーザから見えるか・見えないか」が外部設計と内部設計を見分ける目印

コラム

「設計書なんて書かずにいきなり作ればいいのでは?」と思った人へ。
有名な格言があります。「コードを書くのに1時間かかるバグは、設計なら5分で直せる」。
建築で例えると、壁を建てた後に「配管を忘れた」と気づくと壁を壊すことになります。
図面の段階なら、線を引き直すだけです。
ソフトウェアも同じで、後工程での修正ほど高くつきます。これを「手戻りコスト」と呼びます。

2. DBMSとは〜なぜファイルに直接書かないのか

DBMS(DataBase Management System:データベース管理システム)は、データの保存・検索・更新を一手に引き受けてくれるソフトウェアです。
MySQL、PostgreSQL、SQLiteなどが代表例です。

ここで考えてみてください。
データはテキストファイルに直接書いても保存できます。なぜわざわざDBMSを使うのでしょうか?

DBMSの主なメリットは2つです。

  • アクセスの標準化
    • SQLという共通の言葉でデータを操作できる
    • 誰が書いても「SELECT 文で取り出す」という同じ作法になる
    • ファイル直書きだと、読み書きの方法をプログラマごとに発明することになり、バラバラになる
  • クエリによる高速化
    • DBMSは索引(インデックス)などの仕組みで、大量のデータから一瞬で目的の行を探せる
    • 図書館に例えると、本棚を端から全部見るのではなく、蔵書検索システムで一発で棚番号がわかるイメージ

ほかにも、複数人が同時に書き込んでも壊れない仕組み(排他制御)や、途中で失敗したら元に戻す仕組み(トランザクション)も持っています。

なお、本研修ではDBMSを使わない選択もできます。
その場合もデータの設計は必要で、「正規化したデータ」と「ファイル設計書」を作ります。
保存先がテーブルかファイルかが違うだけで、データを整理する考え方は同じです。

ここがポイント

  • DBMSのメリットは「アクセスの標準化」と「クエリによる高速化」。この2つは言えるようにする
  • DBMSを使わないチームも正規化は行う。正規化はDBMSの機能ではなく「データ整理の考え方」だから
  • 自チームの開発ツール(Bubble等)が内部でどうデータを持つかも確認しておくとよい

コラム

リレーショナルデータベースの理論は、1970年にIBMのエドガー・F・コッド博士が1本の論文で提唱しました。
当時のIBMは自社の既存製品と競合するため、この発明にあまり乗り気でなかったと言われています。
その隙に他社が商用化して大成功しました。それが後のOracle社です。
「良いアイデアを放置すると他人が形にする」という、PBL的にも教訓のある話です。

3. 正規化〜伝票を例に第一→第二→第三正規形へ

いよいよ今日の核心です。
正規化とは、データの重複をなくし、矛盾が起きない形にテーブルを分割していく手順です。

具体的な伝票で見ていきます。文房具店の注文票です。

正規化前(非正規形): 注文票そのままの形

注文番号 注文日 顧客番号 顧客名 顧客住所 商品コード・商品名・単価・数量(繰り返し)
1001 6/10 C01 佐藤 東京都港区 S01 ボールペン 100円 ×3、S02 ノート 200円 ×5
1002 6/11 C02 鈴木 大阪市北区 S02 ノート 200円 ×2

1枚の伝票の中に商品が複数並んでいます。これが「繰り返し項目」です。
繰り返しがあると、プログラムから「2番目の商品の数量」を取り出すのが大変です。

第一正規化: 繰り返しをなくし、1行1事実にする

注文番号 注文日 顧客番号 顧客名 顧客住所 商品コード 商品名 単価 数量
1001 6/10 C01 佐藤 東京都港区 S01 ボールペン 100 3
1001 6/10 C01 佐藤 東京都港区 S02 ノート 200 5
1002 6/11 C02 鈴木 大阪市北区 S02 ノート 200 2

繰り返しは消えました。この表の主キーは「注文番号+商品コード」の組み合わせです。
しかし注文日や顧客名が何度も重複しています。気持ち悪いですね。

第二正規化: 主キーの一部だけで決まる項目を分離する

「注文日・顧客名」は注文番号だけで決まります。「商品名・単価」は商品コードだけで決まります。
主キーの一部にしか依存しない項目(部分関数従属)を別テーブルに出します。

  • 注文テーブル: 注文番号(主キー), 注文日, 顧客番号, 顧客名, 顧客住所
  • 注文明細テーブル: 注文番号+商品コード(主キー), 数量
  • 商品テーブル: 商品コード(主キー), 商品名, 単価

これで「商品名を変えたいのに注文明細を全行直す」事態がなくなりました。

第三正規化: 主キー以外の項目で決まる項目を分離する

注文テーブルをよく見てください。
顧客名と顧客住所は、主キーの注文番号ではなく「顧客番号」で決まります。
主キー以外を経由して決まる項目(推移的関数従属)を別テーブルに出します。

  • 注文テーブル: 注文番号(主キー), 注文日, 顧客番号
  • 顧客テーブル: 顧客番号(主キー), 顧客名, 顧客住所
  • 注文明細テーブル: 注文番号+商品コード(主キー), 数量
  • 商品テーブル: 商品コード(主キー), 商品名, 単価
flowchart TD A["非正規形 繰り返し項目あり"] -->|第一正規化 繰り返しを行に展開| B["第一正規形 1行1事実"] B -->|第二正規化 主キーの一部で決まる項目を分離| C["第二正規形 注文・明細・商品に分割"] C -->|第三正規化 主キー以外で決まる項目を分離| D["第三正規形 顧客を分離して完成"]

ここで考えてみてください。
もし正規化せずに顧客住所を全伝票にコピーしたまま、佐藤さんが引っ越したらどうなるでしょうか?
過去の伝票を全部探して書き換えることになります。1件でも直し忘れると「住所が2つある顧客」が生まれます。
これを更新時異常と呼びます。正規化は「1つの事実は1か所にだけ書く」ための手順です。

ここがポイント

  • 第一正規化=繰り返しをなくす。第二正規化=主キーの一部で決まる項目を分ける。第三正規化=主キー以外で決まる項目を分ける
  • 合言葉は「1つの事実は1か所に」(One Fact In One Place)
  • よくある間違い: 分割しただけで「どの列が主キーか」を決め忘れる。各テーブルの主キーを必ず宣言する
  • 単価のように「注文時点の値を残したい」項目は、あえて明細側にコピーする実務判断もある。まず第三正規形を作り、崩すなら理由を言えるようにする

コラム

正規形には実は第四、第五、さらにボイス・コッド正規形まであります。
ではなぜ実務は第三正規形までで止まるのか。
コッド博士の同僚ウィリアム・ケントが残した覚え方が有名です。
「すべての項目は、キーに依存し(第一)、キー全体に依存し(第二)、キー以外の何物にも依存してはならない(第三)。神に誓って(So help me Codd)」。
法廷の宣誓「So help me God」のGodをCodd博士にかけたダジャレです。
データベース界では今も語り継がれる、世界一有名な駄洒落かもしれません。

💬 AIに聞いてみよう

ここまでの内容で疑問があれば、AIに質問してみましょう。たとえば:

  • 「第二正規化と第三正規化の違いが曖昧なので、別の伝票の例で説明して」
  • 「関数従属って何?中学生にもわかるように教えて」
  • 「自分たちのテーマは○○だけど、正規化の題材になりそうなデータはどれ?」
  • 「DBMSを使わない場合、正規化したデータをCSVファイルでどう持てばいい?」

まとめ(5分)

今回学んだことを一言でまとめると「内部設計は外部設計の実現方法を決める工程で、その第一歩が『1つの事実は1か所に』のための正規化」です。

  • 内部設計=外部設計をシステム内部でどう実現するかの仕様化
  • DBMSのメリット=アクセスの標準化、クエリによる高速化
  • 正規化=繰り返し排除(第一)→部分従属の分離(第二)→推移従属の分離(第三)
  • DBMS不使用チームも正規化は同じ。成果物がファイル設計書になるだけ

次のセッションでは、自分たちの情報モデル定義書のデータを実際に第三正規形まで正規化し、テーブル定義書を作ります。

🔄 振り返りチェック

以下の問いに答えられるか確認してみましょう:

  • 外部設計と内部設計の違いを、ユーザから見えるか見えないかの観点で説明できますか?
  • DBMSのメリットを2つ挙げられますか?
  • 注文票の例で、第一・第二・第三正規化がそれぞれ何をしたか説明できますか?
  • 正規化しないままデータを重複させると、どんな事故(更新時異常)が起きますか?

答えに自信がない場合は、該当部分を読み返すか、AIに質問してみてください。

補足資料

  • 参考リンク: 自チームで使うDBMS(または開発ツールのデータ機能)の公式ドキュメントの「データ型」のページを開いておくと次のセッションが楽になります
  • 発展課題: 学校の「時間割表」を非正規形とみなして、第三正規形まで正規化してみましょう。AIに答え合わせをしてもらいましょう

学習ガイド

このセクションは、受講者が理解を深めることをサポートする参考情報です。

想定される質問と回答例

質問 ヒント
正規化はどこまでやればいいの? 本研修では第三正規形まで。それ以上は実務でも稀。逆に性能のためにあえて崩す(非正規化)こともあるが、必ず第三正規形を作ってから判断する
主キーが見つからないときは? 行を一意に特定できる項目がなければ、連番(ID)を人工的に付与してよい。これをサロゲートキーと呼ぶ
DBMSを使うか使わないか、どう決める? チームの開発ツールがDBを内蔵していればそれを使う。静的サイト中心ならファイル(JSON/CSV)でもよい。どちらでも正規化の考え方は適用する
情報モデルとテーブルは同じもの? ほぼ対応するが、正規化の結果1つの情報モデルが複数テーブルに分かれることがある(注文→注文+注文明細)

つまずきやすいポイント

つまずきポイント ヒント
第二と第三の区別がつかない 第二は「主キーの一部」に依存する項目の分離(複合キーのときだけ起きる)。第三は「主キー以外の項目」に依存する項目の分離
何でも1つの大きな表に詰め込んでしまう 「この項目は何があれば決まる?」を1列ずつ問い、決め手が違う項目は別テーブルの候補
分割しすぎて訳がわからなくなる テーブル1つ=現実世界の「モノか出来事」1種類が目安。顧客・商品はモノ、注文はコト
繰り返し項目に気づけない 「同じ種類のデータがカンマ区切りや列1,列2,列3で並んでいないか」を探す
読み上げを開始します...

AIに質問する