導入
初学者が正規化について,簡単なテーブル例を使いながら第一正規系から第三正規系まで解説する備忘録です.
記事を読むのにかかる時間
- 5分
以下の条件のworldsテーブルを例に正規化を進める.
条件
- 名前: worlds
- id(主キー): NOT NULL
- name: NOT NULL
- launch_url: NOT NULL
- tags: タグ複数をカンマ区切りで格納, NOT NULL
- description
元テーブル
worlds
| id | name | launchURL | tags | description |
|---|---|---|---|---|
| 1 | skipfloor | url001 | chill,study,home,jp | 実家 |
| 2 | jpt | url002 | jp | --- |
| 3 | jplus | url003 | jp | にぎわっている |
| 4 | 始発駅 | url004 | chill,music,jp | 広い |
第一正規化
重複データを削除する
worlds
| id | name | launchURL | tag | description |
|---|---|---|---|---|
| 1 | skipfloor | url001 | chill | 実家 |
| 1 | skipfloor | url001 | study | 実家 |
| 1 | skipfloor | url001 | home | 実家 |
| 1 | skipfloor | url001 | jp | 実家 |
| 2 | jpt | url002 | jp | NULL |
| 3 | jplus | url003 | jp | にぎわっている |
| 4 | 始発駅 | url004 | chill | 広い |
| 4 | 始発駅 | url004 | music | 広い |
| 4 | 始発駅 | url004 | jp | 広い |
第二正規化
冗長な項目を削除
主キーの一部にしか依存しないtagを他テーブルに分離
worlds(idのみ依存)
| id | name | launchURL | description |
|---|---|---|---|
| 1 | skipfloor | url001 | 実家 |
| 2 | jpt | url002 | NULL |
| 3 | jplus | url003 | にぎわっている |
| 4 | 始発駅 | url004 | 広い |
world_tags(idとtagの関連)
| world_id | tag |
|---|---|
| 1 | chill |
| 1 | study |
| 1 | home |
| 1 | jp |
| 2 | jp |
| 3 | jp |
| 4 | chill |
| 4 | music |
| 4 | jp |
第三正規化
第二正規化後は,1つのworldが複数のtagを持ち,1つのtagが複数のworldに紐づけされていることがわかる.これが多対多の関係である.
ここで,プライマリキーであるidが他のキー項目を一意に定めるためには,idとworld_idが一対一対応していれば良い.
よって,worldsとworld_tagsを結ぶ中間テーブルtaggingsを作成する.
worlds(変更なし)
| id | name | launchURL | description |
|---|---|---|---|
| 1 | skipfloor | url001 | 実家 |
| 2 | jpt | url002 | NULL |
| 3 | jplus | url003 | にぎわっている |
| 4 | 始発駅 | url004 | 広い |
tags(タグのマスタを行う)
| id | name |
|---|---|
| 1 | chill |
| 2 | study |
| 3 | home |
| 4 | jp |
| 5 | music |
taggings(worldsとtagsをつなぐ中間テーブル)
| world_id | tag_id |
|---|---|
| 1 | 1 |
| 1 | 2 |
| 1 | 3 |
| 1 | 4 |
| 2 | 4 |
| 3 | 4 |
| 4 | 1 |
| 4 | 5 |
| 4 | 4 |
注意: 第三正規化の厳密な定義は,主キー以外の列に関数的に従属する列を失くすことだが,今回は第二正規化において関数従属が解決されているため,定義と照らし合わせると少し解釈が変わる.
よろしくお願いします.
参考文献
https://qiita.com/morikuma709/items/9fde633db9171b36a068
https://www.momoyama-usagi.com/entry/info-database-seikika