MODULE 6 · PART 2 · UNIT 2.2
資料的身分證與認親線索
Unit 2.1 你學會設計一張表。但真實的 App 有 users、orders、products 很多張表,它們得認得彼此。 這個 unit 講兩個角色:Primary Key 是每筆資料的唯一身分證,Foreign Key 是表跟表之間的認親線索。 最後你會親手製造「孤兒資料」,再用刪除策略把資料一致性守回來。
§1 · 從一張表到很多表
orders 怎麼知道哪筆是誰買的?
把使用者、訂單、商品分開存(這是上個 Part 講的正規化)。但分開之後,要怎麼把它們連回去?
table: orders
id · user_id · item
101 · ? · 鍵盤
102 · ? · 滑鼠
要把它們連回去,靠兩個角色。先用兩張圖建立直覺,後面 §2、§3 再實際動手操作。
概念Primary Key(PK)唯一身分證
每張表都需要一個欄位,能唯一指認每一筆資料,通常就叫 id。它就像身分證字號,不會重複、不會空白:報出一個號碼,就只會對到一個人。
報號點名:
概念Foreign Key(FK)認親線索
一張表用一個欄位指向另一張表的 PK。orders 的 user_id 存的就是某位使用者的 id,就像訂單上寫著主人的會員編號,照號碼就能認親。
訂單的 user_id:
✓ #101 的 user_id=1,認到 users.id=1(小明)。
下面 §2 先看 PK 怎麼保證唯一,§3 再看 FK 怎麼認親。
§2 · Primary Key
唯一身分證:id 不准重複
PK 是每筆資料的唯一識別。資料庫會強制它不重複、不為空,這樣你才永遠指得到某一筆特定資料。
table: users(id = PRIMARY KEY)
🔑VIBE CODER 秘訣
👀觀察
AI 通常會自動加 id 主鍵,這點還不錯。但有時為了「方便」會拿 email、手機號這種會變動的自然鍵當主鍵。
💬怎麼跟 AI 講
「每張表都用一個獨立的代理主鍵(自動遞增 id 或 UUID),不要拿 email、手機這種會變的欄位當主鍵。」
§3 · Foreign Key
認親線索:user_id 指向 users.id
點一筆訂單,看它的 user_id 指到哪位使用者。再改改看 user_id,把它指向不存在的人會怎樣。
table: users
id=1 · 小明
id=2 · 小華
id=3 · 小美
table: orders(user_id = FOREIGN KEY → users.id)
🔑VIBE CODER 秘訣
👀觀察
FK 不只是一個「指過去」的欄位,它還會幫你檢查:寫進去的 user_id 必須真的存在,不然拒收。很多 AI 給的 schema 只放了 user_id 欄位,卻沒宣告 FK 約束,那層保護就沒了。
💬怎麼跟 AI 講
「orders.user_id 要加上 REFERENCES users(id) 的外鍵約束,不要只放一個普通的 id 欄位。」
§4 · 一對多
一個使用者,可以有很多筆訂單
這叫「一對多(one-to-many)」關係。一邊是 1(使用者),另一邊是 N(他的訂單),靠 FK 串起來。
小明目前有 2 筆訂單(每筆的 user_id 都是 1) 🔑VIBE CODER 秘訣
👀觀察
「一對多」是最常見的關係。AI 通常處理得不錯,但偶爾會把本該分開的多筆資料硬塞進一個欄位(例如把多筆訂單存成一串逗號分隔的字串)。
💬怎麼跟 AI 講
「這是一對多關係,請開獨立的子表用 FK 連回去,不要把多筆資料塞進單一欄位。」
§5 · 孤兒資料
刪掉使用者,他的訂單變成「孤兒」
如果沒有保護,刪掉小明之後,那些 user_id=1 的訂單還指著一個已經不存在的人。
table: orders
#101user_id=1· 鍵盤
#102user_id=2· 滑鼠
#103user_id=1· 螢幕
好消息是:只要宣告了 FK 約束,資料庫預設就不准你這樣刪。下面 §6 看你可以選哪幾種處理方式。
§6 · 關聯保護
刪除時,FK 幫你守住一致性
宣告 FK 時可以指定 ON DELETE 策略,決定「父資料被刪時,子資料怎麼辦」。選一個,再刪小明試試。
table: orders
#101user_id=1· 鍵盤
#102user_id=2· 滑鼠
#103user_id=1· 螢幕
概念RESTRICT(預設)
最安全。還有子資料就不准刪父資料,逼你想清楚。轉帳、訂單這種不能掉的場景用它。
概念CASCADE
父資料刪掉,子資料連帶刪光。例如刪掉一個聊天室,底下訊息也一起清掉。用前要很確定。
概念SET NULL
父資料刪掉,子資料留著但失去關聯。例如員工離職,他建立的紀錄保留但「建立者」設為空。
🔑VIBE CODER 秘訣
👀觀察
AI 給的刪除功能常常直接 DELETE FROM users,沒考慮關聯資料。沒 FK 約束時會留下孤兒;有約束但策略選錯時,可能誤刪一票資料(CASCADE)或刪不掉(RESTRICT)。
💬怎麼跟 AI 講
「這個刪除會牽動關聯資料嗎?FK 的 ON DELETE 該用 RESTRICT、CASCADE 還是 SET NULL?請按業務語意選,預設用 RESTRICT 最安全。」
§7 · 小測驗
PK、FK、刪除策略,你選得對嗎?
一樣答錯不鎖死,黃色提示陪你想清楚。
收尾 · Part 2 前兩個 unit
你現在能看懂 AI 給的 schema 了
把這兩個 unit 的直覺收進口袋,跟 AI 一起設計資料模型時隨時拿出來用。
UNIT 2.1 型態直覺
- · 看到「金額」想到 DECIMAL / 整數分,絕不用 FLOAT
- · 看到「會排序的編號」想到別存字串
- · 看到「開關」想到 BOOLEAN,小心字串 "false"
- · 看到「時間」想到 TIMESTAMPTZ,存 UTC
- · 看到 schema 沒約束,想到補 NOT NULL / CHECK / DEFAULT
UNIT 2.2 關聯直覺
- · 每張表都要一個獨立的代理主鍵(id)
- · 關聯欄位要宣告 FK(REFERENCES),不只放 id
- · 一對多用子表 + FK,多對多用中間表
- · 刪資料前先想關聯,預設 ON DELETE RESTRICT 最安全
- · 看到孤兒資料,回頭檢查 FK 約束有沒有少
資料型態跟 PK / FK,是 schema 的兩根支柱。型態管「每一格裝什麼」,PK / FK 管「表跟表怎麼連」。 這兩件事 AI 都會幫你做,但它常常為了「能跑、寫得快」而偷工:型態用 TEXT 通吃、關聯不加約束。 你現在看得懂、也問得出對的問題,這就是 vibe coder 跟一般使用者最大的差別。
下一個 unit 我們會把這些表組成完整的資料地圖,學會跟 AI 一起設計一份能長大、少踩遷移地獄的 schema。我們下個 unit 見。