iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 18
0
AI & Data

作者超囉嗦,但一天只要十分鐘的MYSQL真.新手教學系列 第 18

第十八日-新手資料表設計:資料庫正規化

  • 分享至 

  • xImage
  •  

介紹完單張資料表資料選取的各種方式後,
我們要開始跟關聯資料表玩耍啦!
今天不動手,是很囉唆的介紹關聯資料表與資料庫正規化。

用自己對資料庫的理解,舉生活化的例子解釋,
如果有更好的例子或是更精確的講法,歡迎留言!

  • 關聯資料表

什麼叫關聯資料表呢?
簡單來說就是「這些表有關係」,
嗯,這感覺是句廢話XD
但想像一下,
一個學校裡面有班級表、老師表、學生表、上課表:

課程表:課程名字(PK)、教室位置
老師表:老師名字(PK)、課程名字(PK)
學生表:學生名字(PK)、緊急連絡人
上課表:課程名字(PK)、老師名字(PK)、學生名字(PK)

我們一般PK會設ID,而非名字,但為了方便理解,我們先用名字當PK
一行超過一個PK的代表是複合主鍵

是不是可以看到這三張表之間有些欄位會出現在別張資料表的欄位裡面,
而且代表的意義相同?例如:我們可以從老師表的課程名字連到課程表,
代表這兩張表示有關連的。

  • 為什麼不把這些通通寫在一張表就好?

但問題來了,
為什麼不把所有資料通通寫在一張表就好?
想想,如果把全部資訊放在一起,會變成:


整張表眼花撩亂,很多重複的資料,
甚至一欄有不只一個值(例如有三個學生名字),
以緊急連絡人來說,完全看不出來大明是哪個學生的緊急連絡人!
在更新資料的時候,如果想刪除王老師的國文課資料,
對不知道這所學校有兩種國文課的人而言,
很可能會DELETE FROM 資料表 WHERE課程名字='國文課',
連李老師的國文課也被刪掉,
這所學校直接沒有國文課!

  • 前人智慧的結晶:資料庫正規化

想預防上面這些問題的產生,
降低資料重複,減少錯誤的資料變動
我們需要做的就是資料庫正規化。
資料庫正規化其實就是資料庫標準化,
它有一套標準,讓大家可以遵循去設計資料庫,
而照這個標準設計出來的資料庫會比較方便使用。

下面介紹比較基本的第一正規化和第二正規化。

  • 第一正規化:一個蘿蔔一個坑

第一正規化:

  1. 一個欄位一個值
  2. 沒有重複的列(有PK)

第一正規化白話一點就是一個蘿蔔一個坑,
像一個國文課對上兩個老師,就是兩個蘿蔔擠一個坑,
後面的學生名字一次填三個是三個蘿蔔一個坑,都是不行的!

如果改成一個蘿蔔一個坑的話:

雖然表格變長了,但是不是可以很清楚的辨識出各種資料?
同時我們的資料表也沒有一模一樣重複的列,
也可以設定複合PK是課程名字+老師名字+學生名字。
(忘記複合鍵的請複習)

  • 第二正規化:能分的就分出去

第二正規化:

  1. 滿足第一正規化
  2. 資料表欄位要完全相依

我們不要管上面這個文言文(欸),
第二正規化就是:能分的就分出去!
把主鍵通通拉出去!
例如我們的複合主鍵有課程名字+老師名字+學生名字,
那我們先做一張表,課程名字當PK,那什麼欄位只會被課程名字影響呢?
就是教室位置!教室位置只會因為課程而改動,
不會因為換老師或換學生就改教室位置,
所以我們會把教室位置拉出去,跟課程放一張表.

所以:
課程表:課程名字(PK)、教室位置
老師表:老師名字(PK)、課程名字(PK)
學生表:學生名字(PK)、緊急連絡人



最後如何呈現這些關係呢?

如果想查上課地點,
就把上課表的課程名字關連到課程表,查詢教室位置;
如果想查緊急連絡人,
就把上課表的學生名字關連到學生表,查詢緊急連絡人;
如果想查小明的國文老師還教什麼其他科目,
就把上課表老師名字關連到老師表,查詢課程名字;

第二正規化的概念就是盡量減少資料大亂鬥,
但有些時候,資料會多對多
例如:一個老師教很多門課程,同樣的課程會有不同老師教,
像這樣處理起來就比較麻煩,
但簡單的一對一資料,
例如:一個學生對一個緊急連絡人,我們就會盡量抽出來!
明天就開始介紹,如何把抽出來的資料組回去查詢囉!


上一篇
第十七日-大到小小到大的資料排序:ORDER BY
下一篇
第十九日-把不同表格的資料合在一起:聯集INNER JOIN
系列文
作者超囉嗦,但一天只要十分鐘的MYSQL真.新手教學30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言