LoginSignup
0
0

DBを正規化するということ

Posted at

はじめに

楽々ERDレッスンを読んだので、重要だと思った点についてまとめ。

  • One Fact in One Place
  • ビジネスの視点から正規化

One Fact in One Placeについて

データベース設計の基本的な考え方がOne Fact in One Placeである。
日本語では「1つの事実が1つの場所にのみ存在する」ということ。
これを実現するための一つの手法として、データベースの正規化が挙げられる。
正規化というと、1つの事実を2つ以上の場所に置かない1ことを想像してしまいがちである。
しかし、2つ以上の事実を1つの場所に置かないことも重要だ。

2つ以上の事実を1つの場所に置いた状態

具体例を交えて考えてみる。
社員というテーブルを例に考える。
only_employee.png

上記のテーブルでは、退職区分というカラムがあり、現役の社員なのか退職済みの社員なのかという情報を持っている。
現役社員の場合は、退職日がnullとなる。
退職済みの社員の場合は、セキュリティの観点から名前を保持しないため姓名がnullとなり、退職日に値が入る。
社員という一つのくくりで表現しようとしているが、社員には現役と退職済みという2つの種類があり、2つの事実を1つのテーブルの中に持ってしまっている。
区分というカラムによって、レコードの意味が変わってしまうという問題が発生している。
解決するためには、One Fact in One Placeを進めていけば良い。
employee copy.png

このようにすれば、現役社員と退職済社員の2つを別のテーブルで管理することができる。
しかし、これだけでは十分ではない。退職済社員に着目すると、退職済社員というリソースの情報と、退職をするというイベントの情報が1つのテーブルにまとまっている。
これらを分解すると、
employee.png

のようになる。

ビジネスの視点から正規化する

テーブルをわけて重複を排除していくことが正規化ではない。
正規化とは、ビジネスの視点から情報を整理していくことである。
例として商品の売上を管理するということを考える。
売上.png

前提として今回の説明と関係ない項目は極力排除してある。
商品テーブルに単価を持たせているため、売上明細テーブルには商品の金額を持たせていない。
また、商品テーブルの単価と売上明細テーブルの数量を見れば合計金額は導出できるため、売上テーブルに合計金額は持たせていない。
テーブルの正規化というと上記のように、「持たせなくていいものをできるだけ持たせない」ということを想像してしまいがちである。
しかし、これが常に正しいとは限らない。
例えば、「今回のみ、この商品に関しては割引をして売る」ということが発生する場合、上記のテーブルでは表現することができない。この場合は、売上明細テーブルに販売価格を持つことが正しい。
あるいは「全体の売上金額から端数を割引する」ということが発生する場合、売上テーブルに割引後の合計金額を持つことが正しい。
このように、ビジネスで起こり得ることも加味したうえでテーブル設計を行う必要があり、ただ、テーブルをわけて重複を排除するのみが正規化ではない。

参考

  1. 例えば商品の売上の管理をする場合、価格を商品テーブルと売上テーブルに持たせてしまうと、価格という1つの事実を2つの場所で持っていることになる

0
0
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
0
0