完全関数従属(カンゼンカンウスウゾク)とは | 意味や読み方など丁寧でわかりやすい用語解説

完全関数従属(カンゼンカンウスウゾク)の意味や読み方など、初心者にもわかりやすいように丁寧に解説しています。

作成日: 更新日:

読み方

日本語表記

完全関数従属 (カンゼンカンウスウゾク)

英語表記

full functional dependency (フルファンクショナルディペンデンシー)

用語解説

「完全関数従属」とは、リレーショナルデータベースの設計において非常に重要な概念であり、データベースの正規化、特に第2正規化の理解に不可欠な基礎知識である。この概念を正しく理解することは、データベースに格納されるデータの品質を高め、冗長性を排除し、データの整合性を維持するために極めて重要となる。

まず、リレーショナルデータベースでは、情報をテーブル(リレーション)という形で管理する。各テーブルは、データを格納する行(レコード)と、データの種類を表す列(属性、フィールド)から構成される。それぞれのレコードを一意に識別するために、「主キー」と呼ばれる一つ以上の属性が設定される。例えば、顧客情報テーブルであれば「顧客ID」、商品情報テーブルであれば「商品コード」が主キーとなる。

ここで「関数従属」という概念を理解する必要がある。関数従属とは、ある属性(または属性の集合)Aの値が決まれば、それに対応する別の属性(または属性の集合)Bの値も一意に決まるという関係を指す。これは「AがBを決定する」と表現され、A → Bと表記される。例えば、「顧客ID → 顧客名」という関係は関数従属である。なぜなら、顧客IDが決まれば、それに紐づく顧客名も一意に決まるからだ。

「完全関数従属」は、この関数従属の中でも、特に複合主キーを持つテーブルにおいて重要な意味を持つ。複合主キーとは、複数の属性を組み合わせて主キーとする場合のことだ。例えば、ある注文の詳細情報を管理するテーブルで、「注文番号」と「商品コード」の二つの属性を組み合わせて、その注文の特定の商品に関する情報を一意に識別するようなケースが複合主キーの例である。

この複合主キー「(注文番号, 商品コード)」が決まれば、それに対応する「数量」が一意に決まる場合、「数量」は「(注文番号, 商品コード)」に対して完全関数従属していると言える。なぜなら、「注文番号」だけでは「数量」は決まらないし、「商品コード」だけでも「数量」は決まらない。これら二つの情報、つまり複合主キーのすべての属性が揃って初めて「数量」が決定されるからだ。このように、非キー属性(主キー以外の属性)が、そのテーブルの「複合主キーのすべての属性」にのみ関数従属している状態が、完全関数従属である。

これに対して、「部分関数従属」という状態も存在する。部分関数従属とは、非キー属性が「複合主キーの一部」にのみ関数従属している状態を指す。上記の注文詳細テーブルの例で考えてみよう。もしこのテーブルが「注文番号、商品コード、顧客名、商品名、数量、単価」という属性を持ち、複合主キーが「(注文番号, 商品コード)」であったとする。このとき、「顧客名」という非キー属性は「注文番号」が決まれば一意に決まるはずだ。つまり「注文番号 → 顧客名」という関数従属が存在する。しかし、「注文番号」は複合主キーの一部に過ぎない。このように、非キー属性が複合主キー全体ではなく、その一部によって決定される場合、それは部分関数従属である。同様に、「商品名」や「単価」は「商品コード」が決まれば一意に決まるため、「商品コード → 商品名」、「商品コード → 単価」という部分関数従属も存在することになる。

部分関数従属が存在する状態は、データベース設計において望ましくない。その理由は、データの冗長性(重複)が生じ、それに伴って「更新異常」という問題を引き起こすからだ。例えば、先の注文詳細テーブルで「商品名」が「商品コード」に部分関数従属している場合、同じ商品が複数の注文で利用されるたびに、その商品の「商品名」がテーブル内で何度も繰り返し格納されることになる。これは無駄なデータの重複であり、ストレージの浪費につながる。

さらに深刻なのは更新異常である。もしある商品の「商品名」が変更された場合、その商品が登場するすべての注文レコードを探し出して「商品名」を更新しなければならない。一つでも更新漏れがあれば、データベース内で同じ商品コードなのに異なる商品名が存在するというデータの不整合が生じてしまう(更新時不整合)。また、特定の注文が削除された際に、その注文にしか登場しない商品情報(商品名、単価など)も一緒に削除されてしまい、本来残すべき情報が失われる可能性もある(削除時不整合)。逆に、ある商品がまだどの注文にも使われていない場合、その商品の情報をデータベースに登録できないという問題も発生する(挿入時不整合)。

これらの問題を解決するために行われるのが「正規化」であり、特に第2正規化は部分関数従属を排除し、完全関数従属の状態を目指すプロセスである。第2正規化では、部分関数従属が存在する非キー属性を元のテーブルから分離し、独立した新しいテーブルを作成する。そして、分離されたテーブルには、その非キー属性を決定する主キーの属性を新しい主キーとして設定し、元のテーブルには新しいテーブルへの参照として外部キーを残す。

具体例で考えてみよう。 元のテーブル: 注文詳細テーブル 属性: (注文番号, 商品コード, 顧客名, 商品名, 数量, 単価) 複合主キー: (注文番号, 商品コード)

このテーブルには以下の関数従属が存在する。

  • (注文番号, 商品コード) → 数量 (これは完全関数従属)
  • 注文番号 → 顧客名 (これは部分関数従属)
  • 商品コード → 商品名 (これは部分関数従属)
  • 商品コード → 単価 (これも部分関数従属)

第2正規化のプロセスでは、部分関数従属を排除するためにテーブルを分解する。

  1. 注文番号 → 顧客名 の部分関数従属を排除するために、注文テーブルを作成する。

    • 注文テーブル: (注文番号, 顧客名)
    • 主キー: 注文番号 (ここでは注文番号が顧客を一意に識別できると仮定)
  2. 商品コード → 商品名 および 商品コード → 単価 の部分関数従属を排除するために、商品テーブルを作成する。

    • 商品テーブル: (商品コード, 商品名, 単価)
    • 主キー: 商品コード
  3. 元の注文詳細テーブルからは、部分関数従属していた「顧客名」「商品名」「単価」の属性を削除し、完全関数従属のみを残した注文商品テーブルとして再定義する。

    • 注文商品テーブル: (注文番号, 商品コード, 数量)
    • 複合主キー: (注文番号, 商品コード)

このようにテーブルを分解することで、以下のようなメリットが得られる。

  • 冗長性の排除: 「顧客名」や「商品名」「単価」が複数のレコードで重複して格納されることがなくなり、各情報はそれぞれ独立したテーブルで一度だけ管理される。
  • 更新異常の防止: 商品名や単価が変更された場合、商品テーブルの該当レコードを一度更新するだけで済むため、データの不整合を防ぎやすくなる。
  • 挿入異常の防止: まだどの注文にも使われていない新商品を、商品テーブルに直接登録できる。
  • 削除異常の防止: ある注文が削除されても、その注文に使われた商品の情報(商品名、単価)は商品テーブルに残るため、重要な商品情報が誤って失われることがない。

「完全関数従属」という概念は、このように効率的で堅牢なデータベースを設計するための基盤となる。システムエンジニアを目指す上で、どの属性がどの属性に依存しているのか、特に複合主キーを持つテーブルにおいて、非キー属性が主キーのどの部分に依存しているのかを正確に識別し、完全関数従属の状態を確保することは極めて重要である。これにより、データの整合性が保たれ、アプリケーションのパフォーマンス向上と保守性の向上にもつながるのだ。この考え方は、データベース正規化の基礎であり、より複雑な正規化(第3正規化、ボイス・コッド正規形など)を理解するための出発点でもある。

関連コンテンツ

完全関数従属(カンゼンカンウスウゾク)とは | 意味や読み方など丁寧でわかりやすい用語解説 | いっしー@Webエンジニア