資料庫正規化與反正規化設計,是一門藝術

2022-07-06 20:30:28 字數 2388 閱讀 6074

在日常業務研發過程中,我們常常需要與資料庫表打交道。設計正規化是資料表設計的基本原則,對於資料表的設計正規化,我們特別容易忽略它的存在。很多時候,當資料庫執行了一段時間之後,我們才發現資料表設計上有問題。然後重新調整資料表的結構,需要做資料遷移,還有可能影響程式處理的業務邏輯,甚至系統的正常服務執行。

其實在資料庫表結構設計的初期時候,我們就需要重視資料表的設計。

我們在設計關係型資料庫模型的時候,需要對關係內部各個屬性之間聯絡的合理化程度進行定義,這就有了不同等級的規範要求,這些規範要求被稱為正規化(nf)。

正規化簡單理解即為:一張資料表的設計結構需要滿足的某種設計標準的級別。

目前關係型資料庫一共有 6 種正規化,按照正規化級別,從低到高分別是:1nf(第一正規化)、2nf(第二正規化)、3nf(第三正規化)、bcnf(巴斯 - 科德正規化)、4nf(第四正規化)和 5nf(第五正規化,又叫做完美正規化)。

資料庫的正規化設計越高階,冗餘度就越低,同時高階的正規化一定符合低階正規化的要求,比如滿足 2nf 的一定滿足 1nf,滿足 3nf 的一定滿足 2nf,依次類推。

這麼多的正規化級別,那是不是都要符合呢?

一般來說資料表的設計應盡量滿足 3nf。但也不絕對,有時候為了提高某些查詢效能,我們還需要破壞正規化規則,也就是反規範化。

正規化化模型要求滿足下面三大正規化:

這種情況比較好理解,我們在設計某個欄位的時候,對於字段 x 來說,就不能把字段 x 拆分成字段 x-1 和字段 x-2。

假設存在使用者、商品兩個資料模型

使用者模型的主鍵是使用者id,那麼使用者模型其它欄位都應該依賴於使用者id

商品模型的主鍵是商品id,它和使用者沒有直接關係,則這個屬性不應該放到使用者模型,而應該放到「使用者-商品」相關聯的訂單表中去。

例如:訂單表(訂單id,商品id,使用者id,使用者姓名)

初看該錶沒有問題,滿足第二正規化,每列都和主鍵列「訂單編號」相關。再細看你會發現「使用者姓名」和「使用者id」相關聯,「使用者id」和「訂單id」又相關聯,最後經過傳遞依賴,「使用者姓名」和」訂單id」相關聯。為了滿足第三正規化,應去掉訂單表中「使用者姓名」列,放入使用者表中。

總結一下:

儘管前面我們介紹了資料表的設計有很多正規化,資料庫設計正規化越高階,資料表就會越精細,資料的冗餘度也就越少,在一定程度上可以讓資料庫在內部關聯上更好地組織資料。但事實上,我們在設計資料表的時候卻不一定要一定嚴格參照這些標準,有時候我們也需要採用反範進行優化,通過空間來換取時間。

既然正規化是為了消除冗餘,那麼反正規化就是通過增加冗餘、聚合的手段來提公升效能。

反正規化就是相對正規化化而言的,換句話說,就是允許少量的冗餘,通過空間來換時間。同時反正規化優化也是一種改善慢查詢的優化思路。

例如:上面使用者、商品、訂單表的例子

我們可以在訂單表中冗餘商品名稱字段,這樣我們可以通過使用者關聯查詢到訂單表之後,無需再次關聯商品表而拿到商品名稱。如:訂單表(訂單id,商品id,使用者id,商品名稱)

從上面的例子中可以看出,反正規化設計可以通過空間換時間,提公升查詢的效率,但是反正規化也會帶來一些新問題。

主要問題包括:

那麼反正規化優化適用於哪些場景呢?

其實每次發生的訂單收貨資訊都屬於歷史快照資訊,需要進行儲存,但同時使用者又可以隨時修改自己的資訊,這時儲存這些冗餘資訊是非常有必要的。

結論:當冗餘資訊有價值或者能大幅度提高查詢效率的時候,我們就可以採取反正規化設計的優化。

在日常我們的工作當中,需要遵守一定的規範,例如專案研發流程規範、專案匯報規範以及會議規範等等,這些規範雖然會叫人感覺存在一定的約束感,所以我們常常對規則加以調整靈活運用,這樣可以保證工作的正確性和效率的保障性。

其實這與資料表的設計規範很像,我們既需要規範性,同時也要考慮到執行時的方便性。

正規化設計與反正規化設計堪稱 一門設計 「藝術」,因為它沒有標準答案...

正規化本身沒有優劣之分,只有適用場景不同。沒有完美的設計,只有合適的設計,我們在資料表的設計中,還需要根據需求將正規化和反正規化混合使用。

「技術架構精進」專注架構研究,技術分享

thanks for reading!

資料庫正規化與反正規化

最近涉及到設計和建立數倉表,資料總體劃分為ods fact aggr dws rpt dim層,具體結構如下圖所示 遵從設計規則 以星型模型為設計模式,維度採用反正規化化,且維度資料要整個倉庫可共用,資料準確性要保證,事實表允許冗餘部分維度資料。針對其中幾個地方,解釋並mark一下。多維資料模型是最...

資料庫正規化設計和反正規化設計

1 庫表設計遵從三大正規化。a 資料庫設計的第一大正規化 資料庫表中的所有欄位都只具有單一屬性 單一屬性的列是由基本資料型別所構成的 設計出來的表都是簡單的二維表。乙個列存放的資訊只是乙個屬性的資訊,不能乙個字段存放多個屬性的組合資訊。即資料庫表中的所有字段值都是不可分解的原子值 b 資料庫設計的第...

mysql資料庫設計正規化與反設計正規化操作思考

資料庫結構優化的目的 減少資料冗餘,盡量避免資料維護中出現更新 插入和刪除異常,節約資料儲存空間。資料庫設計正規化 第一正規化 1 資料表中的所有欄位都只具有單一屬性 2 單一屬性的列是由基本的資料型別所構成的 3 設計出來的表都應該是簡單的二維表 第二正規化 1 要求乙個表中具有乙個業務主鍵,也就...