范式設計可以消除數據庫的數據冗余及插入異常,但是過分的范式設計可能導致數據查詢時需要關聯多張表,導致數據庫查詢效率下降,因此在實際工作中,需要適當的反范式設計。
舉例說明,某在線圖書銷售網站,希望實現如下功能: 1)用戶登錄 2)用戶管理 3)商品展示 4)商品管理 5)供應商管理 6)在線銷售
符合三范式的數據庫設計
用戶信息表 : 用戶名(主鍵),密碼,姓名,手機號,注冊日期
圖書信息表 : 圖書名稱(主鍵),出版社名詞,圖書價格圖書描述,作者
分類信息表 : 分類名詞(主鍵),分類描述
圖書分類表 : (圖書名詞,圖書分類)(主鍵)
供應商信息表:出版社名詞(主鍵),地址,電話,聯系人,銀行帳號
訂單表:訂單編號(主鍵),用戶名,下單日期,物流單號
訂單圖書關聯表 : (訂單編號,圖書名稱)(主鍵), 商品數量
在如上的數據庫設計中,如果需要查詢每個用戶的消費總金額
select 用戶名, sum(c.圖書價格*b.商品數量)
from 訂單表 a join 訂單圖書關聯表 b on a.訂單編號=b.訂單編號
join 圖書信息表 c on b.圖書名稱=c.圖書名稱
group by 用戶名
以上查詢需要關聯3張表,因為在線銷售經常會有促銷活動,商品價格時而會波動,在以上設計中,如果圖書價格發生變化,則查詢結果也會發生變化。
如果需要查詢下單用戶和訂單詳情
select a.訂單編號 a.用戶名 c.圖書名稱 b.商品數量 c.圖書價格
from 訂單表 a join 訂單圖書關聯表 b on a.訂單編號=b.訂單編號
join 圖書信息表 c on b.圖書名稱=c.圖書名稱
以上查詢也需要關聯3張表格。
反范式設計 ,在 訂單表 和 訂單圖書關聯表 中增加冗余數據
訂單表:訂單編號(主鍵),用戶名,下單日期,物流單號,訂單金額
訂單圖書關聯表 : (訂單編號,圖書名稱)(主鍵), 商品數量,圖書價格
在如上的數據庫設計中,如果需要查詢每個用戶的消費總金額
select 用戶名,sum(訂單金額) from 訂單表 group by (用戶名)
需要查詢下單用戶和訂單詳情
select a.訂單編號 a.用戶名 b.圖書名稱 b.商品數量 b.圖書價格
from 訂單表 a join 訂單圖書關聯表 b on a.訂單編號=b.訂單編號
反范式設計后,因為 訂單圖書關聯表 已經保存了當時的商品價格,所以商品價格波動并不影響查詢結果,而且減小查詢需要關聯的表。
反范式設計需要更具具體業務實際決定,將經常使用的業務表進行合理的反范式設計可以提高數據庫的查詢效率。
在實際的業務工作中,一般不使用外鍵,因為外鍵會在每次數據插入時進行合法性校驗,這樣回極大的拖累數據庫的插入效率。
新聞熱點
疑難解答