シカラボ

データベースの正規化|表を分けると何が良くなるのか【ITパスポート】

シカラボ編集部
データベースの正規化|表を分けると何が良くなるのか【ITパスポート】

図書館の貸出記録を、1枚の表で管理しているとします。同じ本が何度も借りられるので、書名と著者が何度も出てきます。ここで著者名の表記を直すことになりました。直すべき行は何行あるでしょうか。その本が借りられた回数だけあります。1行でも見落とすと、同じ本なのに著者が違うという状態が残ります。これを起こさないための作業が正規化です。

図書館の貸出記録を1枚の表で管理している例。同じ書籍番号B01の行が3つあり、著者は「山田」が2行、4行目だけ「山口」になっている。同じ本の著者名が行ごとに書き写されるため、表記を直すときはB01の3行すべてを直す必要があり、4行目のように1行漏らすと食い違いが残ることを示している

正規化とは

過去問では、こう説明されています。

売上伝票のデータを関係データベースの表で管理することを考える。売上伝票の表を設計するときに、表を構成するフィールドの関連性を分析し、データの重複及び不整合が発生しないように、複数の表に分ける作業はどれか。

(出典:ITパスポート試験 令和元年秋期 問87)

正解は「正規化」です。

大事なところは3つあります。フィールドの関連性を分析すること、重複と不整合をなくすこと、そして複数の表に分けること。この3つを押さえておきましょう。

分けないと何が起きるのか

さきほどの貸出記録を、1枚の表のまま書いてみます。

貸出番号・会員番号・会員名・書籍番号・書名・著者・貸出日を1枚の表にまとめた図。同じ会員番号の行で会員名が、同じ書籍番号の行で書名と著者が、そのまま繰り返されていることを示している

たとえば同じ本を2人が借りると、書名と著者がそっくり同じ内容で2行に書かれます。同じ人が2回借りれば、会員名も2行に書かれます。ここから困りごとが出てきます。

  • 同じデータを何度も持つことになる——冗長性(同じ情報が、何か所にも重ねて置かれている状態)が生まれます
  • 直すときに漏れる——著者名を変えるなら、その本のすべての行を直す必要があります
  • 食い違いが生まれる——1行だけ直し忘れると、同じ書籍番号なのに著者が違うという状態になります

3つ目がいちばん厄介です。どちらが正しいのか、表を見ても判断できなくなります。**これが「不整合」**だと考えてみてください。

分けるとどうなるか

そこで表を3つに分けます。

貸出表・会員表・書籍表の3つに分割した図。貸出表は貸出番号・会員番号・書籍番号・貸出日を持ち、会員表は会員番号と会員名、書籍表は書籍番号と書名と著者を持つ。貸出表からそれぞれの番号で参照していることを矢印で示している
  • 貸出表: 貸出番号・会員番号・書籍番号・貸出日
  • 会員表: 会員番号・会員名
  • 書籍表: 書籍番号・書名・著者

書名と著者は書籍表に1行だけ、会員名は会員表に1行だけ置かれます。貸出記録の側は、番号だけを持ちます。

こうすると、著者名を直す場所は1か所だけになります。複数行の直し漏れによる食い違いを防ぎやすくなるわけです。必要なときは番号をたどって、表をつなげて読みましょう。このとき貸出表が持つ書籍番号は、書籍表の主キーを参照する外部キーにあたります。

どこで切るか——「何が決めているか」を見る

分ける位置に迷ったら、その項目を決めているのはどの番号なのかを問い直してみてください。

項目決めているのは置き場所
会員名会員番号会員表
書名書籍番号書籍表
著者書籍番号書籍表
貸出日貸出番号貸出表

**その項目を決めている番号を主キーにした表に置く。**これが切り分けの基本になります。

貸出日が貸出表に残るのも、同じ理屈です。貸出日を決めているのは貸出番号だからです。「そのつど変わるから残る」のではありません。

決めている番号が2つ以上見つかることもあります。会員名は会員番号で決まりますが、貸出番号が分かれば会員番号も分かるので、たどれば貸出番号でも決まります。そういうときは、より直接決めているほう——ここでは会員番号を選びます。たどって決まるほうを選ぶと、分けていない状態に戻ってしまいます。

この例で置いている前提:1冊の本につき著者は1人とします。著者が複数いる本を扱うなら、著者の側にも表を用意する設計が必要になります。

試験でのポイント: ITパスポートでは正規形の名前までは問われません。「その項目は、どの番号が分かれば決まるか」を1つずつ確かめる——ここで扱っている、1つの番号で決まる形の問題はこれで解けます。

ただし決めているのが番号1つとは限りません。令和5年の問59を見てください。設問は「一人の会員が複数の店舗に登録した場合は、会員番号を店舗ごとに付与する」と断っています。すると会員名を決めるのは会員番号だけでは足りず、(店舗コード、会員番号)の組になります。正解も、その2つをそろって主キーにした表でした。

**「どの番号が」ではなく「何が分かれば決まるか」**と読み替えてみてください。組になる形にも当てはめられます。

試験ではこう出る

まずは、目的を問う形からどうぞ。

腕試し問題

出典:ITパスポート試験 平成31年春期 問92

関係データベースを構築する際にデータの正規化を行う目的として、適切なものはどれか。

解答と解説

解説(解答せずに開けます)

正解はです。

正答の理由

正規化がなくすのは重複と矛盾で、その結果として維持管理が楽になります。著者名を直す場所が1か所で済む、という話がまさにこれにあたります。

誤答の解説

  • ❌ ア「データに冗長性をもたせて、データ誤りを検出する」→ 逆向きです。誤り検出のために冗長性を持たせる手法はありますが、正規化は冗長性を減らすほうに働きます
  • ❌ ウ「文字コードを統一して…」→ 文字コードの統一は正規化とは別の話です
  • ❌ エ「データを可逆圧縮して…」→ 圧縮もしません

ポイント

  • キーワードは「重複」「矛盾」「維持管理」
  • 「圧縮」「暗号化」「誤り検出」が出てきたら、いずれも正規化ではありません

もう1問、実際に分けてみる形を確かめておきましょう。

腕試し問題

出典:ITパスポート試験 令和6年度 問81

一つの表で管理されていた受注データを、受注に関する情報と商品に関する情報に分割して、正規化を行った上で関係データベースの表で管理する。正規化を行った結果の表の組合せとして、最も適切なものはどれか。ここで、同一商品で単価が異なるときは商品番号も異なるものとする。また、発注者名には同姓同名はいないものとする。

解答と解説

解説(解答せずに開けます)

正解はです。

正答の理由

この記事のやり方をそのまま当てはめます。商品番号が決めているものはどれでしょうか。商品名単価です(問題文に「同一商品で単価が異なるときは商品番号も異なる」と書かれているので、単価は商品番号で決まります)。この2つが商品表に移ります。

いっぽう個数を決めているのは、商品番号ではなくその受注です。だから受注表に残ります。

結果として、受注表は(受注番号, 発注者名, 商品番号, 個数)、商品表は(商品番号, 商品名, 単価)になります。

誤答の解説

  • ❌ ア「受注表に商品番号がない」→ 2つの表をつなげられません。どの受注がどの商品なのか分からなくなります
  • ❌ イ「商品表に個数がある」→ 個数は商品番号が決めている値ではありません
  • ❌ ウ「受注表に単価がある」→ 単価は商品番号で決まるので、受注表に残すと単価の重複と更新時の不整合が残ります。商品名は分けられているものの、正規化としては不十分です

ポイント

  • 「商品番号が決めているか」だけで仕分けられます
  • 個数と単価の扱いが分かれ目。個数は受注側、この問題では単価は商品側です(設問が「同一商品で単価が異なるときは商品番号も異なる」と断っているため)。この但し書きが無ければ、売ったときどきで決まる単価は受注側に残ります

まとめ

  • 正規化は、重複と不整合が起きないように、表を複数に分ける作業
  • 分けないと、冗長性・直し漏れ・食い違いが起きる
  • 切り分けの基本は「その項目を決めているのはどの番号か
  • **その番号を主キーにした表に置く。**元の表に残る項目も、元の表の番号が決めているから残る
  • 表どうしは、外部キーから相手の主キーを参照してつなぐ

分割の問題は、項目を1つずつ「何が分かれば決まるか」に当てはめてみてください。決めているものが番号1つのことも、番号の組のこともあります。手が止まらなくなります。

この記事のタグ

関連記事