歡迎來到資料庫的世界!

你有沒有想過 Spotify 是如何追蹤數以百萬計的歌曲,或者學校是如何管理成千上萬名學生的資料而不遺失任何記錄的呢?祕密就在於資料庫 (Databases)!在本章中,我們將學習如何整理資訊,使其易於搜尋、更新並確保其安全性。如果一開始覺得術語很多也不用擔心;只要把資料庫想像成一個非常聰明的數位檔案櫃就可以了。


1. 建構基礎:資料表、記錄與欄位

在建立複雜系統之前,我們需要先了解關聯式資料庫 (Relational Database) 的基本結構。

資料庫由什麼組成?

想像一下班級名單的試算表:

  • 資料表 (Table): 關於特定主題的完整資料集合(例如:「學生」資料表)。
  • 記錄 (Record 或 Row): 單一水平條目。它代表一個「個體」(例如:某位特定的學生)。
  • 欄位 (Field 或 Column): 單一垂直類別。它代表一個「屬性」或特徵(例如:「電話號碼」或「出生日期」)。
  • 屬性 (Attribute): 這只是欄位的另一個名稱。它描述了實體的一種特性。

快速複習: 如果你有一張「圖書」資料表,作者就是一個欄位,而《哈利波特:神秘的魔法石》則是某條記錄的一部分。


2. 資料庫的「鍵」(Keys)

在資料庫中,我們需要透過某些方式來識別資料並連結不同的資料表,我們稱之為鍵 (Keys)

鍵的類型

  • 主鍵 (Primary Key): 每條記錄的唯一識別碼。沒有兩條記錄可以擁有相同的主鍵。例如:你的學號或身份證號碼。
  • 複合鍵 (Composite Key): 當單一欄位不足以成為唯一識別碼時,我們會結合兩個或多個欄位來組成。例如:結合「課程編號」與「學生編號」來識別特定的選修記錄。
  • 外鍵 (Foreign Key): 資料表中的一個欄位,它是另一個資料表中的主鍵。這是我們用來「連結」資料表的方式。
  • 次要鍵 (Secondary Key): 不是主鍵,但經常被用於搜尋資料的欄位。例如:不使用學號,而是以「姓氏」來搜尋學生。

記憶小撇步: 可以把主鍵想像成你的指紋(對你而言是獨一無二的),而外鍵則像是一封推薦信(它指向另一個人)。


3. 資料冗餘與相依性

一個好的資料庫應該要「精簡有效」。我們需要避免兩個大問題:

資料冗餘 (Data Redundancy)

當相同的資料存放在多個地方時,就會發生這種情況。例如:將學生的住址寫在五個不同的資料表中。
為什麼這很糟糕? 它不僅浪費儲存空間,還會導致「更新異常 (Update Anomalies)」——如果學生搬家了,你可能忘記在五個地方同時更新,導致資料不一致。

資料相依性 (Data Dependency)

這指的是欄位之間的關係。我們希望欄位依賴於主鍵。如果某項資訊(例如「醫生的電話號碼」)依賴於主鍵以外的其他東西(例如「醫生的姓名」),當資料被刪除或更改時,就會造成混亂。

關鍵總結: 我們要減少冗餘,以確保資料準確並節省空間!


4. 正規化:打造完美資料庫的三個步驟

正規化 (Normalization) 是透過整理資料庫來減少冗餘的過程。對於 H2 Computing 課程,你需要知道如何將資料表達到第三正規化 (3NF)

逐步流程

  1. 第一正規化 (1NF): 移除「重複群組」。每個儲存格必須只包含一個單一值(原子值)。格子裡不准出現列表!
  2. 第二正規化 (2NF): 必須先達到 1NF。接著,移除部分相依 (Partial Dependencies)。這意味著每個欄位必須依賴於整個主鍵(這通常只有在你擁有複合鍵時才會成為問題)。
  3. 第三正規化 (3NF): 必須先達到 2NF。接著,移除傳遞相依 (Transitive Dependencies)。這意味著「非鍵欄位不應依賴於其他非鍵欄位」。

記憶口訣: 要達到 3NF,欄位必須依賴:「主鍵 (1NF)、整個主鍵 (2NF),以及除了主鍵之外什麼都不依賴 (3NF),上帝保佑 Codd!」(E.F. Codd 是這套系統的發明者)。


5. 實體關聯圖 (ER Diagrams)

ER 圖是用來呈現資料表之間如何關聯的地圖。它使用方框與線條來表示連結。

  • 實體 (Entity): 用矩形表示(例如:[學生])。
  • 關聯 (Relationship): 它們之間的連線。

常見的關聯類型

  • 一對一 (1:1): 一個人只有一本護照。
  • 一對多 (1:M): 一位母親可以有多個孩子。(這是資料庫中最常見的!)
  • 多對多 (M:N): 許多學生修讀許多科目。注意:在實際資料庫中,我們通常會使用「連結資料表」將其拆解為兩個 1:M 的關聯。

6. SQL:與資料庫溝通

結構化查詢語言 (SQL) 是我們用來「向資料庫索取」資訊或進行修改的語言。

必要的 SQL 指令

  • SELECT: 用於選擇你想要查看的欄位。
  • FROM: 資料來自哪個資料表。
  • WHERE: 過濾資料(像是一種「搜尋」條件)。
  • ORDER BY: 排序結果(ASC 為遞增,DESC 為遞減)。
  • INSERT INTO: 新增一條記錄。
  • UPDATE: 修改現有資料。
  • DELETE: 刪除記錄。
  • JOIN: 根據相關欄位合併兩個或多個資料表的資料列。

查詢範例:
SELECT Name, Score FROM Students WHERE Score > 70 ORDER BY Score DESC;
(這會顯示所有分數高於 70 分的學生姓名與分數,並按分數從高到低排列。)


7. SQL vs. NoSQL:現代選擇

傳統資料庫使用 SQL 和嚴格的資料表。但有時資料過於混亂或變動太快,這時 NoSQL 就派上用場了。

兩者比較

SQL (關聯式):

  • 使用具有列和欄的結構化資料表。
  • 非常適合資料「形狀」不常改變的場景(例如:銀行帳戶)。
  • 強一致性(資料在系統中永遠保持準確)。

NoSQL (非關聯式):

  • 解決了如擴展性 (Scaling) 等短處(NoSQL 可以輕鬆處理跨多個伺服器的海量資料)。
  • 靈活的「架構」(Schema)(不需要固定的資料表;資料可以儲存為文件、圖形或鍵值對)。
  • 非常適合「大數據」和即時 Web 應用(例如:社交媒體動態牆)。

你知道嗎? SQL 資料庫就像一座圖書館(組織嚴謹,每樣東西都有特定位置),而 NoSQL 就像一個洗衣籃(容易快速丟入物品,靈活彈性,但尋找東西時需要不同的方式)。


8. 在 Python 中操作資料庫

在實作考試中,你很可能會使用 Python 中的 sqlite3 模組來操作 SQL 資料庫。

Python-SQL 工作流程

  1. 連線 (Connect): 建立與資料庫檔案的連線。
  2. 游標 (Cursor): 建立一個「游標」物件(把它想像成執行指令的數位「指針」)。
  3. 執行 (Execute): 使用 cursor.execute("SQL 指令")
  4. 提交 (Commit): 使用 connection.commit() 來儲存你的變更!
  5. 關閉 (Close): 完成後務必關閉連線。

常見錯誤: 忘記提交 (commit)!如果你不提交,你的 INSERTUPDATE 指令就不會儲存到檔案中,到時候你就會納悶資料怎麼消失了!


快速複習箱

主鍵 (Primary Key): 唯一 ID。
外鍵 (Foreign Key): 連結到另一個資料表。
正規化 (Normalization): 減少資料重複(冗餘)。
1NF: 儲存格內沒有列表。
2NF: 沒有部分相依。
3NF: 沒有傳遞相依。
SQL: 資料庫的語言。
NoSQL: 靈活,比 SQL 更擅長處理「大數據」。