第3の正規形(3NF)は、第1正規形(1NF)および第2正規形(2NF)によって提供されるデータベース正規化原則に基づいてデータの完全性をサポートするデータベース原則です。
第3の標準的なフォーム要件
データベースを3番目の正規形にするための基本的な要件は2つあります。
- データベースは、すでに1NFと2NFの両方の要件を満たしている必要があります 。
- すべてのデータベース列はプライマリキーに依存していなければなりません。つまり、プライマリキーのみから列の値を派生させることができます。
主キー依存について
すべての列が主キーに依存していなければならないということを意味します。
列の値を主キーと表の別の列の両方から派生させることができれば、3NFに違反します。 次の列を持つEmployees表を考えてみます。
- 従業員ID
- ファーストネーム
- 苗字
LastNameとFirstNameの両方がEmployeeIDの値だけに依存していますか? さて、LastNameはファーストネームに依存していますか? LastNameに固有の何もFirstNameの値を示唆するものではないからです。 FirstNameはLastNameに依存できますか? LastNameが何であっても、FirstNameの値についてのヒントは得られませんでした。 したがって、この表は3NFに準拠しています。
しかし、このVehiclesテーブルを考えてみましょう:
- VehID
- メーカー
- モデル
メーカーとモデルはVehicleIDから派生する可能性がありますが、モデルは特定のメーカーのみが作成するため、製造元から派生する可能性もあります。 このテーブル設計は非3NFに準拠しているため、データの異常が発生する可能性があります。 たとえば、モデルを更新せずに製造元を更新し、不正確さを導入する場合があります。
これを準拠させるには、追加の従属列を別の表に移動し、外部キーを使用して参照する必要があります。 これは2つのテーブルになります:
車両テーブル
以下の表では、ModelIDはModelsテーブルの外部キーです。
- VehID
- メーカー
- ModelID
モデル表
この新しいテーブルは、モデルをメーカーにマップします。 モデル固有の車両情報を更新する場合は、Vehiclesテーブルではなく、このテーブルで行います。
- ModelID
- メーカー
- モデル
3NFモデルの派生フィールド
表には、表の他の列に基づいて計算された派生フィールドが含まれている場合があります。 たとえば、このウィジェットの注文の表を考えてみましょう。
- 注文番号
- 顧客番号
- 単価
- 量
- 合計
3NF準拠は、プライマリキーに完全に依存するのではなく、単価に数量を掛けて導き出すことができるため、合計は3NF準拠を破ります。 私たちはテーブルからそれを取り除いて、3番目の正規形に準拠させる必要があります。
実際、それは導出されているので、データベースにまったく格納しないほうがよいでしょう。
データベースクエリを実行するときに、「オンザフライ」で単純に計算することができます。 たとえば、以前このクエリを使用して注文番号と合計を取得していたとします。
SELECT OrderNumber、WidgetOrdersからの合計次のクエリを使用できるようになりました。
SELECT OrderNumber、UnitPrice * Quantity AS合計WidgetOrdersからの合計正規化ルールに違反することなく同じ結果を達成できます。