資料庫原理(索引 / 事務 / 查詢最佳化)
核心問題
為什麼你的 Excel 查詢要 10 秒,而淘寶搜尋只要 0.01 秒? 當資料從「幾千條」變成「十億條」,從「一人使用」變成「千萬人同時存取」,Excel 就不夠用了。資料庫就是為解決這個問題而生的——它是專門處理海量資料、高併發存取的「超級 Excel」。本章將帶你從零開始理解資料庫的核心原理。
1. 為什麼要「資料庫」?
1.1 從小書店到淘寶:資料規模的演變
想像你開了一家小書店,每天賣出幾本書。你隨手在筆記本上記下:
2024-01-15:張三買了《百年孤寂》,59元
2024-01-16:李四買了《活著》,39元這時候,筆記本完全夠用。但當你的書店變成了「亞馬遜」,每天有百萬訂單湧入,問題就出現了:
- 資料量大:不是幾十行,而是幾億行
- 併發存取:不是一個人在查,而是幾千萬人同時存取
- 資料關聯:訂單關聯使用者、商品、庫存、物流……複雜關係需要高效管理
- 資料安全:不能因為斷電就遺失所有訂單
Excel / 筆記本
- 適合個人或小團隊
- 資料量:幾千到幾萬行
- 單人使用,循序存取
- 手動尋找,速度慢
資料庫
- 適合企業級應用
- 資料量:億級以上
- 千萬人同時在線存取
- 毫秒級查詢速度
這就是「資料庫」要解決的問題:如何高效儲存、快速查詢、安全地管理海量資料?
1.2 一個真實的踩坑故事:為什麼不能用 Excel 存使用者資料
你可能會說:「我的專案才幾萬使用者,Excel 不就夠用了嗎?」讓我講一個真實的故事。
小林的創業踩坑記
小林創業做了一個社交應用,剛開始使用者不多,他用 Excel 儲存使用者資訊(姓名、手機、註冊時間等)。每天匯出 Excel 統計使用者成長,一切正常。
當使用者突破 10 萬時,問題開始出現了:
- Excel 開啟要等 5 分鐘
- 篩選「台北的使用者」要卡頓半天
- 有一次 Excel 檔案損毀,幾千個使用者資料永久遺失
最致命的是,他想要實作「查看某個使用者的所有訂單」這個功能——但使用者資訊和訂單分別在不同的 Excel 表裡,他只能手動複製貼上,每次都要花半小時。
後來他請教學長,學長看了一眼就笑了:「你需要的不是 Excel,而是資料庫。」
改用資料庫後,一切都變了:
- 查詢「台北的使用者」只需要 0.01 秒
- 透過「關聯」自動關聯使用者和訂單,一個 SQL 語句搞定
- 資料自動備份,再也不怕檔案損毀
小林從此明白了一個道理:資料量小的時候,什麼都能用;但資料一大,Excel 就是災難。
核心啟示
資料庫不是「更複雜的 Excel」,而是完全不同的設計理念:
- Excel:為小資料、單人使用設計
- 資料庫:為大資料、高併發、複雜關聯設計
選擇合適的工具,能讓你的系統效能提升成千上萬倍。
2. 核心概念:表、行、列、主鍵
這些概念和資料庫有什麼關係?
表、行、列、主鍵就是資料庫的「積木塊」。
想像你要蓋房子:
- 表 = 一個房間(存放一類資料)
- 行 = 房間裡的一個箱子(一條完整記錄)
- 列 = 箱子上的標籤(姓名、年齡等)
- 主鍵 = 箱子的唯一編號(絕對不會重複)
理解這些基礎概念,你才能知道資料是如何組織的。
在深入學習資料庫之前,我們需要先搞清楚這幾個核心概念。為了幫助你理解,我們用圖書館的比喻來類比。
2.1 用圖書館比喻理解資料庫結構
想像你走進一座圖書館,裡面的組織和資料庫驚人地相似:
| 概念 | 圖書館比喻 | 實際作用 | 具體例子 |
|---|---|---|---|
| 資料庫 (Database) | 整座圖書館 | 存放所有資料的容器 | 一個電商網站的資料庫 |
| 表 (Table) | 一個書架 | 存放同一類資料的集合 | 使用者表、商品表、訂單表 |
| 列 (Column) | 書脊上的標籤 | 資料的屬性(欄位) | 姓名、年齡、手機號 |
| 行 (Row) | 書架上的每一本書 | 一條具體的資料記錄 | 「張三,25歲,台北」 |
| 主鍵 (Primary Key) | 每本書的 ISBN 編號 | 唯一識別每一行的 ID | user_id = 1001 |
看個真實例子:使用者表 (users)
| user_id (主鍵) | name | age | city | |
|---|---|---|---|---|
| 1001 | 張三 | 25 | 台北 | zhangsan@example.com |
| 1002 | 李四 | 30 | 上海 | lisi@example.com |
| 1003 | 王五 | 28 | 台北 | wangwu@example.com |
- 表:
users(存放所有使用者資料) - 列:
user_id、name、age、city、email(每個使用者的屬性) - 行:每一行是一個使用者(如「張三,25歲,台北」)
- 主鍵:
user_id(1001、1002、1003,永不重複)
2.2 主鍵 (Primary Key):資料的「身分證號」
什麼是主鍵?
主鍵就是表中每一行的唯一識別,就像身分證號一樣。
關鍵特點:
- 唯一性:絕對不會重複(沒有兩個人有相同的身分證號)
- 非空:必須有值(不可能有「沒有身分證號」的人)
- 不變性:一旦設定,不會修改(你的身分證號不會變)
常見的做法:
- 使用自增整數:1、2、3、4...
- 使用 UUID(全球唯一識別碼):
550e8400-e29b-41d4-a716-446655440000
為什麼需要主鍵?想像一下沒有主鍵的世界:
場景:你想修改「張三」的年齡,但表裡有 3 個「張三」,系統該改哪一個?
-- 沒有主鍵,這會同時修改所有叫「張三」的人!
UPDATE users SET age = 26 WHERE name = '張三';
-- 有主鍵,精確修改
UPDATE users SET age = 26 WHERE user_id = 1001;主鍵的黃金法則:每個表都應該有一個主鍵,而且永遠不要修改它。
2.3 外鍵 (Foreign Key):連接表的橋樑
這是資料庫比 Excel 強大的關鍵——表之間可以建立關聯。
什麼是外鍵?
外鍵是指向另一張表主鍵的列,用來建立表與表之間的關聯。
簡單理解:
- 主鍵 = 我的身分證號
- 外鍵 = 我引用的別人的身分證號
舉個例子:訂單表裡的 user_id 就是外鍵,它指向使用者表的主鍵。
看一個真實的例子:
使用者表 (users):
| user_id (主鍵) | name | phone |
|---|---|---|
| 1001 | 張三 | 138xxxx |
| 1002 | 李四 | 139xxxx |
訂單表 (orders):
| order_id (主鍵) | product_name | price | user_id (外鍵) |
|---|---|---|---|
| 5001 | iPhone 15 | 5999 | 1001 |
| 5002 | MacBook | 14999 | 1001 |
| 5003 | AirPods | 1999 | 1002 |
關鍵理解:
- 訂單表裡的
user_id = 1001指向使用者表裡的user_id = 1001(張三) - 當你要查「訂單 5001 是誰買的」,資料庫會自動去使用者表查找
user_id = 1001的使用者
好處:
- 資料不重複:張三買 100 單商品,他的資訊也只在使用者表存一次
- 易於維護:張三換手機號,只改使用者表,所有訂單自動關聯新手機號
- 靈活查詢:可以輕鬆回答「每個使用者的總消費是多少」這類複雜問題
主键(Primary Key):用户表的 user_id 是主键,唯一标识每个用户。
外键(Foreign Key):订单表的 user_id 是外键,指向用户表的主键。
关联查询:通过外键,数据库可以快速找到"订单 001 是用户 101 买的",然后去用户表查到"用户 101 是张三"。
3. 如何和資料庫對話?SQL 入門與實戰
你不能直接用滑鼠「點」資料庫(雖然有圖形化工具,但本質也是轉換成指令),你需要用一種特殊的語言來指揮資料庫工作。
這種語言就是 SQL (Structured Query Language,結構化查詢語言)。
好訊息是:SQL 非常接近自然英語,讀起來就像在說話。
3.1 SQL 的核心操作:CRUD
大部分時候,你只需要掌握四種操作,江湖人稱 CRUD:
| 操作 | 英文 | SQL 關鍵字 | 通俗理解 |
|---|---|---|---|
| Create | 建立 | INSERT | 新增一筆資料 |
| Read | 讀取 | SELECT | 查詢資料 |
| Update | 更新 | UPDATE | 修改資料 |
| Delete | 刪除 | DELETE | 刪除資料 |
從表格中你能看到什麼?
這四個操作涵蓋了資料處理的全部場景:
- Create:使用者註冊時,插入一筆新使用者記錄
- Read:使用者登入時,查詢使用者名稱和密碼
- Update:使用者修改個人資料時,更新表中的資料
- Delete:使用者註銷帳號時,刪除使用者資料
記住這四個,你就掌握了 80% 的日常 SQL 操作。
3.2 查詢資料 (SELECT):資料庫最常用的操作
查詢是資料庫最重要的功能,也是效能最佳化的關鍵。
示例 1:查找所有台北的使用者
SELECT name, age FROM users WHERE city = '台北';逐詞理解:
SELECT name, age:選擇 name 和 age 這兩列FROM users:從 users 這張表WHERE city = '台北':在 city 等於「台北」的條件下
回傳結果:
| name | age |
|---|---|
| 張三 | 25 |
| 王五 | 28 |
示例 2:查找價格在 5000 到 15000 之間的商品
SELECT name, price FROM products
WHERE price BETWEEN 5000 AND 15000;示例 3:模糊搜尋(查找名字包含「張」的使用者)
SELECT name FROM users WHERE name LIKE '%張%';效能陷阱:LIKE 的使用
LIKE '%張%' 會導致全表掃描,資料量大時非常慢。
最佳化建議:
- 不要用
LIKE '%張%'(前後都有 %) - 可以用
LIKE '張%'(只有後面有 %)
因為 LIKE '張%' 可以利用索引,而 LIKE '%張%' 無法使用索引。
3.3 插入資料 (INSERT):新增記錄
示例:新增一個使用者
INSERT INTO users (user_id, name, age, city, email)
VALUES (1004, '趙六', 35, '高雄', 'zhaoliu@example.com');逐詞理解:
INSERT INTO users:插入到 users 表(user_id, name, age, city, email):指定要插入的列VALUES (1004, '趙六', ...):對應的值
批量插入(更高效):
INSERT INTO users (name, age, city) VALUES
('小明', 25, '台北'),
('小紅', 28, '上海'),
('小剛', 30, '高雄');3.4 更新資料 (UPDATE):修改記錄
示例:給所有台北的使用者年齡加 1
UPDATE users SET age = age + 1 WHERE city = '台北';非常危險:別忘了 WHERE!
如果你忘記寫 WHERE 子句,會修改所有行!
-- 危險!會把所有使用者的年齡都改成 26
UPDATE users SET age = 26;
-- 正確:只修改 user_id = 1001 的使用者
UPDATE users SET age = 26 WHERE user_id = 1001;真實教訓:2012 年,某知名公司因為工程師忘記寫 WHERE,導致正式環境數百萬使用者資料被錯誤更新,系統癱瘓 4 小時,損失巨大。
3.5 刪除資料 (DELETE):刪除記錄
示例:刪除 user_id = 1004 的使用者
DELETE FROM users WHERE user_id = 1004;雙重危險:DELETE 更需要 WHERE!
-- 危險!會刪除整張表的所有資料!
DELETE FROM users;
-- 正確:只刪除指定行
DELETE FROM users WHERE user_id = 1004;最佳實踐:
- 刪除前先用 SELECT 確認資料
- 在重要系統中,使用「軟刪除」(新增
is_deleted欄位標記刪除) - 正式環境操作前先備份資料
3.6 多表查詢 (JOIN):資料庫的魔法時刻
還記得我們講過的「外鍵」嗎?SQL 最強大的地方在於可以一次性查詢多張關聯的表。
場景:查詢「張三買過的所有商品」
假設我們有三張表:
使用者表 (users):
| user_id | name |
|---|---|
| 1001 | 張三 |
商品表 (products):
| product_id | name | price |
|---|---|---|
| 201 | iPhone 15 | 5999 |
| 202 | MacBook | 14999 |
訂單表 (orders):
| order_id | user_id | product_id | quantity |
|---|---|---|---|
| 5001 | 1001 | 201 | 1 |
| 5002 | 1001 | 202 | 2 |
SQL 查詢:
SELECT u.name, p.name AS product_name, p.price, o.quantity
FROM orders o
JOIN users u ON o.user_id = u.user_id
JOIN products p ON o.product_id = p.product_id
WHERE u.name = '張三';回傳結果:
| name | product_name | price | quantity |
|---|---|---|---|
| 張三 | iPhone 15 | 5999 | 1 |
| 張三 | MacBook | 14999 | 2 |
理解 JOIN 的過程:
FROM orders o:從訂單表開始JOIN users u ON o.user_id = u.user_id:透過 user_id 關聯使用者表JOIN products p ON o.product_id = p.product_id:透過 product_id 關聯商品表WHERE u.name = '張三':篩選張三的訂單
SELECT name, age FROM users WHERE age > 25;4. 為什麼資料庫這麼快?索引原理揭密
這是資料庫最神奇的地方,也是面試中最愛問的問題。
如果你在 Excel 裡查找「所有姓張的人」,Excel 需要從第一行掃到最後一行。這就是全表掃描——資料越多,速度越慢。
但在資料庫裡,即使有 10 億行資料,查找也只需要幾毫秒。
秘訣就是:索引 (Index)。
4.1 直觀理解:字典的啟示
想像你要在一本沒有目錄的 1000 頁書裡找一個詞。你該怎麼辦?
只能一頁一頁翻——這就是全表掃描,平均需要翻 500 頁。
但如果這本書有注音索引呢?
你要找「資料庫」這個詞:
- 翻到索引,找到「資」字開頭的區域
- 在「資」字區域內,找「料」字
- 索引告訴你:在第 256 頁
你只需要翻 3 次就能找到!這就是索引查找。
資料庫的索引就像書的目錄:
- 沒有索引:逐行掃描(10 億行 = 數分鐘)
- 有索引:直接跳轉(10 億行 = 3 次磁碟 I/O = 幾毫秒)
4.2 全表掃描 vs 索引查找:速度對比
假設我們有一張使用者表,有 1000 萬條記錄。
場景:查找 user_id = 5,555,555 的使用者
| 方式 | 過程 | 需要檢查的行數 | 耗時估算 |
|---|---|---|---|
| 全表掃描 | 從第 1 行開始,一行一行看 | 平均 500 萬行 | 5-30 秒 |
| 索引查找 | 查索引樹,直接跳到目標位置 | 3-4 次比較 | 0.003 秒 |
速度差距:數千倍!
核心啟示
索引不是銀彈,它有代價:
- 佔用空間:索引需要額外的儲存空間
- 降低寫入速度:每次 INSERT/UPDATE/DELETE 都要更新索引
什麼時候建索引?
- 經常用來查詢的列(WHERE、JOIN 的條件)
- 資料量大(幾千行以下不需要)
什麼時候不建索引?
- 很少查詢的列
- 頻繁更新的列
- 資料量小的表
4.3 底層資料結構:B+ 樹
真實的索引不是簡單的「字母列表」,而是一種精心設計的資料結構,叫做 B+ 樹 (B+ Tree)。
什麼是 B+ 樹?
B+ 樹是一種「矮胖」的樹形資料結構:
- 矮:從根到葉子通常只有 3-4 層
- 胖:每個節點可以儲存幾百個鍵值
為什麼要「矮胖」?
因為資料儲存在磁碟上,每次讀取磁碟(I/O)都非常慢(比記憶體慢幾千倍)。B+ 樹的設計目標就是盡量減少磁碟 I/O 次數。
- 3-4 層高度 = 最多 3-4 次磁碟讀取
- 每層存大量資料 = 保證樹不會太高
真實例子:
假設一棵 B+ 樹的每個節點可以儲存 1000 個鍵值:
- 根節點:1000 個鍵值 → 指向 1000 個子節點
- 中間節點:每個存 1000 個鍵值 → 指向 1000 個葉子節點
- 葉子節點:每個存 1000 條真實資料
總資料量 = 1000 × 1000 × 1000 = 10 億條資料
樹的高度 = 3 層
這意味著:在 10 億條資料中查找任意一條,只需要 3 次磁碟 I/O!
這就是資料庫查詢飛快的秘密。
👆 点击"开始查找"看全表扫描有多慢
👆 点击"开始查找"看索引有多快
5. 事務:如何保證資料不丟、不亂?
想像一下春運搶票的場景:
- 時間 T1:使用者 A 查詢,發現「G1234 次列車還剩 1 張票」
- 時間 T2:使用者 B 也查詢,也發現「還剩 1 張票」
- 時間 T3:使用者 A 點擊「購買」,系統扣庫存,票賣給了 A
- 時間 T4:使用者 B 點擊「購買」——如果沒有保護機制,系統會再次扣庫存,把同一張票賣給 B!
這就是典型的併發衝突問題。
5.1 什麼是事務 (Transaction)?
事務是資料庫的一組操作,這些操作要麼全部成功,要麼全部失敗,不會出現「做了一半」的情況。
生活中的例子
銀行轉帳就是一個典型的事務:
- 從帳戶 A 扣除 100 元
- 給帳戶 B 增加 100 元
如果第 1 步成功了,但第 2 步失敗了(比如斷電),會發生什麼?
- 沒有事務:帳戶 A 的錢沒了,帳戶 B 沒收到錢,錢 憑空消失了
- 有事務:系統發現第 2 步失敗,自動回滾第 1 步,兩個帳戶都恢復原狀
這就是事務的原子性:要麼全做,要麼全不做。
5.2 事務的四大特性 (ACID)
事務有四大特性,簡稱 ACID:
| 特性 | 英文 | 含義 | 銀行轉帳的例子 |
|---|---|---|---|
| Atomicity | 原子性 | 要麼全做,要麼全不做 | 扣款和入帳必須同時成功,不能只扣錢不入帳 |
| Consistency | 一致性 | 資料始終保持合法狀態 | 轉帳前後,兩個帳戶的總金額應該不變 |
| Isolation | 隔離性 | 多個事務互不影響 | A 在轉帳時,B 看到的應該是「轉帳前」或「轉帳後」的餘額,不能看到中間狀態 |
| Durability | 持久性 | 一旦提交,資料永久儲存 | 轉帳成功後,即使斷電,帳戶餘額也不會變回去 |
從表格中你能看到什麼?
這四個特性保證了資料的安全性:
- 原子性:防止「做一半」(扣了錢但沒到帳)
- 一致性:防止資料不合理(轉帳後總金額變了)
- 隔離性:防止併發衝突(兩個人同時修改同一資料)
- 持久性:防止資料遺失(提交後斷電也不影響)
沒有這些保證,銀行系統根本無法運行。
5.3 事務的隔離級別:權衡安全與效能
理論上,我們希望事務完全隔離。但完全隔離 = 效能極差(因為需要大量加鎖,其他事務只能等待)。
因此,資料庫提供了四種隔離級別:
| 隔離級別 | 髒讀 | 不可重複讀 | 幻讀 | 效能 | 適用場景 |
|---|---|---|---|---|---|
| 讀未提交 | 可能 | 可能 | 可能 | 最快 | 幾乎不用(資料可能錯誤) |
| 讀已提交 | 不可能 | 可能 | 可能 | 較快 | 普通業務(Oracle 預設) |
| 可重複讀 | 不可能 | 不可能 | 可能 | 中等 | 銀行轉帳(MySQL 預設) |
| 串行化 | 不可能 | 不可能 | 不可能 | 最慢 | 極端嚴格場景(極少用) |
三個「讀」是什麼意思?
- 髒讀:讀到了其他事務還沒提交的資料(可能回滾,資料不準確)
- 不可重複讀:同一事務裡,兩次讀同一資料,結果不一樣(被其他事務修改了)
- 幻讀:同一事務裡,兩次查詢,結果集的行數不一樣(其他事務插入/刪除了資料)
通俗例子(銀行查餘額):
- 髒讀:你查到餘額 1000 元,但對方事務回滾了,實際只有 100 元
- 不可重複讀:你第一次查餘額 1000 元,第二次查變成 800 元(被扣款了)
- 幻讀:你第一次查到 5 筆交易,第二次查變成 6 筆(新增了一筆)
场景:用户 A 和 B 同时看到还剩 1 张票,同时点击购买。
没有事务:A 扣库存,B 也扣库存,同一张票卖给了两个人!
有事务(隔离性):A 的操作加锁,B 必须等待。A 买完后,库存变为 0,B 看到的是"已售罄"。
6. 效能最佳化:讓查詢快 1000 倍的實戰技巧
現在你已經理解了索引、事務這些核心概念。但在真實專案中,你可能會遇到各種效能問題。
本節將給出可直接落地的最佳化策略。
6.1 索引使用避坑指南
常見錯誤:索引失效的坑
很多時候,你明明建了索引,但查詢還是很慢——因為索引失效了。
導致索引失效的常見原因:
- 在索引列上使用函式
- 隱式類型轉換
- LIKE 查詢以 % 開頭
- OR 條件(部分情況)
- 複合索引不滿足最左前綴原則
坑 1:在索引列上使用函式
-- 錯誤:對索引列使用函式,無法使用索引
SELECT * FROM users WHERE YEAR(created_at) = 2024;
-- 正確:改寫為範圍查詢,可以使用索引
SELECT * FROM users
WHERE created_at >= '2024-01-01' AND created_at < '2025-01-01';坑 2:隱式類型轉換
-- 假設 user_id 是 int 類型
-- 錯誤:傳字串,導致隱式轉換,無法使用索引
SELECT * FROM users WHERE user_id = '123';
-- 正確:傳對應類型
SELECT * FROM users WHERE user_id = 123;坑 3:LIKE 以 % 開頭
-- 錯誤:以 % 開頭,無法使用索引
SELECT * FROM users WHERE name LIKE '%張三%';
-- 正確:以固定前綴開頭,可以使用索引
SELECT * FROM users WHERE name LIKE '張三%';
-- 或者使用全文索引(適用於文字搜尋)
SELECT * FROM users WHERE MATCH(name) AGAINST('張三');6.2 SQL 最佳化實戰模板
模板 1:分頁最佳化(深分頁問題)
查看問題與解決方案
-- 問題:OFFSET 很大時,查詢越來越慢
SELECT * FROM orders
ORDER BY created_at DESC
LIMIT 10 OFFSET 1000000;
-- 最佳化方案 1:使用上次查詢的時間戳記作為游標
SELECT * FROM orders
WHERE created_at < '2024-01-15 12:00:00'
ORDER BY created_at DESC
LIMIT 10;
-- 最佳化方案 2:使用主鍵範圍查詢
SELECT * FROM orders
WHERE order_id > 1000000
ORDER BY order_id
LIMIT 10;模板 2:批量插入最佳化
-- 低效:多次單條插入(網路往返多次)
INSERT INTO users (name, age) VALUES ('張三', 25);
INSERT INTO users (name, age) VALUES ('李四', 30);
INSERT INTO users (name, age) VALUES ('王五', 28);
-- 高效:單條 SQL 批量插入(只需一次網路往返)
INSERT INTO users (name, age) VALUES
('張三', 25),
('李四', 30),
('王五', 28);**模板 3:避免 SELECT ***
-- 低效:回傳所有列(包括不需要的大欄位)
SELECT * FROM users WHERE user_id = 1;
-- 高效:只回傳需要的列
SELECT user_id, name, email FROM users WHERE user_id = 1;6.3 高併發場景應對策略
| 場景 | 問題 | 解決方案 |
|---|---|---|
| 熱點資料 | 某行資料被頻繁讀寫,導致鎖競爭 | 使用快取(Redis)+ 讀寫分離 |
| 秒殺場景 | 瞬間高併發扣減庫存 | 樂觀鎖 + 庫存預熱 + 訊息佇列削峰 |
| 慢查詢 | 複雜查詢拖垮資料庫 | 索引最佳化 + 查詢拆分 + 讀寫分離 |
| 連線數耗盡 | 太多併發請求導致連線池耗盡 | 連線池最佳化 + 限流 + 服務降級 |
核心啟示
效能最佳化的基本原則:
- 先測量,後最佳化:用
EXPLAIN分析查詢計畫,找到真正的瓶頸 - 索引優先:80% 的效能問題都可以透過最佳化索引解決
- 減少資料庫壓力:能用快取就用快取,能非同步就非同步
- 分而治之:大表拆分成小表,大查詢拆分成小查詢
7. 總結與學習路線
讓我們用一張表格來回顧資料庫的核心概念:
| 概念 | 一句話解釋 | 解決的問題 | 關鍵點 |
|---|---|---|---|
| 表、行、列 | 資料的組織方式 | 如何儲存結構化資料 | 表 = Excel 工作表,行 = 記錄,列 = 欄位 |
| 主鍵 | 每行的唯一識別 | 如何精確找到一行資料 | 唯一、非空、不變 |
| 外鍵 | 連接表的橋樑 | 如何關聯不同表的資料 | 指向另一張表的主鍵 |
| SQL | 和資料庫對話的語言 | 如何增刪改查資料 | SELECT、INSERT、UPDATE、DELETE |
| 索引 | 加速查詢的資料結構 | 如何快速找到資料 | B+ 樹,減少磁碟 I/O |
| 事務 | 保證資料安全的機制 | 如何防止併發衝突和遺失資料 | ACID:原子性、一致性、隔離性、持久性 |
寫在最後
資料庫是一個博大精深的主題,本文只是入門。如果你想繼續深入學習,建議按以下路線:
下一步學習:
- 動手實踐:安裝 MySQL 或 PostgreSQL,建立表、插入資料、寫 SQL 查詢
- ORM 框架:學習如何在程式碼中使用資料庫(如 SQLAlchemy、Prisma、TypeORM)
- 索引最佳化:深入研究複合索引、覆蓋索引、索引下推等進階主題
- 事務原理:了解 MVCC(多版本併發控制)、鎖機制、隔離級別實作
- 分散式資料庫:學習分庫分表、讀寫分離、主從複製等架構
記住:理論 + 實踐 = 真正的掌握。