5-2 非正規化とパフォーマンス
正規化とSQLパフォーマンスのトレードオフは重要なため、別の角度からも考えてみる
それは、冗長性を排除した結果、SQLパフォーマンスが悪化すること
パフォーマンス悪化の問題は、SQL構文の観点で見ると、2パターンある
1つ目は、サマリデータの冗長性排除
2つ目ま、選択条件の冗長性排除
サマリデータの冗長性とパフォーマンス
1対多のテーブルがあったとする
https://scrapbox.io/files/68776c06836efdb4fc082afc.jpg
再び、結合はパフォーマンスの敵
受注日ごとにいくつの注文があるか集計したいとする
2つのテーブルを結合すれば良いだけではあるが、実際の業務だと多くのレコードが作成される。特に受注詳細
こういった大きなテーブル同士を結合させることはパフォーマンスの悪化
結合しないSQLを作るためのテーブル設計
上記の問題を解決するにはどうしたら良いか
それは受注テーブルに商品数カラムを追加すること
だだしこれは、非正規化の一種
{受注ID}→{受注日}→{商品数}
このような推移的関数従属があるため、第3正規化できていないことになる
これは更新時における問題を抱えることになるが、それ以上にパフォーマンスを優先するなら良い手段
選択条件の冗長性とパフォーマンス
1対多のテーブルがあったとする
https://scrapbox.io/files/68776c06836efdb4fc082afc.jpg
受注日が1/6〜1/7の期間に、注文された商品の一覧を見たいとする
これをするには、もちろん結合するしかない
選択条件が冗長でないことの問題点
上記は、テーブルのレコード数が多いテーブル同士を結合するので、パフォーマンスが悪化しがち
問題の解決策は、受注明細テーブルに受注日カラムを追加すること
選択条件を冗長にすると第2正規化ではなくなる
{受注ID}→{受注日}の部分関数従属になってしまったため、第2正規化を満たせなくなる
実際の開発現場で、パフォーマンスによる非正規化まで考慮された設計は、そう多くはない
なぜなら、正規化は教科書的にできるが、非正規化はそうではないから