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

データベーススペシャリスト 2016年 午前203


問題文

関係R(A, B, C)において、関数従属A→B, B→Cが成立するとき、導けない関数従属はどれか。

選択肢

{A, B, C} → {A, B}
{A, C} → {A, B}
{A, C} → {A, B, C}
{B, C} → {A, C}(正解)

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

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

正解の理由

与えられた関数従属は です。これらから推移律により が導け、さらに拡大律と分解律を用いると 、すなわち が成立します。一方で {B,C} が A を決定する根拠はありません。したがって選択肢({B, C}→{A, C})は導けない、すなわち正答です。

解法ステップ

  1. 与えられた関数従属性を整理する:
  2. 推移律(transitivity)を使う: から を得る。
  3. 拡大律(augmentation)で属性を付ける: から を得る。
  4. 分解律(decomposition)で右辺を分ける: から (および )を得る。
  5. 包含律(反射律/reflexivity)により、任意の集合はその部分集合を決定する: 例えば は自明に成立する。
  6. 上の手順で各選択肢の導出可否を判定する(属性閉包を用いるのが確実)。

選択肢別の誤答解説

  • ア: {A, B, C} → {A, B}
    包含律(反射律)により自明に成立します。任意集合はその部分集合を決定するため、{A,B,C}→{A,B} は真です。
  • イ: {A, C} → {A, B}
    を拡大律で右辺に C を付けて とし、分解律で を取り出せます。さらに包含律で も成立するため、{A,C}→{A,B} は導けます。
  • ウ: {A, C} → {A, B, C}
    上記の理由に加え、(包含律)と (拡大+分解)および (包含律)より が成立します。したがってウも導けます。
  • エ: {B, C} → {A, C}
    これを成立させるには (属性閉包)に A が含まれている必要があります。 を計算すると初期で {B,C} があり、 は既に C を含むため新しい属性を得られません。 は逆方向なので A を導けず、閉包に A は含まれません。従って {B,C}→{A,C} は導けません(選択肢が導けない)。

よくある誤解

  • 「ある属性集合がその部分集合を決定するのは拡大律で説明できる」と考える誤り。部分集合を決定する自明な関係は包含律(反射律)によるものであり、拡大律は X→Y から XZ→YZ を導く規則です。両者を混同しないこと。
  • 関数従属は双方向だと誤解する(X→Y が成り立つと Y→X も成り立つと誤認する)。方向性が重要で、逆は一般に成り立ちません。
  • 「右辺に属性があれば、その属性を含む任意の集合が左辺を決定する」と思う誤り。左辺の閉包に右辺が含まれるかをチェックする必要があります(属性閉包の計算が確実)。

補足コラム

属性閉包(X+)の計算は、与えられた関数従属集合の下で「ある属性集合が別の属性集合を決定するか」を判定する標準的手法です。手順は単純です:
  1. 初期集合を X+ に入れる。
  2. 既知の関数従属 Y→Z で Y⊆X+ となるものを見つけ、Z を X+ に追加する。
  3. 追加がなくなるまで 2 を繰り返す。
今回の例:
  • 計算 : 初期 {A} → より {A,B}、さらに より {A,B,C}。従って A は関係 R のキーになっています。
  • 計算 : 初期 {B,C} → は既に C を含むため何も増えず、。A は含まれません。
簡単な属性閉包の自動化例(参考、Python):
def closure(attrs, fds):
    closure = set(attrs)
    changed = True
    while changed:
        changed = False
        for left, right in fds:
            if set(left).issubset(closure) and not set(right).issubset(closure):
                closure |= set(right)
                changed = True
    return closure

fds = [("A","B"), ("B","C")]
print(closure("BC", fds))  # 出力: {'B','C'}
print(closure("A", fds))   # 出力: {'A','B','C'}

FAQ

Q. どの公理を優先して使えばよいですか?
A. まず包含律(自明な決定)と与えられた従属を確認し、属性閉包法で確実に判定するのが最も確実です。導出には拡大律(X→Y から XZ→YZ)と推移律(X→Y, Y→Z から X→Z)を必要に応じて使います。
Q. 「拡大律」と「包含律」はどこが違うのですか?
A. 包含律は「集合はその部分集合を決定する」という自明則です。拡大律は既に成立する従属に別の属性群を両辺に付けて新たな従属を作る規則で、両者は別の公理です。
Q. 実戦で素早く判定するコツは?
A. 属性閉包(X+)を瞬時に計算する習慣をつけること。主要な従属(キーになりうる属性)をまずチェックすると時間短縮になります。

関連キーワード: 関数従属、属性閉包、包含律、拡大律、推移律、分解律、アームストロング公理
← 前の問題へこの年度をクイズで解く次の問題へ →
戦国ITクイズ機能

\ せっかくなら /

データベーススペシャリスト
クイズ形式で学習しませんか?

クイズ画面へ遷移する

すぐに利用可能!

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

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