![はむ](https://tackblog.net/wp-content/uploads/2021/06/ham-image.png)
この前論理設計について教えてもらったのですが、実際に作業を始めると、テーブルをどのように分割していけばいいのかわからなくなりました。
![タック](https://tackblog.net/wp-content/uploads/2021/04/Tack-k様・アイコン.png)
テーブルの分割って難しいですよね。逆に言えば分割こそが、データベース設計の肝ともいえます。今回は正規化を詳しく見ていきましょう!
今回の記事で身に付くこと
- テーブルを分割する考え方がわかる
- 効率の悪いテーブルをつくらなくなる
論理設計の工程のうち正規化に焦点を当ててお話します。論理設計って何?という方はこちらが参考になります。
正規化とは「効率の悪いテーブルを分割すること」です。大きく分けると3つの工程に分かれています。
- 第1正規形
- 第2正規形
- 第3正規形
それでは、3つの工程をざっくり見ていきましょう。
第1正規形
第1正規形とは「一つのセルには一つのデータだけ入れるテーブルにすること」です。
次のテーブルをみると、商品欄に複数の情報があります。エクセルでよく見られますね。
id | 会社名 | メールアドレス | 商品 | 割引率 |
1 | A | A@co.jp | タブレット スマホ |
10 |
2 | B | B@co.jp | 洗濯機 | 0 |
3 | C | C@co.jp | パソコン | 10 |
4 | D | D@co.jp | 掃除機 冷蔵庫 |
20 |
5 | E | E@co.jp | パソコン | 30 |
この状態を分割して解消するのが第1正規形です。
なぜ、一つのセルに一つの情報とするのでしょうか。その理由は主キーから関連するデータを一つに決めるためです。
主キーは出席番号みたいなものです。重複しない値になっているため、データの情報を一つに特定することができます。
主キーであるid:2に対して商品:洗濯機が一対一で対応することで、一つに絞り込むことができます。
一方でid:1に対して、商品の中にスマホとタブレットが入っているので、商品が特定できなくなってしまっています。
キーから関連するデータを一つに絞り込めない事態を避けるために、第一正規形にします。
id | 会社名 | メールアドレス | 商品 | 割引率 |
1 | A | A@co.jp | タブレット | 10 |
2 | A | A@co.jp | スマホ | 10 |
3 | B | B@co.jp | 洗濯機 | 0 |
4 | C | C@co.jp | パソコン | 10 |
5 | D | D@co.jp | 掃除機 | 20 |
6 | D | D@co.jp | 冷蔵庫 | 20 |
7 | E | E@co.jp | パソコン | 30 |
第2正規形
第2正規形とは「完全に従属する関係にあるもの同士に分割すること」です。
もう少しわかりやすい表現にすると「データを仲間同士にまとめること」です。
ここで言う従属や仲間は何を指しているのでしょうか。「主キーと関係性のあるデータ」だと捉えるといいと思います。
第一正規形のテーブルを考えてみましょう。
id | 会社名 | メールアドレス | 商品 | 割引率 |
1 | A | A@co.jp | タブレット | 10 |
2 | A | A@co.jp | スマホ | 10 |
3 | B | B@co.jp | 洗濯機 | 0 |
4 | C | C@co.jp | パソコン | 10 |
5 | D | D@co.jp | 掃除機 | 20 |
6 | D | D@co.jp | 冷蔵庫 | 20 |
7 | E | E@co.jp | パソコン | 30 |
よく見ると2つの関係になっていることに気付きます。会社に関する情報と商品に関する情報です。
それぞれの仲間同士に分割します。これが第2正規化です。
会社テーブル
会社id | 会社名 | メールアドレス |
1 | A | A@co.jp |
2 | B | B@co.jp |
3 | C | C@co.jp |
4 | D | D@co.jp |
5 | E | E@co.jp |
商品テーブル
商品id | 商品 | 割引率 |
1 | タブレット | 10 |
2 | スマホ | 10 |
3 | 洗濯機 | 0 |
4 | パソコン | 10 |
5 | 掃除機 | 20 |
6 | 冷蔵庫 | 20 |
7 | パソコン | 30 |
第3正規形
第3正規形とは「隠れた関係性を分割すること」です。
商品テーブルを割引率に着目してみてみます。一見すると商品と割引率は商品に関する情報でひとまとめにできそうです。
今後割引率が50%で販売したい商品があると仮定しましょう。
この場合、商品データを登録しない限り、割引率50%は設定できません。商品データと割引率が同じレベルで管理されているからです。
割引率は割引率として別のテーブルで管理すれば、この問題は解決できます。
商品テーブル
商品id | 商品 |
1 | タブレット |
2 | スマホ |
3 | 洗濯機 |
4 | パソコン |
5 | 掃除機 |
6 | 冷蔵庫 |
7 | パソコン |
割引率テーブル
割引率id | 割引率 |
1 | 0 |
2 | 10 |
3 | 20 |
4 | 30 |
5 | 50 |
分割したテーブルはSQL文で結合(JOIN)することで、必ず元の形にすることができます。
正規化は常にするべきか
第3正規形までは原則行ったほうがいいと言えます。
- データの冗長性が排除されて、データの不整合が起きにくくなる
- テーブルの持つ意味が明確になり、開発者が理解しやすい
一方でテーブル数が増えるためSQLで結合することが多くなり、パフォーマンスが低下するデメリットもあるので、意識する必要があります。
まとめ
最後にまとめていきます!
- 第1正規形「一つのセルには一つのデータだけ入れるテーブルにすること」
- 第2正規形「完全に従属する関係にあるもの同士に分割すること」
- 第3正規形「隠れた関係性を分割すること」
第3正規形までしたテーブルはSQLで結合することで元の形にすることができる。
第3正規形までは原則行うほうがいいが、パフォーマンスが悪くなるデメリットもある。
参考
今回参考にさせていただいたのは「達人に学ぶDB設計 徹底指南書」です。
今回は第3正規形まで説明しました。この書籍では更に詳しく
- ボイスーコッド正規形
- 第4正規形
- 第5正規形
まで説明されているので、より深く知りたいと思った方はぜひ御覧ください!
コメント