歡迎來到選修單元 A:資料庫!

嗨,未來的電腦科學家們!這個單元非常關鍵,因為資料庫是現代世界的隱形引擎。每當你登入社交媒體、查看成績或在網上購物時,你其實都在與複雜的資料庫系統進行互動。

在本章中,我們將跨越簡單的試算表,學習如何高效且安全地建構、管理並查詢海量且互相關聯的資料。如果聽到正規化 (normalization) 之類的術語覺得很頭痛,別擔心,我們會用淺顯易懂的生活例子將其拆解!


1. 資料管理基礎

1.1 資料 (Data) 與資訊 (Information)

首先,讓我們釐清這兩個經常被混用的術語:

  • 資料 (Data): 原始、未經處理的事實與數字(例如:1987Smith$500.00)。
  • \n
  • 資訊 (Information): 經過處理、組織並結構化後,具有意義的資料(例如:Smith 先生,1987 年出生,本月收入為 $500.00)。

1.2 資料庫方案與平面檔案 (Flat Files)

在專用資料庫系統出現之前,人們使用平面檔案(如簡單的文字檔或基礎試算表)來儲存資料。

平面檔案的局限性(為什麼我們需要資料庫):
  • 資料冗餘 (Data Redundancy): 同一份資訊(如客戶地址)被儲存了多次,浪費空間。
  • 資料不一致 (Data Inconsistency): 如果地址被儲存了 10 次,但其中 3 次更新錯誤,資料就會變得不可靠。
  • 資料依賴性 (Data Dependence): 資料結構與存取它的應用程式緊密連結,導致更新非常困難。
  • 安全性有限: 很難控管誰能看到特定的欄位或記錄。

現代的資料庫管理系統 (DBMS) 通過集中化資料、控制存取權限並定義不同資料間的明確關係,解決了這些問題。

快速複習:重點摘要 1

DBMS 實現了可控、一致且結構化的儲存,擺脫了平面檔案冗餘所帶來的困擾。

2. 關聯式資料庫結構 (RDBMS)

你將要學習的最常見資料庫類型是關聯式資料庫管理系統 (RDBMS)。該系統將資料組織成多個資料表(稱為關聯),並通過共用的鍵值將其連結起來。

2.1 核心資料庫術語

想像一個單一的試算表(即資料表 Table),其中行和列有特定的稱呼:

  • 資料表 (Table/Relation): 由相關資料組成的集合,按行和列進行組織。(例如:STUDENTS 資料表)
  • 欄位 (Field/Attribute): 資料表中的「列」,定義了特定的資料項目。(例如:Student_ID, Name, Date_of_Birth)
  • 記錄 (Record/Tuple): 資料表中的「行」,代表一組完整且相關的資料。(例如:某位特定學生的所有資料)

2.2 理解鍵值 (Keys)

鍵值對於強制執行結構和連結資料表至關重要。它們是能夠唯一識別記錄或建立關係的屬性(欄位)。

a) 主鍵 (Primary Key, PK)

一個(或一組)能唯一識別資料表中每一筆記錄的欄位。

  • 規則: PK 不能為空(實體完整性 Entity Integrity)且必須是唯一的。
  • 類比:你的專屬學生證號碼。
b) 外鍵 (Foreign Key, FK)

資料表中的一個欄位,指向另一個資料表的主鍵。這就是建立關係的方式。

  • 類比:學生清單(在 STUDENTS 資料表中)包含一個 "Course_ID"。這個 Course_ID 就是外鍵,連結回 COURSES 資料表中唯一的 Course_ID 主鍵。
  • 你知道嗎? 外鍵在它自己的資料表中不需要是唯一的,因為許多學生可以選修同一門課程。
c) 複合鍵 (Composite Key)

由兩個或多個欄位組成的聯合主鍵。當單一欄位不足以提供唯一性時就會用到。

  • 範例:在追蹤註冊情況的資料表中,可能需要 (Student_ID + Course_ID) 的組合來唯一識別一筆註冊紀錄。

3. 資料完整性與一致性

3.1 資料完整性 (Data Integrity)

資料完整性指的是資料庫中資料的準確性、完整性和一致性。一個健康的資料庫需要高水平的完整性。

  • 實體完整性 (Entity Integrity): 確保每一筆記錄都有唯一的識別碼(主鍵不能為 NULL)。
  • 域完整性 (Domain Integrity): 確保輸入到欄位的資料符合可接受的邊界(例如:年齡必須 > 0)。

3.2 參照完整性 (Referential Integrity, RI)

這是 RDBMS 中最重要的概念之一。參照完整性確保了資料表之間的關係始終保持一致。

  • 規則: 任何外鍵的值,要麼必須與參照資料表中的主鍵值相符,要麼必須為 NULL。
  • 常見錯誤: 當「主要」資料表中的記錄仍有外鍵參照時,直接刪除該記錄。這會產生「懸空參照」或「孤兒記錄」。

範例: 如果你從 COURSES 資料表中刪除了 'CS101' 課程,但 STUDENTS 資料表中還有 50 位學生將 'CS101' 列為他們的課程,你就違反了參照完整性。

4. 資料庫設計:正規化 (Normalization)

正規化是一套系統化的流程,用於組織資料表和欄位,以最大限度地減少冗餘和依賴。它使資料庫設計更高效、更易於維護且更可靠。

如果一開始覺得很複雜,別擔心。把正規化想像成整理一個凌亂、擁擠的檔案櫃,讓所有東西都存放在正確且專門的地方。

4.1 正規化形式 (Normal Forms, NF)

4.1.1 第一正規化 (1NF)

要求: 消除重複群組(儲存格內的清單),並確保資料是原子性 (atomic) 的。

  • 原子性資料: 每一欄必須只包含一個值,且該值不可再細分(例如:姓名應拆分為「姓」和「名」欄位)。
  • 目標: 每一行與每一列的交叉點只包含一個不可分割的值。

如果你有一個儲存格列出了「課程 A, 課程 B, 課程 C」,這就不符合 1NF。你必須將這些拆分到不同的記錄或另一個連接表 (junction table) 中。

4.1.2 第二正規化 (2NF)

要求: 必須先符合 1NF,且所有非主鍵屬性必須完全依賴於整個主鍵。

  • 這僅在你有複合鍵時才適用。
  • 目標: 確保你沒有在該資料表中儲存僅與複合鍵「部分」相關的資料。如果有,請將其移至單獨的資料表中。

步驟範例:
1. 資料表:ORDERS (OrderID, ProductID, Product_Name, Product_Price)
2. 主鍵為 (OrderID + ProductID)。
3. 注意:Product_Name 和 Product_Price 僅依賴於 ProductID,而非整個主鍵。
4. 解決方案: 建立一個獨立的 PRODUCTS 資料表 (ProductID, Product_Name, Product_Price) 並連結回 ORDERS 表。現在 ORDERS 表就符合 2NF 了。

4.1.3 第三正規化 (3NF)

要求: 必須先符合 2NF,且消除遞移依賴 (transitive dependencies)

  • 遞移依賴: 一個非主鍵屬性決定了另一個非主鍵屬性 (A -> B -> C,但 A 是主鍵)。資料並不直接依賴於主鍵,而是依賴於另一個非主鍵欄位。
  • 目標: 確保所有欄位僅依賴於主鍵,與其他無關。

範例:
1. 資料表:EMPLOYEES (Employee_ID, Employee_Name, Department_ID, Department_Manager)
2. Employee_ID 是主鍵。
3. Department_Manager 依賴於 Department_ID,而非 Employee_ID。這就是遞移依賴。
4. 解決方案: 建立一個獨立的 DEPARTMENTS 資料表 (Department_ID, Department_Manager) 並連結回去。現在 EMPLOYEES 表就符合 3NF 了。

記憶口訣 (3NF): 每個非主鍵屬性必須提供關於鍵的資訊,且是完整的主鍵除了主鍵之外什麼都沒有

快速複習:正規化

我們進行正規化至 3NF,目的是防止冗餘、最小化更新/刪除異常,並確保資料一致性。

5. 資料庫查詢:結構化查詢語言 (SQL)

SQL (Structured Query Language) 是與關聯式資料庫進行互動和管理的標準語言。對於檢索、插入、修改和刪除資料至關重要。

5.1 資料操作語言 (DML)

DML 指令用於處理資料表內儲存的資料。

a) SELECT (檢索資料)

用於從一個或多個資料表中檢索記錄。這是最常見的指令。

語法結構:
SELECT [欄位] FROM [資料表] WHERE [條件] ORDER BY [欄位]

範例 1 (基本檢索): 檢索所有學生姓名。
SELECT Name FROM Students;

範例 2 (條件檢索): 檢索年齡大於 18 歲的學生姓名。
SELECT Name FROM Students WHERE Age > 18;

b) INSERT (新增資料)

用於向資料表中新增記錄(行)。

語法結構:
INSERT INTO [資料表] (欄位1, 欄位2, ...) VALUES (值1, 值2, ...);

範例:
INSERT INTO Courses (Course_ID, Title) VALUES ('CSHL', 'HL Computer Science');

c) UPDATE (修改現有資料)

用於變更資料表中現有記錄的值。使用 WHERE 子句時請務必小心!

語法結構:
UPDATE [資料表] SET [欄位] = [新值] WHERE [條件];

範例: 將 'CSHL' 課程名稱改為 'Advanced Comp Sci'。
UPDATE Courses SET Title = 'Advanced Comp Sci' WHERE Course_ID = 'CSHL';

d) DELETE (移除資料)

用於從資料表中移除記錄(行)。

語法結構:
DELETE FROM [資料表] WHERE [條件];

範例: 移除 ID 為 999 的學生。
DELETE FROM Students WHERE Student_ID = 999;

常見錯誤: 在 UPDATE 或 DELETE 指令中忘記寫 WHERE 子句。如果忘記,操作將會影響資料表中的每一筆記錄

5.2 資料表連結 (Joining Tables)

使用 RDBMS 的主要原因是能夠利用外鍵連結(Join)多個資料表的資料。

INNER JOIN 會結合兩張資料表中,在特定欄位(通常是 PK/FK 對)有相符值的記錄。

範例: 檢索學生姓名以及他們所選修的課程名稱。
SELECT S.Name, C.Title
FROM Students S
INNER JOIN Courses C ON S.Course_ID = C.Course_ID;

6. 資料庫安全性與存取權限

資料庫通常儲存敏感資訊(個人資料、財務記錄)。安全性至關重要,包括物理和邏輯兩方面的防禦措施。

6.1 邏輯安全措施

  • 使用者認證: 要求唯一的使用者名稱和強密碼來存取資料庫系統。
  • 存取權限 (Permissions): 定義特定使用者或使用者群組可以執行哪些操作(例如:Jane 只能 SELECT 資料;Bob 可以 INSERTUPDATE)。這通常由 SQL 的 GRANTREVOKE 指令控制。
  • 檢視表 (Views): View 是基於 SQL 查詢結果的虛擬資料表。它允許你限制使用者能看到的欄位和行,而無需給予底層資料表的完整存取權。(例如:老師的 View 只顯示學生姓名和分數,隱藏地址和病歷。)
  • 加密: 將敏感資料(如密碼)以加密格式儲存,這樣即使資料庫被駭,資料也無法讀取。

6.2 物理措施與災難恢復

  • 備份 (Backups): 定期將整個資料庫複製到安全的異地位置,以便在系統故障或毀損時進行恢復。
  • 交易記錄 (Transaction Logs): 記錄對資料庫執行的每一項操作。如果發生當機,這些記錄允許資料庫回滾未完成的交易或還原最近的變更。
  • 冗餘 (Redundancy): 使用重複的硬體(如 RAID 系統),確保單一組件故障不會導致資料遺失或系統停機。


你現在已經掌握了關聯式資料庫的結構與核心原則,這是幾乎所有現代大型應用程式的基礎!請記住,良好的資料庫設計(正規化)是建立可靠、高效系統的關鍵。繼續練習那些 SQL 查詢語法吧!