Blog
本記事の目的
正規化のデメリットを理解し、メリットとデメリットを踏まえて、どのようにトレードオフしていくかについての方針を考えること。
正規化のデメリット
正規化のメリットとしては、冗長性を排除し、データの整合性を向上させることでした。
詳しくは過去の記事に詳細を記載しています。
一方、正規化にはデメリットが大きく2点あります。
では、詳しくみていきましょう。
デメリット① パフォーマンスの低下
正規化を行うことで、データの検索時に複数のテーブルを結合する必要が生じ、検索クエリの実行速度が低下する可能性があります。
特に読み込みが多いシステムではパフォーマンスが悪化する場合があります。
例) ECサイトの商品データ検索
products テーブル:商品名や価格などの基本情報を管理
id | name | price | category_id |
---|---|---|---|
001 | 机 | 30000 | 1 |
002 | 掃除機 | 10000 | 2 |
002 | 炊飯器 | 5000 | 2 |
categories テーブル:商品カテゴリー情報を管理
id | name |
---|---|
1 | 家具 |
2 | 家電 |
SELECT p.id, p.name, p.price
FROM products p
INNER JOIN categories c ON p.category_id = c.id
WHERE c.name = '家電';
正規化された構造では、複数のテーブルを結合する必要があります。この結合操作(JOIN)はデータ量が増えるほど負荷が高くなり、クエリの応答時間が遅くなる原因になります。
上記例では商品数が数千、数万となると、JOIN処理が検索結果のボトルネックになり、ユーザーが待たされる時間が増えてしまいます。
一方、非正規化の場合、productsテーブルの中に全てのカラムが入っているため、以下のように結合操作を行わず検索することができます。
非正規化
products テーブル:商品名や価格などの基本情報を管理
id | name | price | category_id | category_name |
---|---|---|---|---|
001 | 机 | 30000 | 1 | 家具 |
002 | 掃除機 | 10000 | 2 | 家電 |
002 | 炊飯器 | 5000 | 2 | 家電 |
SELECT id, name, price
FROM products
WHERE category_name = '家電';
と、このようになります。ただし、非正規化にはパフォーマンス面で別の問題もあります。
たとえば、カテゴリー名を変更する場合、該当する複数のレコードを更新しなければなりません。その結果、更新時のパフォーマンスに影響を与える可能性があります。
デメリット② クエリの複雑化
正規化が進むと、データを取得するためのクエリが複雑になります。複数のテーブルを結合する必要があるため、SQL文が長くなり、パフォーマンスに影響を与えるだけでなく、可読性も低下する可能性があります。
ただ、フレームワークが発達している近年では、正規化によるクエリの複雑化は、それほど大きなデメリットにはならないのでは?と個人的には思っています。
ORM(Object-Relational Mapping)の利用や、クエリビルダーの利用等によってデメリットは少し軽減されそうです。
終わり
これらのデメリットを踏まえた結果、基本的には第3正規化までは行いたいというのが個人的な感想です。
パフォーマンス以上に、保守性の向上、データの整合性の向上についてのメリットを大きく感じます。
非正規化を検討するタイミングとしては、
- 大規模データの高速検索が必要な場合
- 例:Webサーバーログのリアルタイム解析
- リアルタイム性が重視される場合
- 例:SNSのフィード表示等
- 高頻度な読み取りアクセス
- 例:ECサイトの商品レコメンドシステム(商品情報・カテゴリー情報・在庫情報・購入履歴などの複数テーブルデータが必要)
といったところでしょうか。よっぽどデータ検索のスピードが求められない限り、基本的には正規化を行うのが良いのではないかと思います。ただし、実装途中でデータベースの構成変更は改修コストが非常に高くつくため、設計段階で慎重に考えることが重要ですね:)
後々、思わぬ手間や問題に直面することになるかもしれません。。(これに関しては設計全般に言えることではありますが)
それでは、ここまでお付き合いいただきありがとうございました!
CONTACT
あくまでも本業がメインですが、休日や業務の隙間時間は個人でも動いております。
もしお手伝いできることがあれば、お気軽にお問い合わせください。