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?

【DB設計】応用情報 H18年春問62【解説】

0
Posted at

問題

次のような繰返し構造をもったレコードからなるデータを、第3正規形に正規化したものはどれか。ここで、下線部分は主キーを表す。また、単位と単価は商品コードごとに決まるものとする。
元のレコード構造:
伝票番号(PK)、日付、顧客コード、顧客名、住所、【繰返し:商品コード、単位、数量、単価】
出典:応用情報技術者試験 平成18年春期 午前問62

※この記事では、主キーを (PK) と表記します。

結論

正解は 「イ」 です。

第3正規形となっているのは以下の構成です。

  • 伝票: 伝票番号(PK), 日付, 顧客コード
  • 顧客: 顧客コード(PK), 顧客名, 住所
  • 明細: 伝票番号(PK), 商品コード(PK), 数量
  • 商品: 商品コード(PK), 単位, 単価

「1つの事実は1箇所にだけ書く」、伝票の発行日は親である伝票テーブルにのみ記載して、明細側は「伝票番号と商品コード」だけで管理する。
これにより、どんなにデータが増えても矛盾が起きないDB設計になります。

解説

❌ 選択肢「エ」がNGな理由:

部分関数従属が残っているため(第1正規形止まり)

  • 伝票: 伝票番号(PK), 日付, 顧客コード, 顧客名, 住所
  • 明細: 伝票番号(PK), 商品コード(PK), 単位, 数量, 単価

パッと見は綺麗ですが、明細テーブルに問題があります。
明細テーブルの主キーは「伝票番号 + 商品コード」の複合キーです。
しかし、問題文に「単位と単価は商品コードごとに決まる」とある通り、
この2つは伝票番号には無関係です。
この状態(部分関数従属)を放置すると、「商品の単価が変わった時、過去の明細データまで全部書き直すか、矛盾が発生する」というデータ異常が起きるのでNG。

❌ 選択肢「ウ」がNGな理由:

推移的関数従属が残っているため(第2正規形止まり)

  • 伝票: 伝票番号(PK), 日付, 顧客コード, 顧客名, 住所
  • 明細: 伝票番号(PK), 商品コード(PK), 数量
  • 商品: 商品コード(PK), 単位, 単価

伝票テーブルの中にある「顧客名」と「住所」は、伝票番号に直接従属しているのではなく、「顧客コード」が分かれば決まる項目です。
この状態(推移的関数従属)を放置すると、「まだ一度も伝票を発行していない新規顧客の、名前と住所だけを登録しておくことができない」という不都合が生じるためNG。

❌ 選択肢「ア」がNGな理由:

主キーの制約がガバガバになるため(致命的な罠)

  • 伝票: 伝票番号(PK), 顧客コード
  • 顧客: 顧客コード(PK), 顧客名, 住所
  • 明細: 伝票番号(PK), 日付(PK), 商品コード(PK), 数量
  • 商品: 商品コード(PK), 単位, 単価

一見すると全ての項目が分散されて綺麗に見えますが、
明細テーブルの複合主キーに「日付」を追加してしまっている点が最大のバグです。

主キーが担う「重複を許さない(一意性制約)」というルールは、
構成する項目が増えるほど条件がゆるくなります。
もし { 伝票番号, 日付, 商品コード } を主キーにしてしまうと、
システム上は以下のようなデータ登録を許してしまいます。

  • { 伝票001, 6月21日, りんご }
  • { 伝票001, 6月22日, みかん }

現実の業務において、「1枚の伝票(レシート)の中に、違う日付の買い物が混ざる」ことはあり得ないので、この設計はNGです。

まとめ

正規化の選択肢で迷ったら、「そのテーブル構成でシステムを作った時、どんなあり得ないデータが登録できてしまうか?」という事実ベースの極端なテストケース(例:同じ伝票で別の日付を入れる等)を想像すると、正解を導き出しやすいです。

db_kako.png

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?