ボイス・コッド正規形(BCNF)とは?定義と具体例で学ぶデータベースの正規化
ボイス・コッド正規形(BCNF)とは
BCNF(Boyce-Codd Normal Form:ボイス・コッド正規形)は、第3正規形(3NF)を拡張した正規形であり、3NFよりもわずかに厳密な条件を満たす必要があります。そのため、「強い3NF」と呼ばれることもあります。
BCNFの定義
関係 R がBCNFに適合するのは、すべての非自明な関数従属 P → Q について、決定項 P が関係 R のスーパーキーであるときです。
関係がBCNFに適合していれば、関数従属に基づく冗長性は取り除かれたことを意味します。ただし、BCNFであってもすべての冗長性が消えるわけではなく、一部の冗長性は依然として残る可能性があります。
具体例:スポーツクラブの予約テーブル
次の <SportsClub> テーブルは、グラウンドごとの利用時間帯と、それに対応するパッケージ(料金プラン)を管理する例です。
| グラウンド(Ground) | 開始時刻(Begin_Time) | 終了時刻(End_Time) | パッケージ(Package) |
| G01 | 07:00 | 09:00 | Gold |
| G01 | 10:00 | 12:00 | Gold |
| G01 | 10:30 | 11:00 | Bronze |
| G02 | 10:15 | 11:15 | Silver |
| G02 | 08:00 | 09:00 | Silver |
この関係は1NF・2NF・3NFのいずれにも適合していますが、BCNFには適合していません。その理由を確認しましょう。
BCNF違反の原因
このテーブルには、{Package → Ground} という関数従属が存在します。これは「パッケージが決まれば、割り当てられるグラウンドも一意に決まる」という依存関係です。
しかし、この関数従属の決定項である Package 属性は、候補キーでも候補キーのスーパーセットでもありません。BCNFでは「すべての決定項はスーパーキーでなければならない」という条件があるため、この関数従属が違反となります。
BCNFへの分解
違反を解消するには、問題となっている関数従属を独立したテーブルとして切り出し、元のテーブルを二つに分解します。
<Package> テーブル
| パッケージ(Package) | グラウンド(Ground) |
| Gold | G01 |
| Silver | G02 |
| Bronze | G01 |
<TomorrowBookings> テーブル
| グラウンド(Ground) | 開始時刻(Begin_Time) | 終了時刻(End_Time) |
| G01 | 07:00 | 09:00 |
| G01 | 10:00 | 12:00 |
| G01 | 10:30 | 11:00 |
| G02 | 10:15 | 11:15 |
| G02 | 08:00 | 09:00 |
分解後の両テーブルは、いずれもBCNFに適合しています。
- <Package> テーブルの候補キー:「Package」「Ground」
- <TomorrowBookings> テーブルの候補キー:{Ground, Begin_Time} および {Ground, End_Time}
<Package> 関係で Package をキーとして扱ったことで、元のテーブルに存在していた更新時の異常(アノマリー)が解消されました。これにより、パッケージとグラウンドの対応関係を重複なく一元的に管理できるようになります。
-
第3正規形(3NF)とは?条件と変換例をわかりやすく解説
第3正規形(3NF)とは?データベースの正規化における第三段階が第3正規形(3NF:Third Normal Form)です。テーブルが3NFであるためには、次の2つの条件を満たす必要があります。リレーションが第2正規形(2NF)であること推移的関数従属が存在しないこと推移的関数従属とは、「A → B」「B → C」という依存関係から、間接的に「A → C」が導かれてしまう状態を指します。このような依存関係が残っていると、データの冗長性や更新時の不整合が発生しやすくなります。例:3NFに違反するテーブル次の <MovieListing> テーブルを見てみましょう。Movie_IDL
-
Djangoフォームウィジェットの使い方を徹底解説|Textareaで入力フォームをカスタマイズ
Djangoのフォームウィジェットとは? この記事では、Djangoフォームにおける「ウィジェット(widget)」の使い方について詳しく解説します。ウィジェットを活用すると、フロントエンドの見た目や操作性を大きく向上させることができます。 ウィジェットとは、DjangoフォームからHTMLとしてレンダリングされる要素のことです。テキストボックス(input)、テキストエリア(textarea)、パスワード入力欄(password input)など、フォームを構成するUI部品はすべてウィジェットに該当します。 事前準備:プロジェクトとアプリの作成 まずはDjangoプロジェクトとアプリを作成