Logo

新人日誌

首頁關於我部落格

新人日誌

Logo

網站會不定期發佈技術筆記、職場心得相關的內容,歡迎關注本站!

網站
首頁關於我部落格
部落格
分類系列文

© 新人日誌. All rights reserved. 2020-present.

關聯式資料庫入門:設計資料表的基本流程

最後更新:2026年1月5日資料庫

前面的文章我們學會了:

  • 如何找出個體和關係
  • 為什麼要分成多張表
  • 如何透過關聯避免重複資料

這篇文章會透過三個實際案例,從簡單到複雜,讓你練習如何把日常生活中的資訊轉換成資料表。你會發現,有些看似簡單的句子,背後其實藏著複雜的結構。

範例一:一句話拆成三張表

原始資訊

David 在 3 月 11 日去吃了「饗食天堂」這家吃到飽餐廳。

找出個體

這句話裡有哪些「東西」?

  • David:一個人
  • 饗食天堂:一家餐廳

人和餐廳是不同類型的東西,所以要分成兩張表。

找出關係

David 和餐廳之間有什麼關係?

  • 用餐:David 去這家餐廳用餐

找出性質

  • 餐廳有一個性質:餐廳類型(吃到飽)
  • 用餐關係有一個性質:用餐日期(3 月 11 日)

設計資料表

設計資料表的順序是:先把表開好,再把性質加進去。

第一步:先開個體表

我們有兩種個體:人物和餐廳,所以先開兩張表。

人物表:

名稱
David

餐廳表:

名稱
饗食天堂

第二步:把個體的性質加進去

餐廳有一個性質「餐廳類型」,把它加到餐廳表:

餐廳表:

名稱餐廳類型
饗食天堂吃到飽
餐廳類型吃到飽

第三步:開關係表

David 和餐廳之間有「用餐」這個關係,所以開一張用餐表:

用餐表:

人物餐廳
David饗食天堂
餐廳饗食天堂

第四步:把關係的性質加進去

用餐關係有一個性質「用餐日期」,把它加到用餐表:

用餐表:

人物餐廳用餐日期
David饗食天堂3/11
餐廳饗食天堂
用餐日期3/11

小結

短短一句話,就需要三張表來記錄:

  1. 人物表:記錄人物的基本資料
  2. 餐廳表:記錄餐廳的基本資料和類型
  3. 用餐表:記錄誰在什麼時候去哪家餐廳用餐

範例二:當關係指向另一個關係

原始資訊

胖虎欺負大雄這件事,引起了靜香的反感。

找出個體

  • 胖虎、大雄、靜香:三個人

找出關係

這裡有兩個關係:

  1. 欺負:胖虎欺負大雄
  2. 反感:靜香對某件事反感

分析關係的結構

欺負關係:

「胖虎欺負大雄」可以抽象成「A 欺負 B」的結構。

這個關係是非對稱的:A 欺負 B 不等於 B 欺負 A。胖虎欺負大雄,不代表大雄欺負胖虎。

欺負的人被欺負的人
胖虎大雄
被欺負的人大雄

其他可能的情況:

欺負的人被欺負的人
胖虎大雄
小夫大雄
大雄哆啦A夢
被欺負的人大雄
被欺負的人大雄
被欺負的人哆啦A夢

反感關係:

靜香反感的是什麼?

  • 不是反感胖虎這個人
  • 不是反感大雄這個人
  • 是反感「胖虎欺負大雄」這件事

也就是說,反感的對象是一個「關係」,不是一個「個體」。

還記得我們說過「個體和關係之間也可以有關係」嗎?這就是一個例子:

  • 欺負關係:胖虎(個體)和大雄(個體)之間
  • 反感關係:靜香(個體)和「欺負關係」(關係)之間

設計資料表

人物表:

名稱
胖虎
大雄
靜香

欺負表:

欺負的人被欺負的人
胖虎大雄
被欺負的人大雄

反感表:

反感的人反感的對象
靜香胖虎欺負大雄的關係
反感的對象胖虎欺負大雄的關係

關聯的運用

注意:欺負表中的「胖虎」和「大雄」都會關聯回人物表。

如果胖虎有其他性質(例如:體重 80 公斤),需要記錄在欺負表嗎?

不需要。 回去查人物表就好。

這就是關聯的好處:每個人的資料只存在人物表一個地方,其他表只需要記錄「是誰」,詳細資料透過關聯查詢。

範例三:簡單的句子,複雜的結構

原始資訊

因為現在週年慶,全館商品免運。

這句話有多複雜?

表面上看起來很簡單,但仔細想想:

  • 什麼是「商品」?
  • 什麼是「運費」?
  • 「免運」要怎麼記錄?

拆解「商品」的概念

「商品」這個詞其實包含了好幾個東西:

  1. 品項:球棒、球鞋…
  2. 消費者:誰要買這些東西
  3. 交易關係:消費者購買品項的這個動作

那「運費」呢?運費要放在哪裡?

仔細想想,運費其實也是一種「你要付錢的東西」,跟球棒、球鞋的性質很像。差別只在於:球棒是實體商品,運費是服務。

所以我們可以把運費也當成一種「品項」來處理:

  1. 品項:球棒、球鞋、運費…
  2. 消費者:誰要買這些東西
  3. 交易關係:消費者購買品項的這個動作

這樣一來,「免運」就變成很單純的事情:運費這個品項的金額設為 0 元。

第一版:單一交易表的設計

假設胖虎在 3 月 20 日買了一支球棒,我們可以這樣設計:

品項表:

品項名稱價格
球棒500
運費60
價格500
價格60

交易表:

消費者品項下單日期
胖虎球棒3/20
胖虎運費3/20
品項球棒
下單日期3/20
品項運費
下單日期3/20

問題:怎麼知道哪些品項是同一筆訂單?

胖虎買了球棒,也付了運費。但從上面的表格,我們怎麼知道這兩筆是「同一筆訂單」?

如果胖虎在 3 月 20 日買了兩次東西呢?

消費者品項下單日期
胖虎球棒3/20
胖虎運費3/20
胖虎球鞋3/20
胖虎運費3/20
品項球棒
下單日期3/20
品項運費
下單日期3/20
品項球鞋
下單日期3/20
品項運費
下單日期3/20

哪個運費是球棒的?哪個運費是球鞋的?分不清楚了。

第二版:加入訂單編號識別同一筆交易

我們需要一個「訂單編號」來識別同一筆交易:

訂單編號消費者品項下單日期
1胖虎球棒3/20
1胖虎運費3/20
2胖虎球鞋3/20
2胖虎運費3/20
消費者胖虎
品項球棒
下單日期3/20
消費者胖虎
品項運費
下單日期3/20
消費者胖虎
品項球鞋
下單日期3/20
消費者胖虎
品項運費
下單日期3/20

現在可以分清楚了:訂單 1 包含球棒和運費,訂單 2 包含球鞋和運費。

問題:資料重複了

但是,你發現問題了嗎?

  • 「消費者:胖虎」重複出現
  • 「下單日期:3/20」重複出現

如果發現訂單 1 的消費者其實是靜香,不是胖虎,你要改幾個地方?兩個地方。

這就是我們之前說的「重複資料的問題」。

第三版:分表解決重複資料問題

解決方法:把「訂單資訊」和「訂單品項」分成兩張表。

訂單表:

訂單編號消費者下單日期
1胖虎3/20
2胖虎3/20
消費者胖虎
下單日期3/20
消費者胖虎
下單日期3/20

訂單品項表:

訂單編號品項
1球棒
1運費
2球鞋
2運費
品項球棒
品項運費
品項球鞋
品項運費

現在,如果要修改訂單 1 的消費者,只需要改訂單表的一個地方。

訂單品項表透過「訂單編號」關聯回訂單表,不需要重複儲存消費者和下單日期。

如何實現「免運」?

回到原本的問題:週年慶期間,全館商品免運。

現在我們有了完整的資料結構,實現免運就很簡單:

只要下單日期落在週年慶期間,該訂單的運費品項金額就設為 0 元。

或者,週年慶期間的訂單根本不需要新增運費這個品項。

小結

這篇文章透過三個範例,練習了資料結構化的過程:

範例一(一句話拆成三張表)學到:

  • 先找出個體,再找出關係
  • 先把表開好,再把性質加進去

範例二(當關係指向另一個關係)學到:

  • 關係可以是非對稱的
  • 反感的對象不一定是「人」,也可以是「事件」(例如:靜香反感的是「胖虎欺負大雄」這件事)
  • 透過關聯查詢其他表的資料,不需要重複儲存

範例三(簡單的句子,複雜的結構)學到:

  • 簡單的句子可能藏著複雜的結構
  • 當資料重複時,就是需要分表的訊號
  • 透過「編號」來關聯不同的表

設計資料表的基本流程:

  1. 找出個體 → 建立個體表
  2. 找出關係 → 建立關係表
  3. 找出性質 → 加到對應的表
  4. 發現重複 → 考慮分表
  5. 透過關聯 → 串接不同的表

把這個流程練熟,你就掌握了關聯式資料庫設計的基本功。

目前還沒有留言,成為第一個留言的人吧!

發表留言

留言將在審核後顯示。

資料庫

目錄

  • 範例一:一句話拆成三張表
  • 原始資訊
  • 找出個體
  • 找出關係
  • 找出性質
  • 設計資料表
  • 小結
  • 範例二:當關係指向另一個關係
  • 原始資訊
  • 找出個體
  • 找出關係
  • 分析關係的結構
  • 設計資料表
  • 關聯的運用
  • 範例三:簡單的句子,複雜的結構
  • 原始資訊
  • 這句話有多複雜?
  • 拆解「商品」的概念
  • 第一版:單一交易表的設計
  • 問題:怎麼知道哪些品項是同一筆訂單?
  • 第二版:加入訂單編號識別同一筆交易
  • 問題:資料重複了
  • 第三版:分表解決重複資料問題
  • 如何實現「免運」?
  • 小結
  • 範例一(一句話拆成三張表)學到:
  • 範例二(當關係指向另一個關係)學到:
  • 範例三(簡單的句子,複雜的結構)學到:
  • 設計資料表的基本流程: