正規化は「表をきれいに分ける作法」ではなく、同じ事実を1か所にだけ置くための操作です。1つの表に何もかも詰め込むと、同じ事実が何行にも散り、片方だけ直して矛盾する(更新時異常)。だから分ける。そして分けた表どうしを外部キーでつなぎ直した設計図がE-R図です。試験で問われるのは「どこまで分けたか(正規形)」と「どちらが多か(多重度)」の2点に集約されます。
関係データベースの表は行の集まりで、行を1本に特定する列(の組)が主キーです。正規化は「主キーが決まれば、その行の他の列が自動的に決まる」状態(=関数従属が主キーからだけ伸びる状態)に近づける作業。逆に言えば、主キー以外の列が別の列を決めてしまう形が残っていると、そこが冗長=異常の発生源になります。
なぜ正規化するか ― 更新時異常
受注を1枚の表にまとめた例です。同じ商品の名前と単価が何行にも複製されています。
| 受注番号 | 受注日 | 顧客番号 | 顧客名 | 顧客住所 | 商品番号1 | 商品名1 | 単価1 | 数量1 | 商品番号2 | 商品名2 | 単価2 | 数量2 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 1001 | 04-01 | C01 | 山田商事 | 東町1-1 | P10 | A型ケース | 1,200 | 3 | P20 | B型カバー | 800 | 1 |
| 1002 | 04-02 | C02 | 青木物産 | 西町2-2 | P10 | A型ケース | 1,200 | 5 | (空) | (空) | (空) | (空) |
| 1003 | 04-03 | C01 | 山田商事 | 東町1-1 | P10 | A型ケース | 1,250 | 2 | P30 | C型台座 | 500 | 1 |
3行目だけ単価が1,250になっています。どちらが正しいのか、この表からは決められません。これが更新時異常です。1つの事実(P10の単価)が複数の場所に散っていると、更新はその全部に届かなければならず、1か所でも漏れれば矛盾が残る。ほかにも挿入時異常(受注がまだ無い新商品を登録できない)、削除時異常(最後の受注を消すと商品の情報まで消える)が同じ原因から起きます。「同じ値が何度も現れる列」を本文の表から見つけたら、そこが分割対象です。
第1〜第3正規形 ― 同じ表がどう分かれるか
- 第1正規形(1NF)=繰返し項目をなくす。「商品1・商品2…」と横に並べた列を、行方向に展開する。1つのマスには1つの値だけ。
- 第2正規形(2NF)=部分関数従属をなくす。主キーが複数列の組のとき、その一部だけで決まる列を別表に出す。
- 第3正規形(3NF)=推移的関数従属をなくす。主キー以外の列がさらに別の列を決めている関係を別表に出す。
| 受注番号 | 商品番号 | 受注日 | 顧客番号 | 顧客名 | 顧客住所 | 商品名 | 単価 | 数量 |
|---|---|---|---|---|---|---|---|---|
| 1001 | P10 | 04-01 | C01 | 山田商事 | 東町1-1 | A型ケース | 1,200 | 3 |
| 1001 | P20 | 04-01 | C01 | 山田商事 | 東町1-1 | B型カバー | 800 | 1 |
| 1002 | P10 | 04-02 | C02 | 青木物産 | 西町2-2 | A型ケース | 1,200 | 5 |
繰返しは消えましたが、まだ重複が残っています。受注日と顧客は受注番号だけで決まり、商品名と単価は商品番号だけで決まる。つまり主キーの一部だけで決まる列(部分関数従属)が混ざっている状態です。
| 受注番号 | 受注日 | 顧客番号 | 顧客名 | 顧客住所 |
|---|---|---|---|---|
| 1001 | 04-01 | C01 | 山田商事 | 東町1-1 |
| 1002 | 04-02 | C02 | 青木物産 | 西町2-2 |
| 1003 | 04-03 | C01 | 山田商事 | 東町1-1 |
| 受注番号 | 商品番号 | 数量 |
|---|---|---|
| 1001 | P10 | 3 |
| 1001 | P20 | 1 |
| 1002 | P10 | 5 |
| 商品番号 | 商品名 | 単価 |
|---|---|---|
| P10 | A型ケース | 1,200 |
| P20 | B型カバー | 800 |
単価の重複は消えました。ただし受注表には、受注番号→顧客番号→顧客名・顧客住所という玉突きの従属(推移的関数従属)が残っています。顧客が引っ越したら受注行を全部直すことになる。
| 受注番号 | 受注日 | 顧客番号 |
|---|---|---|
| 1001 | 04-01 | C01 |
| 1002 | 04-02 | C02 |
| 1003 | 04-03 | C01 |
| 顧客番号 | 顧客名 | 顧客住所 |
|---|---|---|
| C01 | 山田商事 | 東町1-1 |
| C02 | 青木物産 | 西町2-2 |
「2NFは部分従属、3NFは推移従属」を丸暗記すると、設問の表で判定できません。手順にすると簡単です。①主キーを確定する→②各列について『この列は主キー全体がないと決まらないか』を1つずつ問う。主キーの一部だけで決まるなら2NF違反、主キーでない列から決まるなら3NF違反。判定の入口は常に主キーの確定で、ここを間違えると全部ずれます。なお、単一列が主キーの表には「主キーの一部」が存在しないので、1NFなら自動的に2NFです。
主キー・候補キー・外部キー・参照整合性
行を一意に決める側
- 候補キー:行を一意に決められる列(の組)で、余分な列を含まないもの。複数あってよい(例:商品番号と、商品の型番)。
- 主キー:候補キーの中から1つ選んだもの。空値(NULL)にできず、重複もできない。
- 複合キー:2列以上の組で一意になる主キー(明細表の 受注番号+商品番号)。
他の表を指す側
- 外部キー:他の表の主キーを指す列。値は参照先に実在するか、空値のどちらかでなければならない。
- 参照整合性:「指した先が必ずある」状態を保つ制約。存在しない顧客番号の受注は登録できない。
- 削除時の扱い:参照されている顧客を消そうとしたら、拒否する/連動して受注も消す/外部キーを空にするのいずれか。設問では「どれを選ぶと業務上まずいか」が問われる。
顧客名/顧客住所
受注日/顧客番号(外部キー)
数量
商品名/単価
E-R図の読み方 ― 多重度の向きを外部キーで決める
エンティティ=表になるもの(顧客・受注・商品)、関連=エンティティ間の線、多重度=その線の両端が「1」か「多」かの印です。
関連の向きを迷ったら、外部キーを持っている側が「多」と覚えます。受注表が顧客番号を持つ=顧客1に対し受注が多。1件の顧客番号は受注表の何行にも現れられるが、1本の受注行が持てる顧客番号は1つだけだからです。設問で「未記入の多重度を答えよ」と問われたら、その表の列に相手の主キーが入っているかどうかを見に行けば決まります。文章から読むときは両方向で言い切ってみるのも有効です(「1人の顧客は複数の受注をする/1件の受注は1人の顧客のもの」=1対多)。
多対多はそのままでは表にできません。受注と商品は多対多ですが、間に「明細」という表(連関エンティティ)を置き、両側の主キーを外部キーとして持たせて複合主キーにすることで1対多×2に分解します。E-R図に多対多が残っていたら、そこに表が1枚増えるサインです。設問の「追加すべきエンティティを答えよ」はほぼこの形。
急所 ― 非正規化と集計表
非正規化はトレードオフ
- 正規化を進めるほど表が増え、参照は結合の回数が増えて遅くなる。
- そこであえて冗長に持つ(受注時点の単価を明細に写す、合計金額を持つ)のが非正規化。
- ただし更新時異常のリスクが戻ってくる。「速さを買って整合性を自分で守る義務を負う」取引だと理解する。
- ★受注時点の単価を明細に持つのは冗長ではない場合がある。商品表の単価は「現在の単価」、明細の単価は「その時いくらで売ったか」で別の事実だから。設問で頻出の引っかけ。
集計表の主キーは集計軸
- 月次の売上集計のような表では、何を単位に集めたか(集計軸)がそのまま主キーになる。
- 「商品別・月別の売上」なら主キーは商品番号+年月。1つの軸を落とすと行が重複して一意でなくなる。
- 逆に、問題文の集計表の見出しから軸を数えれば主キーの列数が決まる。空欄補充はここで解ける。
- 集計値(合計・件数)は元表から導けるので、主キーには絶対に入らない。
データベースの設問は、業務の説明文を読んで表とE-R図に写せるかを測っています。だから問われ方は毎年ほぼ同じ形をとります――(1)未完成のE-R図の多重度や関連線を埋める、(2)表の主キー・外部キーに下線を引く、(3)業務の追加要件(履歴を残す・複数担当を許す)に対しどの表を足すかを答える。(3)はいずれも「1つのマスに複数の値を入れたくなったら表を分ける」という1NFの原則の応用です。要件が『複数の…』と言った瞬間に、表が1枚増えると身構えられれば、その場で解けます。
この仕組みを使う設問
- H31春 AP 問6薬剤管理システムのデータベース設計
- R01秋 AP 問6健康応援システムのデータベース
- R02秋 AP 問6データベース(宿泊予約システム)
- R03春 AP 問6データベース(SQL・E-R・多次元モデル)
- R03秋 AP 問6データベース(E-R図・SQL・トランザクション)
- R03秋 AP 問8情報システム開発(データ中心設計)
- R04春 AP 問6クーポン発行サービスのデータベース設計
- R04秋 AP 問6自動車メーカーJ社が全従業員へ配布するスマートデバイス
- R05春 AP 問6KPI達成状況集計システムの開発
- R05秋 AP 問6在庫管理システムの改修(E-R図とSQL)
- R06春 AP 問6人事評価SaaSのマルチテナント化
- R06秋 AP 問6トレーディングカードの個人間売買サイトをS社が新規構築
- R07春 AP 問6釣り具販売のH社が
- R07秋 AP 問6英会話オンライン教育のD社が受講管理システムを改修