Logo

新人日誌

首頁關於我部落格

新人日誌

Logo

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

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

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

資料庫架構設計入門:用 DRY 原則避免重複資料

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

這篇文章進入資料庫系列文章的重要主題——架構設計。

架構設計在做什麼?簡單來說,就是在規劃你的表單要有哪些欄位、表單之間要怎麼關聯。而設計架構時,有一個最重要的核心精神:

避免資料重複。

為什麼資料重複這麼嚴重?讓我們從工程師常講的一個原則開始說起。

工程師的 DRY 原則

工程師有一個原則叫 DRY,全名是 Don’t Repeat Yourself(不要重複你自己)。

當你複製貼上,等於是把同樣的東西「各自獨立」地放在好幾個地方。這些地方之間沒有任何連結,改了其中一個,其他的不會跟著變。

所以之後如果要改,你必須:

  1. 記得你複製過哪些地方
  2. 每一個地方都找出來改掉

問題是,大多數人複製貼上之後就忘了。結果有些地方改到,有些地方沒改到,程式就壞了。

資料庫重複資料的三大問題

程式碼重複已經很麻煩了,資料庫的重複問題更可怕。

Update 要改很多次

假設你的表單設計不好,客戶的地址被存在三個不同的地方:

  • 「客戶」表單裡有一個地址欄位
  • 「訂單」表單裡也存了一份送貨地址
  • 「發票」表單裡又存了一份帳單地址

有一天客戶搬家了,你更新(update)了「客戶」表單的地址,但忘了更新「訂單」和「發票」表單。

結果:

  • 「客戶」表單顯示新地址
  • 「訂單」表單顯示舊地址
  • 「發票」表單也顯示舊地址
  • 到底哪個才是對的?

這就是「資料不一致」。

Delete 要刪很多次

同樣的道理,如果你要刪除某筆資料,但它重複存在很多地方,你也必須全部都刪到。

漏刪任何一個地方,就會留下「孤兒資料」,造成系統混亂。

你不知道哪裡需要同步修改

最麻煩的是,很多時候你根本不知道或不記得哪些地方有重複的資料。

這不是粗心的問題,而是系統設計的問題。如果架構本身就允許重複,遲早會出事。

銀行資料不一致的風險

想像這件事發生在銀行:

你的帳戶餘額因為系統設計不良,被存在多個地方:

  • A 系統說你有 10,000 元
  • B 系統說你有 8,000 元

到底哪個是真的?

這種情況不只是「不方便」,而是可能造成金錢損失、客戶糾紛、甚至法律問題。

這就是為什麼我們要嚴格避免重複。

程式碼如何避免重複?

在程式設計中,如果發現某段資料或運算重複出現很多次,我們會怎麼做?

把它設成變數或函數,然後在別的地方「引用」它。

什麼是「引用」?就是不要把資料本身複製過去,而是指向那個資料存放的地方。

舉個例子,假設你有一個變數存著公司地址:

公司地址 = "台北市信義區松仁路 100 號"

當你需要在不同地方用到這個地址時,你不會把整串地址複製貼上,而是直接寫「公司地址」這個變數名稱。這樣所有用到「公司地址」的地方,其實都是指向同一個來源。

好處是什麼?

  • 地址只存在一個地方
  • 所有引用它的地方都會自動拿到同樣的內容
  • 要改的時候,只需要改那一個地方,其他地方就自動更新了

這個「引用」的概念,在資料庫裡面也有對應的做法——就是「關聯」。

資料庫如何避免重複?

資料庫的解法跟程式碼一樣:讓每筆資料只存在一個地方,需要的時候用「關聯」去指向它。

這就是「架構設計」要做的事。

什麼是資料庫架構?

簡單來說,資料庫架構就是在描述:

  • 你有哪些表單
  • 每個表單裡有哪些欄位
  • 這些表單之間怎麼互相關聯

表單之間的關聯是什麼意思?

假設你有一個「訂單」表單和一個「客戶」表單。每一筆訂單都會對應到某一個客戶,所以「訂單」表單裡面會有一個欄位,專門用來指向「客戶」表單的某一筆資料。

這種「A 表單的某個欄位指向 B 表單」的設計,就是表單之間的關聯。

訂單表單透過「客戶 ID」欄位,指向客戶表單的某一筆資料

為什麼用關聯可以避免重複?

假設你把客戶的地址直接寫在每一筆訂單裡,那同一個客戶下了 10 筆訂單,地址就會重複 10 次。

但如果你用關聯的方式,訂單只存「客戶 ID」,地址只存在客戶表單那一個地方。這樣不管客戶下了幾筆訂單,地址永遠只有一份,要改也只要改一個地方。

怎麼判斷哪些欄位該放一起?

現在我們知道:好的架構設計要避免重複,方法是把資料集中存在一個地方,其他地方用「關聯」去指向它。

但實際在設計的時候,你會遇到一個問題:

怎麼判斷哪些欄位該放在同一個表單?哪些該分開?

例如:「客戶姓名」和「客戶地址」應該放在一起嗎?「訂單日期」和「送貨地址」呢?「商品名稱」和「商品價格」呢?

這些問題沒有標準答案,要看你怎麼分析資料之間的關係。

之前的文章教過一種方法,就是用「個體、性質、關係」來思考。

用個體、性質、關係來設計資料庫

這個方法是這樣的:

  1. 先找出有哪些個體(例如:客戶、商品、訂單)
  2. 這些個體有哪些性質(例如:客戶有姓名、電話)
  3. 個體之間有什麼關係(例如:客戶「購買」商品)

這個方法在簡單的情境下很好用,但當世界變複雜,問題就來了。

周年慶案例:商品是個體還是關係?

之前課堂上看過一個周年慶的案例。

一開始我們直覺認為「商品」是一個個體——它就是一個東西嘛,應該獨立存在。

但仔細分析後發現,「商品」其實是消費者和店家之間的關係。因為同一個東西,在不同的情境下(例如不同的促銷活動),它的價格、組合方式都可能不同。

這個例子告訴我們:現實世界比想像中複雜,光靠「個體、性質、關係」的直覺判斷,有時候會出錯。

用欄位相依關係來設計架構

既然直覺判斷不夠可靠,這堂課會換一個角度:

觀察欄位之間的「相依關係」,來決定哪些欄位該放在一起、哪些該分開。

後續的文章會介紹很多具體的原則(這些都是前人留下來的經驗法則),幫助我們:

  • 看出欄位之間的關係
  • 把欄位切分到正確的表單
  • 避免資料重複

資料庫架構設計重點整理

這篇文章介紹了資料庫架構設計的核心精神:

  1. DRY 原則:不要重複,因為重複會讓修改和刪除變得困難
  2. 資料不一致是重複造成的最大風險,嚴重時會有金錢或法律問題
  3. 程式碼的解法是用變數和函數來引用,資料庫的解法是用關聯來指向
  4. 架構設計就是規劃表單的欄位,以及表單之間的關聯,讓每筆資料只存在一個地方
  5. 之前用「個體、性質、關係」來思考,但複雜情境下容易判斷錯誤(例如周年慶的商品案例)
  6. 接下來會用「欄位之間的相依關係」來設計架構

接下來的文章會介紹具體的設計原則,幫助我們判斷欄位該怎麼切分,達成「不重複」的目標。

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

發表留言

留言將在審核後顯示。

資料庫

目錄

  • 工程師的 DRY 原則
  • 資料庫重複資料的三大問題
  • Update 要改很多次
  • Delete 要刪很多次
  • 你不知道哪裡需要同步修改
  • 銀行資料不一致的風險
  • 程式碼如何避免重複?
  • 資料庫如何避免重複?
  • 什麼是資料庫架構?
  • 表單之間的關聯是什麼意思?
  • 為什麼用關聯可以避免重複?
  • 怎麼判斷哪些欄位該放一起?
  • 用個體、性質、關係來設計資料庫
  • 周年慶案例:商品是個體還是關係?
  • 用欄位相依關係來設計架構
  • 資料庫架構設計重點整理