數據庫設計
數據庫設計包含需求設計、邏輯設計、物理設計和維護優化。
- 需求分析:全面了解產品設計的存儲需求(存儲需求,數據處理需求,數據的安全性和完整性)
- 邏輯設計:設計數據的邏輯存儲結構(數據實體之間的邏輯關系,解決數據冗余和數據維護異常 )
- 物理設計:根據所使用的數據庫特點進行表結構設計
- 維護優化:根據實際情況對索引、存儲結構等進行優化
數據庫結構優化的目的
- 減少數據冗余
- 盡量你變數據維護中出現更新,插入和刪除異常
- 簡約數據庫的存儲空間
- 提高查詢效率
為了設計出沒有數據冗余和數據維護異常的數據結構,我們需要遵循以下規范:
- 第一范式
- 數據庫表中的所有字段都只有單一屬性
- 單一屬性的列都是由基本的數據類型所構成
- 設計出來的表都是簡單的二維表
- 第二范式
要求一個表中只具有一個業務主鍵,也就是說符合第二范式的表中不能存在非主鍵列對只對部分主鍵的依賴關系。以學生選課為例,它的主鍵是復合主鍵(學生編號,課程),而學分只依賴於課程,即非主鍵列只對部分主鍵存在依賴關系,不符合第二范式。
針對這個問題,我們怎么破呢?我們對上面這個表拆分為3個表:學生表、課程表、學生課程關系表。其中,學生表和課程表只有一個主鍵,而學生課程關系表有一個復合主鍵(學生編號,課程),分數完全依賴於這個復合主鍵,因此符合第二范式。
第三范式
每一個非主屬性既不部分依賴於也不傳遞依賴於業務主鍵,也就是在第二范式的基礎上消除了非主屬性對主鍵的傳遞依賴。
對於學生表,學院依賴於學生編號,而學院地址卻依賴於學院,這就是傳遞依賴,此時,這張表不滿足第三范式。如果想讓這張表滿足第三范式就需要繼續對這張表進行拆分。
反范式化
遵循范式化的數據庫設計,實現了消除數據冗余的目的,但是此時數據庫的性能和讀取效率並不是最優的。為了性能和讀取效率的考慮而適當的對數據庫設計范式的要求進行違反,而允許存在少量的數據冗余,換句話來說反范式化就是使用空間來換取時間。
舉個栗子,以我們經常進行下單為例。根據范式准則,定單表和訂單商品關聯表如下:
訂單表:{訂單編號,下單用戶名,下單日期,支付金額,物流單號}
訂單商品關聯表:{訂單編號,訂單商品分類,訂單商品名,商品數量}
我們知道查詢訂單時,往往需要知道用戶名稱和用戶手機號,那么,此時我們就需要將訂單表和用戶表進行關聯查詢。這種設計存在一個問題,當用戶修改手機號,那么用舊手機號買的訂單號的手機信息是新的手機號,而不是舊手機號,這是不符合業務需求的。解決這個問題的辦法就是將用戶名和用戶手機號加入到訂單表中。同樣情況,商品的價格也存在修改的情況,因此,也需要將支付金額加入到訂單表中,此時,訂單表和訂單商品關聯表如下:
訂單表:{訂單編號,下單用戶名,下單日期,支付金額,物流單號,訂單金額}
訂單商品關聯表:{訂單編號,訂單商品分類,訂單商品名,商品數量,商品單價}
總結
- 范式化設計可以盡量的減少數據冗余,更新操作比反范式化更快,但是對於查詢需要對多個表進行關聯,更難進行索引優化。
- 反范式化設計可以減少表的關聯(順序IO),可以更好的進行索引優化,但是存在數據冗余及數據維護異常,對數據的修改需要更多的成本(需要修改多個地方)。
因此,我們需要結合反范式化和范式化,設計出高性能數據庫結構。
歡迎關注微信公眾號:木可大大,所有文章都將同步在公眾號上。
