戦国IT - 情報処理技術者試験の過去問対策サイト
ブログお知らせお問い合わせ料金プラン

基本情報技術者 2023年 科目A06


問題文

次の関数従属を満足するとき、成立する推移的関数従属はどれか。ここで、“A→B”はBがAに関数従属していることを表し、“A→ {B, C}”は、“A→B”かつ“A→C”が成立することを表す。
〔関数従属〕 {注文コード, 商品コード} → {顧客注文数量, 注文金額} 注文コード → {注文日, 顧客コード, 注文担当者コード} 商品コード → {商品名, 仕入先コード, 商品販売価格} 仕入先コード → {仕入先名, 仕入先住所, 仕入担当者コード} 顧客コード → {顧客名, 顧客住所}

選択肢

仕入先コード → 仕入担当者コード → 仕入先住所
商品コード → 仕入先コード → 商品販売価格
注文コード → 顧客コード → 顧客住所(正解)
注文コード → 商品コード → 顧客注文数量

🔒 解説は解答すると表示されます

推移的関数従属【午前解説】

正解の理由

与えられた関数従属の中で、選択肢 (注文コード → 顧客コード → 顧客住所)が成立します。なぜなら「注文コード → 顧客コード」が成り立ち、さらに「顧客コード → 顧客住所」が成り立つので、推移性により「注文コード → 顧客住所」が導かれるからです。推移的関数従属は「A→B かつ B→C ならば A→C」として導出され、ここでの連鎖がそのまま当てはまります。

解法ステップ

  1. 与えられた関数従属を一覧化する。
  2. 各従属の右辺と左辺をつなぐ「連鎖(チェーン)」を探す。具体的には、ある属性集合Xについて X→Y があり、さらに Y→Z が存在するか確認する。
  3. 連鎖が見つかれば、X→Z が推移的に成立する。候補の選択肢がその形になっているか検証する。
  4. 連鎖の途中に示されている中間属性(Y)が、実際に次の従属の左辺になっていることを厳密に確認する(部分集合や合成キーの扱いに注意)。
簡潔に言うと「左→中」と「中→右」が両方存在すれば「左→右」が成立するかをチェックする、という手順です。

選択肢別の誤答解説

  • ア: 仕入先コード → 仕入担当者コード → 仕入先住所
    与えられた従属には「仕入先コード → 仕入担当者コード」と「仕入先コード → 仕入先住所」はあるが、「仕入担当者コード → 仕入先住所」は与えられていません。中間属性が次の左辺になっていないため、指定の連鎖は成立しません。
  • イ: 商品コード → 仕入先コード → 商品販売価格
    「商品コード → 仕入先コード」は成立しますが、「仕入先コード → 商品販売価格」は与えられていません。実際は商品販売価格は商品コードに直接依存している(商品コード → 商品販売価格)ため、仕入先コードを経由する連鎖にはなりません。
  • : 注文コード → 顧客コード → 顧客住所
    「注文コード → 顧客コード」と「顧客コード → 顧客住所」が与えられているため、推移的に「注文コード → 顧客住所」が導かれ、これが正しい選択です。
  • エ: 注文コード → 商品コード → 顧客注文数量
    与えられた関数従属に「注文コード → 商品コード」は存在しません。また、顧客注文数量は {注文コード, 商品コード} に依存しており(複合左辺)、商品コード単独からは導けません。従って連鎖は成立しません。

よくある誤解

  • 「A→B と B→C があれば必ず推移的従属」と短絡するが、問題文の選択肢で指示された中間属性(B)が実際に次の左辺になっているかを確認しないと誤答する。
  • 複合キー絡みの従属(例:{X,Y}→Z)を見て、X単独またはY単独でも同様に依存すると誤って判断する。複合左辺は単独属性では同じ意味を持たないことが多い。

補足コラム

データベースの正規化で「推移的関数従属」は第3正規形(3NF)の視点で重要です。ある非キー属性が別の非キー属性を介して主キーに依存している場合、冗長性や更新異常が生じやすく、テーブルを分割して非キー属性の連鎖を取り除くことが推奨されます。今回の例では「注文コード → 顧客住所」が推移的に成立するので、設計によっては顧客情報を注文テーブルから分離して顧客テーブルにまとめることで冗長性を減らせます。
小さなツール的確認として、属性閉包(属性集合 X の閉包 X+ を計算)を使うと網羅的に導出可能な属性が確認できます。例えば注文コードの閉包を計算すると顧客住所が含まれる、よって推移的従属があると判定できます。
例(属性閉包を簡易的に計算する Python スニペット):
fds = [
    (('注文コード','商品コード'), ('顧客注文数量','注文金額')),
    (('注文コード',), ('注文日','顧客コード','注文担当者コード')),
    (('商品コード',), ('商品名','仕入先コード','商品販売価格')),
    (('仕入先コード',), ('仕入先名','仕入先住所','仕入担当者コード')),
    (('顧客コード',), ('顧客名','顧客住所')),
]

def closure(attrs):
    attrs = set(attrs)
    changed = True
    while changed:
        changed = False
        for left, right in fds:
            if set(left).issubset(attrs) and not set(right).issubset(attrs):
                attrs |= set(right)
                changed = True
    return attrs

print(closure(('注文コード',)))
# 出力に '顧客住所' が含まれる -> 推移的従属成立

FAQ

Q. 推移的関数従属と直接の関数従属はどちらがより問題になる?
A. 正規化の観点では、非キー属性間の推移的従属が特に第3正規形の違反要因になりやすく、冗長性や更新・削除・挿入異常を引き起こします。直接従属も設計上重要ですが、推移的従属はテーブル分割で解消することが多いです。
Q. 「A→B」「B→C」なのに A→C が既に与えられている場合はどう扱う?
A. 推移的に導けるなら A→C は冗長な従属です。理論上は冗長性の除去(最小基底)で取り除けますが、実務では可読性や実装の都合で残すこともあります。
Q. 複合属性が絡むときの判定方法は?
A. 属性閉包(X+)を計算し、目的の属性が含まれるかで判定するのが確実です。手計算でも順を追って適用すれば判断できます。

関連キーワード: 関数従属、推移的従属、属性閉包、正規化、第3正規形
← 前の問題へこの年度をクイズで解く次の問題へ →
戦国ITクイズ機能

\ せっかくなら /

基本情報技術者
クイズ形式で学習しませんか?

クイズ画面へ遷移する

すぐに利用可能!

©︎2026 情報処理技術者試験対策アプリ

このサイトについてブログプライバシーポリシー利用規約特商法表記開発者について