データベースの整合性を守る Boyce-Codd 正規形 (BCNF) とは?
Boyce-Codd 正規形 (BCNF) の分かりやすい解説
BCNF は、以下の条件を満たす関係 (テーブル) を指します。
- すべての属性が主キーに部分的にまたは完全に決定される。
- 推移的依存関係が存在しない。
主キー は、関係内のレコードを一意に識別する属性の集合です。部分的に決定される とは、主キーの一部によって属性が決定されることを意味します。推移的依存関係 とは、ある属性 A が属性 B を決定し、属性 B が属性 C を決定する場合、A が C を決定する関係を指します。
BCNF の重要性
BCNF を満たす関係は、以下の利点があります。
- データの冗長性がない:同じデータが複数の場所に存在しないため、データの更新や削除が容易になる。
- データの矛盾がない:異なる属性値が同じ意味を表すことがないため、データの整合性が保たれる。
- 更新アノマリが発生しない:一部のデータを更新した際に、他のデータが矛盾してしまうことがない。
BCNF への変換
関係が BCNF を満たしていない場合、以下の方法で BCNF に変換することができます。
- 分解:関係を複数の関係に分割する。
- 主キーの変更:主キーを変更することで、すべての属性が主キーに決定されるようにする。
BCNF の例
以下は、BCNF を満たす関係と満たさない関係の例です。
BCNF を満たす関係
社員(社員番号, 氏名, 部署コード)
部署(部署コード, 部署名)
この関係では、すべての属性が主キー (社員番号) に決定されます。
注文(注文番号, 顧客番号, 商品コード, 数量)
この関係では、属性 "数量" は主キー (注文番号, 顧客番号) に決定されますが、属性 "商品コード" は主キーに決定されません。
BCNF は、データベースの整合性を保つための重要な正規形です。BCNF を理解することで、データの冗長性と矛盾をなくし、データの品質を向上させることができます。
Boyce-Codd 正規形 (BCNF) のサンプルコード
# 社員テーブル
class Employee:
def __init__(self, employee_id, name, department_code):
self.employee_id = employee_id
self.name = name
self.department_code = department_code
# 部署テーブル
class Department:
def __init__(self, department_code, department_name):
self.department_code = department_code
self.department_name = department_name
# サンプルデータ
employees = [
Employee(1, "山田太郎", "営業部"),
Employee(2, "佐藤花子", "開発部"),
Employee(3, "田中一郎", "経理部"),
]
departments = [
Department("営業部", "Sales"),
Department("開発部", "Development"),
Department("経理部", "Accounting"),
]
このコードでは、Employee
と Department
という 2 つのクラスが定義されています。
Employee
クラスは、社員の情報を表すクラスです。属性は以下のとおりです。
employee_id
: 社員番号 (主キー)name
: 氏名department_code
: 部署コード
このコードでは、Employee
クラスのすべての属性は主キー employee_id
に決定されます。また、Department
クラスのすべての属性は主キー department_code
に決定されます。
# 注文テーブル
class Order:
def __init__(self, order_id, customer_id, product_code, quantity):
self.order_id = order_id
self.customer_id = customer_id
self.product_code = product_code
self.quantity = quantity
# サンプルデータ
orders = [
Order(1, 100, "A001", 10),
Order(2, 101, "A002", 20),
Order(3, 100, "A003", 30),
]
このコードでは、Order
というクラスが定義されています。属性は以下のとおりです。
customer_id
: 顧客番号product_code
: 商品コードquantity
: 数量
このコードでは、属性 quantity
は主キー order_id
に決定されますが、属性 product_code
は主キーに決定されません。
BCNF を満たす関係は、データの冗長性と矛盾をなくし、データの品質を向上させることができます。サンプルコードを参考に、BCNF の理解を深めてください。
Boyce-Codd 正規形 (BCNF) への変換方法
分解
最も一般的な方法は、関係を複数の関係に分割することです。関係を分割する際には、以下の点に注意する必要があります。
- 分割後の関係はすべて BCNF を満たす必要がある。
- 分割前の関係のすべての情報が、分割後の関係に保持される必要がある。
以下は、分解による BCNF への変換例です。
元の関係
注文(注文番号, 顧客番号, 商品コード, 数量)
分割後の関係
注文(注文番号, 顧客番号)
注文明細(注文番号, 商品コード, 数量)
元の関係では、属性 "商品コード" は主キーに決定されません。そのため、この関係を以下の 2 つの関係に分割します。
- 注文: 注文番号と顧客番号のみを含む関係
- 注文明細: 注文番号、商品コード、数量を含む関係
主キーの変更
注文(注文番号, 顧客番号, 商品コード, 数量)
注文(顧客番号, 商品コード, 注文番号, 数量)
上記の 2 つの方法以外にも、以下の方法があります。
- 擬似属性の導入:主キーに決定されない属性を擬似属性として導入し、BCNF を満たすようにする。
BCNF を満たしていない関係を BCNF に変換するには、いくつかの方法があります。どの方法を選択するかは、関係の構造やデータの性質によって異なります。
database database-normalization bcnf