動態網站資料庫設計好壞直接影響查詢效能、擴充性與維護成本。正規化透過消除冗餘與異常相依,建立清晰、高效的表結構。本文以「使用者收藏網址」為例,逐步演示 0NF → 1NF → 2NF → 3NF 全過程。
users
name | company | company_address | url1 | url2
Joe | ABC | 1 Work Lane | abc.com | xyz.com
Jill | XYZ | 1 Job Street | abc.com | xyz.com
問題:url 欄位固定數量 (url1, url2...),新增需 ALTER TABLE;公司資訊重複儲存。
規則:1) 無重複欄位群 2) 每組相關資料獨立表 3) 每表有主鍵
users
userId | name | company | company_address | url
1 | Joe | ABC | 1 Work Lane | abc.com
1 | Joe | ABC | 1 Work Lane | xyz.com
2 | Jill | XYZ | 1 Job Street | abc.com
2 | Jill | XYZ | 1 Job Street | xyz.com
改善:url 無上限限制。新問題:公司/用戶資料大量重複 (插入/更新/刪除異常)。
規則:非主鍵屬性必須**完全函數相依**於主鍵 (不僅相依於主鍵一部分)。
拆分為兩表:
users
userId (PK) | name | company_id (FK)
1 | Joe | 101
2 | Jill | 102
companies
company_id (PK) | name | address
101 | ABC | 1 Work Lane
102 | XYZ | 1 Job Street
user_urls
userId (FK) | url
1 | abc.com
1 | xyz.com
2 | abc.com
2 | xyz.com
現在:users 只存用戶屬性,companies 存公司屬性,user_urls 存多對多關係。
規則:非主鍵屬性不得**傳遞相依**於主鍵 (即:非鍵屬性不相依於另一非鍵屬性)。
上述 2NF 已符合 3NF。若 companies 表有 city_id → city_name,則 city_name 傳遞相依於 company_id,需再拆分 cities 表。
| 類型 | 說明 | 實作 |
|---|---|---|
| 一對一 | 用戶 ↔ 詳細檔案 | 同表或外鍵 UNIQUE |
| 一對多 | 公司 → 員工 | 員工表加 company_id FK |
| 多對多 | 用戶 ↔ 收藏網址 | 中介表 user_urls (userId, url) |