Contenu connexe
Similaire à MySQL資料表正規化草稿
Similaire à MySQL資料表正規化草稿 (20)
MySQL資料表正規化草稿
- 1. PHP 與 MySQL 網站規劃管理與應用
第 6 章 MySQL 正規化與多資料表查詢
6-1 正規化
資料表進行正規化的目的避免在避免資料重複出現及解決資料不一致的相依性。
避免資料重複出現可減少資料刪除或更新時的錯誤,而資料不一致的相依性會
造成新增資料時的異常。本節提供一個學生成績登錄資料表範例,我們將瞭解為
何這個資料表需要進行正規化。
6-1-1 第一正規化之前
規劃資料表之前,您會收集相關資料,並進而將資料轉換為表格形式儲存,
如使用 Microsoft Excel 或 OpenOffice.org Calc 。藉由資料的特性,定義資料表欄
位屬性後建立資料表。
【圖 1、收集資料】
欄位名稱 意義 欄位名稱 意義
Stu_no 學號 Subject_id 科目代號
Area 縣市鄉鎮市區 Subject_name 科目名稱
ZIP 郵遞區號 Score 成績
Address 地址
【表 1、欲進行正規化資料表各欄位所代表意義】
這個資料表各欄位名稱所代表意義如表 1。 請將光碟「6」資料夾之「sql」資料夾
內「grade 第一正規化之前.sql」匯入至 pcschool 資料庫內,或請參考以下語法匯
入資料(檔案名稱:「6」資料夾內「grade 第一正規化之前.sql 」):
01 CREATE TABLE `grade` (
02 `Stu_no` double default NULL,
03 `Area` varchar(30) default NULL,
04 `ZIP` double default NULL,
05 `Address` varchar(255) default NULL,
1 葉建榮設計 上奇出版/巨匠課程補充教材
- 2. PHP 與 MySQL 網站規劃管理與應用
第 6 章 MySQL 正規化與多資料表查詢
06 `Subject_id` varchar(30) default NULL,
07 `Subject_name` varchar(30) default NULL,
08 `Score` double default NULL
09 ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
10 INSERT INTO `grade` VALUES (99312, '台中市中區', 400,'奇奇路 16888 號',
'I5302,E5345', '資訊管理,環境保育', 89);
11 INSERT INTO `grade` VALUES (99312, '台中市中區', 400,'奇奇路 16888 號',
'M8005', '財務管理', 78);
12 INSERT INTO `grade` VALUES (99312, '台中市中區', 400,'奇奇路 16888 號',
'S3581', '系統分析', 80);
13 INSERT INTO `grade` VALUES (99312, '台中市中區', 400,'奇奇路 16888 號',
'M1201', '離散數學', 65);
14 INSERT INTO `grade` VALUES (99312, '台中市中區', 400,'奇奇路 16888 號',
'M5251', '統計學', 95);
15 INSERT INTO `grade` VALUES (99524, '新北市板橋區', 220,'榮榮一路 520 號',
'I5302', '資訊管理', 88);
16 INSERT INTO `grade` VALUES (99302, '高雄市小港區', 812,'小卉路 9920 號'
,'I5302,E5345,S3581', '資訊管理,環境保育,系統分析', 98);
17 INSERT INTO `grade` VALUES (99302, '高雄市小港區', 812,'小卉路 9920 號',
'M5251', '統計學', 85);
18 INSERT INTO `grade` VALUES (99345, '台北市大安區',106,'馬克路 140
號','P1234', '資料庫網頁', 40);
2 葉建榮設計 上奇出版/巨匠課程補充教材
- 3. PHP 與 MySQL 網站規劃管理與應用
第 6 章 MySQL 正規化與多資料表查詢
【圖 2、尚未第一正規化之前的資料表】
這個資料表有以下的幾個缺點:
1.浪費空間:例如學號為「99312」這位同學的資料重複五次。
2.不容易修改:若學號為 「99312」這位同學由台中市搬到彰化縣, 「Area」、「ZIP」
與「Address」三個欄位各要修改五次,很容易出錯。
3.容易遺失資料:由第一筆記錄可知學號為 「99312」這位同學成績「Score」欄位內
容
為 89 共有兩個科目,但如果修改資料時刪除「Subject_name」欄位內容內「環
境保育」,資料表的總筆數不變,所以很容易遺失資料而不知。
4.新增異常:當您新增一位新同學資料時,您必須同時新增成績資料。若沒有新
增成績資料,資料表內容無法針對成績學科資料進行分析。
3 葉建榮設計 上奇出版/巨匠課程補充教材
- 4. PHP 與 MySQL 網站規劃管理與應用
第 6 章 MySQL 正規化與多資料表查詢
由於這個資料表內資料重複且資料新增、修改或刪除容易出現資料不一致情形,
此資料表將進入正規化流程進行資料表重新規劃。 進行正規化之前,請先進行欄
位相依性的分析。 在一個資料表中,若 B 欄位的值必須搭配 A 欄位才有意義,這
代表 欄位相依於 A 欄位』 例如學生資料表內有學號、
『B 。 姓名、 地址、 電話等欄位,
姓名、 地址與電話等欄位必須搭配學號欄位才有意義,所以可說 「姓名、 地址與電
話等欄位相依於學號欄位」。
另外「間接相依」是指在二個欄位間並非直接相依,而是借助第三個欄位來達成
資料相依的關係,例如 A 相依於 B;而 B 又相依於 C, 如此 A 與 C 之間就是間接
相依的關係。
【圖 3、欄位相依性分析】
整理 grade 資料表內各欄位相依性如圖 3 所示。Stu_no 及 Subject_id 兩個欄位
代表學號與科目代號,決定了科目名稱與成績。 學號決定了居住地之縣市鄉鎮市
區、郵遞區號及地址,而縣市鄉鎮市區決定了郵遞區號及地址。
6-1-2 第一正規化
第一正規化主要進行以下的工作:
1. 欄位內容必須是單一內容。
2. 同一欄位的內容必須是相同的類型。
3. 必須要有一個或一組主鍵可以辨識資料。
4. 不可用很多欄位來表達同一筆資料。
4 葉建榮設計 上奇出版/巨匠課程補充教材
- 5. PHP 與 MySQL 網站規劃管理與應用
第 6 章 MySQL 正規化與多資料表查詢
主鍵是辨識每筆資料的關鍵欄位,它可以決定其他欄位內容。 主鍵可以是單一
欄位,也可由多個欄位組合起來。 如果現有資料表沒有主鍵呢?例如以下表格:
Orderbooks Quantity OrderDate
PHP 6 與 MySQL 基礎學習教室 10 2011/02/14
PHP 6 與 MySQL 基礎學習教室 20 2011/02/14
【表 2、若現有資料表沒有主鍵】
兩筆資料都是同一天產生,但如何辨識資料呢?請再多加入一個欄位,例如
交易序號,該欄位必須是資料不會重複且沒有空值,該欄位就可以作為資料表
主鍵。
設計資料表時不可有多個欄位來表達同一筆資料。例如以下表格:
Student ID classname1 classname2 classname3
991012 歷史 國文 數學
990218 環境保育 資訊安全 資料庫
【表 3、若現有資料表內有多個欄位表達同一筆資料】
其實 classname1 至 classname3 內容都是課程名稱,只要規劃一個欄位即可。
所以上述表格應改為:
StudentID classname
991012 歷史
991012 國文
991012 數學
990218 環境保育
990218 資訊安全
990218 資料庫
【表 4、資料表經第一正規化後須避免多個欄位表達同一筆資料】
若第一正規化時資料表內產生兩組或兩個(含)以上的主鍵,請將資料表切割為
兩個(含)以上的資料表。例如以下表格:
借書證號碼 讀者姓名 書籍條碼 書名
99621009 葉建榮 8005002021 PHP 6 與 MySQL 基礎學習教室
【表 5、若資料表有兩個以上主鍵】
因為借書證號碼決定讀者姓名,而書籍條碼決定書名,這是兩個主鍵,請將
這四個欄位切割為兩個資料表設計。
5 葉建榮設計 上奇出版/巨匠課程補充教材
- 6. PHP 與 MySQL 網站規劃管理與應用
第 6 章 MySQL 正規化與多資料表查詢
本資料表經第一正規化之後資料表結構與內容如以下語法,請將光碟 「6」 資料
夾之「sql」資料夾內「grade 第一正規化.sql」匯入至 pcschool 資料庫內:
01 CREATE TABLE `grade1` (
02 `Stu_no` double default NULL,
03 `Area` varchar(30) default NULL,
04 `ZIP` double default NULL,
05 `Address` varchar(255) default NULL,
06 `Subject_id` varchar(30) default NULL,
07 `Subject_name` varchar(30) default NULL,
08 `Score` double default NULL
09 ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
10 INSERT INTO `grade1` VALUES (99312, '台中市中區', 400,'奇奇路 16888 號',
'I5302', '資訊管理', 89);
11 INSERT INTO `grade1` VALUES (99312, '台中市中區', 400,'奇奇路 16888 號',
'E5345', '環境保育', 89);
12 INSERT INTO `grade1` VALUES (99312, '台中市中區', 400,'奇奇路 16888 號',
'M8005', '財務管理', 78);
13 INSERT INTO `grade1` VALUES (99312, '台中市中區', 400,'奇奇路 16888 號',
'S3581', '系統分析', 80);
14 INSERT INTO `grade1` VALUES (99312, '台中市中區', 400,'奇奇路 16888 號',
'M1201', '離散數學', 65);
15 INSERT INTO `grade1` VALUES (99312, '台中市中區', 400,'奇奇路 16888 號',
'M5251', '統計學', 95);
16 INSERT INTO `grade1` VALUES (99524, '新北市板橋區', 220,'榮榮一路 520 號',
'I5302', '資訊管理', 88);
17 INSERT INTO `grade1` VALUES (99302, '高雄市小港區', 812,'小卉路 9920 號',
'I5302', '資訊管理', 98);
18 INSERT INTO `grade1` VALUES (99302, '高雄市小港區', 812,'小卉路 9920 號',
'E5345', '環境保育', 98);
19 INSERT INTO `grade1` VALUES (99302, '高雄市小港區', 812,'小卉路 9920
號','S3581','系統分析', 98);
20 INSERT INTO `grade1` VALUES (99302, '高雄市小港區', 812,'小卉路 9920 號',
'M5251', '統計學', 85);
21 INSERT INTO `grade1` VALUES (99345, '台北市大安區',106,'馬克路 140 號',
'P1234', '資料庫網頁', 40);
6 葉建榮設計 上奇出版/巨匠課程補充教材
- 7. PHP 與 MySQL 網站規劃管理與應用
第 6 章 MySQL 正規化與多資料表查詢
【圖 4、第一正規化後資料表結構與內容】
6-1-3 第二正規化
第一正規化之後資料表將產生以下的問題:
1.無法單獨新增一筆學生資料。因為 Subject_id 是主鍵之一,不能為空值。當學
生尚未選修任何課程之前,將無法寫入資料表。
2.無法單獨刪除一筆成績資料。如果打算刪除科目代表為 P1234 這個科目資訊,
您會把這名學生資訊也刪除,學號 99345 這位同學資料就此消失。
3.需要同步異動的資料太多。假設學號為 99312 這個學生搬家了,那麼我們得
異動其中的 6 筆紀錄。
7 葉建榮設計 上奇出版/巨匠課程補充教材
- 8. PHP 與 MySQL 網站規劃管理與應用
第 6 章 MySQL 正規化與多資料表查詢
執行第二正規化之前資料表結構必須符合第一正規化要求才可進行。 第二正規
化將要求資料表裡所有的資料必需與該資料表的主鍵有相依關係,以避免資料
重複與不一致性。 若某欄位只和主鍵的一部份而非全部有關的話,請將這些欄位
獨立成另外一個資料表。由於 Area、ZIP 與 Addess 三個欄位相依於 Stu_no,而非
Stu_no 及 Subject_id 這一組主鍵,所以第二正規化時需將資料表拆成兩個資料
表。
【圖 5、第二正規化】
8 葉建榮設計 上奇出版/巨匠課程補充教材
- 9. PHP 與 MySQL 網站規劃管理與應用
第 6 章 MySQL 正規化與多資料表查詢
資料表重新切割後,接著請您整理資料,將重複的資料刪除。 資料表經第二正
規化之後資料表結構與內容如以下語法,請將光碟 「6」資料夾之 「sql」資料夾內
「grade 第二正規化.sql」匯入至 pcschool 資料庫內:
01 CREATE TABLE `grade2Stuno` (
02 `Stuno` double default NULL,
03 `Area` varchar(30) default NULL,
04 `ZIP` double default NULL,
05 `Address` varchar(255) default NULL,
06 PRIMARY KEY (`Stuno`)
07 ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
08
09 CREATE TABLE `grade2Score` (
10 `Stuno` double default NULL,
11 `Subjectid` varchar(30) default NULL,
12 `Subjectname` varchar(30) default NULL,
13 `Score` double default NULL
14 ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
15
16 INSERT INTO `grade2Stuno` VALUES (99312, '台中市中區', 400,'奇奇路 16888 號');
17 INSERT INTO `grade2Stuno` VALUES (99524, '新北市板橋區', 220,'榮榮一路 520
號');
18 INSERT INTO `grade2Stuno` VALUES (99302, '高雄市小港區', 812,'小卉路 9920
號');
19 INSERT INTO `grade2Stuno` VALUES (99345, '台北市大安區',106,'馬克路 140 號');
20
21 INSERT INTO `grade2Score` VALUES (99312, 'I5302', '資訊管理', 89);
22 INSERT INTO `grade2Score` VALUES (99312, 'E5345', '環境保育', 89);
23 INSERT INTO `grade2Score` VALUES (99312, 'M8005', '財務管理', 78);
24 INSERT INTO `grade2Score` VALUES (99312, 'S3581', '系統分析', 80);
25 INSERT INTO `grade2Score` VALUES (99312, 'M1201', '離散數學', 65);
26 INSERT INTO `grade2Score` VALUES (99312, 'M5251', '統計學', 95);
27 INSERT INTO `grade2Score` VALUES (99524, 'I5302', '資訊管理', 88);
28 INSERT INTO `grade2Score` VALUES (99302, 'I5302', '資訊管理', 98);
29 INSERT INTO `grade2Score` VALUES (99302, 'E5345', '環境保育', 98);
30 INSERT INTO `grade2Score` VALUES (99302, 'S3581', '系統分析', 98);
31 INSERT INTO `grade2Score` VALUES (99302, 'M5251', '統計學', 85);
9 葉建榮設計 上奇出版/巨匠課程補充教材
- 10. PHP 與 MySQL 網站規劃管理與應用
第 6 章 MySQL 正規化與多資料表查詢
32 INSERT INTO `grade2Score` VALUES (99345, 'P1234', '資料庫網頁', 40);
【圖 6、第二正規化後 grade2score 資料表結構與內容】
10 葉建榮設計 上奇出版/巨匠課程補充教材
- 11. PHP 與 MySQL 網站規劃管理與應用
第 6 章 MySQL 正規化與多資料表查詢
【圖 7、第二正規化後 grade2stuno 資料表結構與內容】
6-1-4 第三正規化
第二正規化之後資料表將產生以下的問題:
1.無法單獨新增一筆縣市資料。因為 Stu_no 是主鍵,不能是空值;因此,若無
任何學生居住的某個縣市,其郵遞區號資料將無法被事先建立。
2.無法單獨刪除一筆學生資料。如果我們打算刪除 99524 這筆資料的話,新北
市郵遞區號資料也將一併消失。
3.更新郵遞區號困難。假設有兩位同學同住在台中市清水區,若郵遞區號變更,
則要同時異動多筆紀錄。
11 葉建榮設計 上奇出版/巨匠課程補充教材