10
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

【DB設計】正規化とパフォーマンス

Last updated at Posted at 2019-11-23

#論理設計とパフォーマンス 〜正規化の欠点と非正規化
達人に学ぶDB設計 徹底指南書を読み返して。

まず、
データの整合性を保つ為、正規化を行う事は大原則。しかし、正規化によってパフォーマンスに少なからず影響があるということも理解しておく必要がある。

###正規化とパフォーマンスはトレードオフの関係

正規化を進めていくと、複数のテーブルに分けて管理し、それぞれのデータを参照しながらデータを抽出するが、その分コストが高くなってしまうという。特にテーブル同士の結合はSQLの処理の中でもコストが高い。

#正規形のデメリット
主なデメリットは、正規化されたテーブルにおいて、単独のテーブルだけからでは必ずしも欲しいデータの全てをカバーできないということ。

以下、テーブル、SQLは書籍から引用
例:

####第3正規形のテーブル

会社

会社コード 会社名
C0001 A商事
C0002 B化学
C0003 C建設

社員

会社コード 社員ID 社員名 年齢  部署 
C0001 000A 加藤 40 D01
C0001 000B 藤本 32 D02
C0001 001F 三島 47 D03
C0002 000A 斎藤 47 D03
C0002 009F 田島 25 D01
C0002 010A 渋谷 33 D04

部署

部署コード 部署名
D01 開発
D02 人事
D03 営業
D04 総務

####1、ある社員の勤めている会社を知りたい

SELECT
    会社.会社名
,   社員.社員名
FROM 社員 INNER JOIN 会社 
  ON 社員.社員コード = 会社.会社コード
WHERE 社員.社員コード = '田島';
会社名  社員名
-----  -----
B化学   田島

####2、会社に加えて部署名も知りたい

SELECT
    会社.会社名
,   社員.社員名
,   部署.部署名
FROM 社員 INNER JOIN 会社 
  ON 社員.社員コード = 会社.会社コード
         INNER JOIN 部署 
  ON 社員.部署コード = 部署.部署コード
WHERE 社員.社員コード = '田島';
会社名  社員名  部署名
-----  ----- -----
B化学   田島   開発

####3、会社ごとに社員数をまとめたい
※社員が登録されていない会社があるので外部結合(OUTER JOIN)を使っている。

SELECT
    会社.会社コード
,   COUNT(社員.社員名) AS 社員数
FROM 会社 LEFT OUTER JOIN 社員
   ON 社員.会社コード = 会社.会社コード
GROUP BY 会社.会社コード
会社コード  社員数 
-----    -----
C0001    3
C0002    3
C0003    0

いずれもテーブル同士を結合し、外部キーを参照して欲しいテータを抽出している。

##非正規形でパフォーマンスを追求するデメリット
一方、非正規化することにより、正規化のデメリットであったパフォーマンスは解決できる。

####「ある社員の勤めている会社を知りたい」を非正規化
例えば、テーブルを分けず、1つのテーブルで全ての情報を管理していた場合、以下のSELECT文でデータは抽出できる。ここでは、結合をしていない為、シンプルなSQLになっておりパフォーマンスも改善できる。

会社コード 会社名 社員ID 社員名 年齢   部署コード  部署名
C0001 A商事 000A 加藤 40 D01 開発
C0001 A商事 000B 藤本 32 D02 人事
C0001 A商事 001F 三島 47 D03 営業
C0002 B化学 000A 斎藤 47 D03 営業
C0002 B化学 009F 田島 25 D01 開発
C0002 B化学 010A 渋谷 33 D04 総務
SELECT
    会社名
,   社員名
,   部署名
FROM 社員
WHERE 社員名 = '田島'
会社名  社員名
-----  -----
B化学   田島

###問題点
大きな問題点として、データの更新が非常に非効率になるなど保守性が良くない。
例えば、ある会社が買収され、会社の名前が変更になった場合、社員テーブルの会社名のレコードを一つ一つ更新する必要がある。

非正規化の場合:

UPDATE 社員
  SET 会社名 = 'E物産'
WHERE 会社コード = 'C0001'

対し、正規形の場合、会社テーブルの1レコードのみ更新すればいい。

UPDATE 会社
  SET 会社名 = 'E物産'
WHERE 会社コード = 'C0001'

##ではどちらがいいか
原則的には非正規化は認められない。
引用の引用:
クリス・デイト

十分に正規化された設計を諦めてもよいのは、パフォーマンスを向上させるためのその他全ての戦略が要件を満たさないだけである。

#まとめ
・正規化は、パフォーマンスが悪くなることも
・非正規化は、パフォーマンスは改善されるが、保守性に難あり
・原則的には正規化を行うこと。
・非正規化は最後の手段。

参考文献:
達人に学ぶDB設計 徹底指南書

10
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?