VillageSQL is a drop-in replacement for MySQL with extensions.
All examples on this page work on VillageSQL. Install Now →
第一正規形 (1NF)
テーブルは、すべての列が原子的な値 (セルごとに 1 つの値) を保持し、繰り返しグループが存在しないとき、1NF にあります。 1NF に違反 — 1 つの列に複数の値が詰め込まれている:第二正規形 (2NF)
テーブルは、1NF にあり、かつすべての非キー列が主キーの一部ではなく主キー全体に依存しているとき、2NF にあります。これは複合主キーを持つテーブルにのみ当てはまります。 2NF に違反 —product_name は完全なキー (order_id, product_id) ではなく product_id にのみ依存している:
product_name を独自のテーブルに移動:
第三正規形 (3NF)
テーブルは、2NF にあり、かつどの非キー列も別の非キー列に依存していないとき、3NF にあります。こうした依存は推移的依存と呼ばれます。 3NF に違反 —city と state は customer_id に直接ではなく zip_code に依存している:
非正規化すべきとき
正規化は書き込みの整合性を高め、冗長性を減らしますが、読み取り時に結合のオーバーヘッドを加えます。読み取り中心や分析のワークロードでは、意図的な非正規化が正当化されることがあります。
非正規化の前にインデックスを確認してください。遅い結合の問題のほとんどは、インデックス不足の問題です。結合列にカバリングインデックスを追加するだけで十分なことがよくあります。MySQL のインデックスの仕組みを参照してください。
非正規化は、アプリケーションが書き込むのと同じテーブルではなく、リードレプリカや OLAP ストアで最もうまく機能します。
よくある質問
3NF より先に進む必要はありますか?
ほとんどのアプリケーションでは 3NF で十分です。Boyce-Codd 正規形 (BCNF) は、重なり合う候補キーが 3NF でもなお異常を許してしまうエッジケースに対処します。学術的な演習の外ではめったに生じない状況です。排除したい特定の異常がない限り、3NF で止めてください。パフォーマンスのために非正規化すべきですか?
再構築の前にプロファイルを取ってください。遅いクエリのほとんどは、結合ではなくインデックスの欠如が原因です。まずインデックスを追加してください。適切にインデックスされたクエリが大きなテーブルでなお遅いなら、トランザクション用のデータベースではなく、リードレプリカまたはマテリアライズドな集計テーブルでの非正規化を検討してください。2NF 違反と 3NF 違反の違いは何ですか?
2NF 違反は、主キーの一部に依存する列です (複合主キーでのみ起こり得ます)。3NF 違反は、別の非キー列に依存する列です。2NF は部分的なキー依存に関するもので、3NF は非キー列を介した推移的依存に関するものです。トラブルシューティング
関連項目
- MySQL のデータ型の選択 — スキーマを正規化した後に正しい型を選ぶ
- MySQL の外部キー — 正規化が生み出す関係を強制する
- MySQL の CHECK 制約 — 外部キーの整合性を超える追加のルール
- Sakila サンプルデータベース — 練習用の正規化されたスキーマ