今日はもう一度、しかももっと詳しく、超大事なテーマ「正規化のメリットとデメリット」について話すよ。これで現実世界でどう使われてるか、もっと分かるはず!じゃあ、シートベルト締めて、始めよう!
データの冗長性をなくす
テーブルのデータが正規化されてないと、同じ情報がいろんな行で何回も出てくることがあるんだ。例えば、注文テーブルで、注文ごとにお客さんの住所が毎回書かれてたり。正規化すると、こういう重複データを別のテーブルに分けて、スッキリさせることができるよ。
例:
-- 正規化前
CREATE TABLE orders (
order_id SERIAL PRIMARY KEY,
customer_name TEXT,
customer_address TEXT,
order_date DATE
);
-- 正規化後
CREATE TABLE customers (
customer_id SERIAL PRIMARY KEY,
customer_name TEXT,
customer_address TEXT
);
CREATE TABLE orders (
order_id SERIAL PRIMARY KEY,
customer_id INT REFERENCES customers(customer_id),
order_date DATE
);
なんでこれが大事なの?重複データが少ないと、ミスも減るんだ。もしお客さんの住所が変わったら、1ヶ所だけ直せばOK!
データの整合性を保つ
データを論理的なテーブルに分けると、テーブル同士の関係を管理しやすくなるよ。外部キーを使えば、データの整合性も自動で守れる。例えば、注文テーブルに紐づいてるお客さんをうっかり消しちゃう、みたいなことが起きなくなる。
例:
-- 外部キーでお客さんを消したら関連する注文も消えるようにする
ALTER TABLE orders
ADD CONSTRAINT fk_customer FOREIGN KEY (customer_id)
REFERENCES customers(customer_id)
ON DELETE CASCADE;
これで「孤児データ」が発生しないって安心できるよね。
更新がラクになる
データベースが正規化されてると、更新作業がめっちゃラクでミスも減る。さっきのお客さんの例だと、住所が変わったら1つのテーブルだけ直せばいい。正規化されてないと、いろんな行を直し忘れてデータがバラバラになっちゃうかも。
異常(アノマリー)の最小化
挿入アノマリー:正規化されてないテーブルだと、余計な情報がないと新しいデータを追加できないことがある。例えば、お客さんの名前が分からないと注文を追加できない、みたいな。
更新アノマリー:データを更新するときにミスが起きやすい。例えば、1行だけお客さんの名前を変えて、他の行は古いまま残っちゃうとか。
削除アノマリー:データを消すときに大事な情報まで消えちゃうことがある。例えば、注文を消したらお客さんの名前も消えちゃう(同じテーブルに入ってる場合)。
データ量の削減
正規化すると、重複データがなくなるから、データベースのサイズも小さくなることが多いよ。大量のデータを保存するなら、これは超大事!
正規化のデメリット
1. データベース構造が複雑になる
正規化を進めていくと、テーブルがめっちゃ増えて、何千個(!)も関連するテーブルだらけになることも。そうなると、前は1つのテーブルで済んでたデータを取るのに、複雑なSQLクエリで何回もJOINしなきゃいけなくなる。
複雑さの例:
-- 商品やカテゴリの詳細も含めて注文情報を取得するクエリ
SELECT
o.order_id,
o.order_date,
c.customer_name,
p.product_name,
cat.category_name,
oi.quantity,
oi.unit_price
FROM orders o
JOIN customers c ON o.customer_id = c.customer_id
JOIN order_items oi ON o.order_id = oi.order_id
JOIN products p ON oi.product_id = p.product_id
JOIN categories cat ON p.category_id = cat.category_id;
テーブルやリレーションが増えると、クエリの実行時間もかなり長くなることがあるよ。
2. JOINが多いとパフォーマンスが落ちる
テーブルのJOINが多いと、特にテーブルが大きかったりインデックスがなかったりすると、めっちゃ重くなる。分析系のシステムで何百万行も処理するクエリだと、正規化がパフォーマンスの足を引っ張ることも。
3. 非正規化の追加作業が必要になる
正規化されたデータベースを分析用途で使う場合、一時的に非正規化してクエリを速くすることがある。例えば、VIEWや集計用のテーブルを作ったりね。
例:
-- 分析用の非正規化ビュー
CREATE VIEW orders_with_customers AS
SELECT
o.order_id,
o.order_date,
c.customer_name,
c.customer_address
FROM
orders o
JOIN
customers c ON o.customer_id = c.customer_id;
4. 最初はハードルが高い
初心者にとって、正規化はちょっと難しく感じるかも。全部のデータが1つのテーブルに入ってるんじゃなくて、いくつもテーブルがあって、それぞれの関係も理解しなきゃいけない。チームにDBの知識があんまりないと、開発スピードも落ちるかもね。
5. 冗長性が役立つ場合もある
実際のプロジェクトだと、パフォーマンスのためにあえて冗長データを残すこともある。例えば、アプリがよく使うデータが複雑なJOINしないと取れないなら、1つのテーブルにまとめて持っておいた方が速いこともあるよ。
GO TO FULL VERSION