數據庫冗餘是否必要

數據庫冗餘是否必要

三豐 soft張三丰 前端

數據庫冗餘是否必要

咱們在這裏假設 認爲遵照數據庫設計的範式,不要冗餘 的爲正方:認爲設計數據庫設計須要設計一些適當冗餘的爲 反方:sql

但願你們能結合本身設計經驗,展開積極的討論:數據庫

下面是我舉的一個例子:緩存

好比作一個單據表,主要字段 單號 商品編號 商品名稱 單價 數量服務器

正方:單據表只能有「 單號 商品編號 單價 數量 」這幾個字段, 沒有「商品名稱 」這個字段,要顯示這個信息,就須要和 「商品基本信息表」 關聯獲取;數據庫設計

反方:ide

若是 這裏的「商品基本信息表 」裏若是有100萬條記錄,那麼我每作一個單據,單據明細信息都須要經過和100萬條記錄的「商品基本信息表 」關聯,顯然,這樣軟件運行效率確定要受到影響。性能

並且 ,寫sql語句只關聯一個表總比關聯多個表更方便。設計

正方:blog

若是客戶在使用過程當中,商品名稱發生了改變,那麼那些歷史單據上的商品名稱就會跟着變化,這樣能保證數據的一致性;不然,數據在統計的時候,明明是一個商品的入庫狀況,就會被當成兩個或多個,月末結算的時候就會有問題。

反方:一、「商品基本信息表 」的「商品名稱」原本就不容許輕易改變。若是該商品參與了單據處理,「商品名稱」就不該該修改。二、若是「商品名稱」修改了,那麼修改前和修改後的單據對於同一個「商品編號」原本就應該顯示不一樣的「商品名稱」;就像一我的,若是他在50歲之後該名字的話,那麼它50歲前做的事情,咱們也應該用他的原名啊。 三、若是正方認爲「商品名稱」能夠修改,那麼「商品編號」也能夠修改嘍。可是 你是經過「商品基本信息表 」的「商品編號」做爲關聯的。「商品編號」一旦修改,那麼單據明細因爲找不到之前的「商品編號」,記錄就會丟失。這不是出大亂子。固然,你會說「商品編號」是商品信息的惟一識別;可是,爲何不能把「商品名稱」最爲惟一識別呢。咱們不防看看用戶更改「商品名稱」的緣由是什麼?其實 「商品名稱」 每每是相對固定,而「商品編號」反而會由於當初的是設計不合理,而作更改;好比,一箇中學生,他原本的編號是35 ,後來學校改革。把他的編號該成 9831 他的編號變了,可是他的名字卻不會變。若是我用冗餘,就不會影響該學生在學校食堂的消費歷史紀錄;

正方:若是按照反方的觀點,爲什麼須要「商品編號」,不如在「商品信息表」裏就有一個「商品名稱」不就完了;中學生,也不用學號,直接用姓名識別。首先,「商品編號」或「學生學號」是有意義的。最簡單的,「商品名稱」或「學生姓名」可能重複;可是利用編號就能容易識別;若是用戶須要更改編號,那麼咱們能夠在每一個表裏作個內部的id字段,該字段自增加,各個表須要關聯時,都是經過他們的id來關聯。這樣即便修改了編號也無所謂。

反方:使用內部id的方法,會大大加大軟件的代碼編寫的複雜度。尤爲是報表系統裏,爲了獲取某個特定的信息會寫出很複雜的sql,就算你用視圖,道理也是同樣的,由於寫視圖也很費力。並且有時複雜的視圖的錯誤隱藏的很深。再說,好比那個中學生從初一上到高三,忽然老師那天不當心把他的學號和姓名都修改了,那麼那些在食堂裏消費的歷史紀錄相應的信息修改了。結果想還原都沒有辦法。若是咱們用冗餘,就不存在這個問題。

+++++++++++++++++++++++++++++++++++++++++++++++

數據庫冗餘:存儲兩倍數據,冗餘可使系統速度更快。(減小聯查)

我的理解:

在設計數據庫時,某一字段屬於一個表,但它又同時出如今另外一個或多個表,且徹底等同於它在其原本所屬表的意義表示,那麼這個字段就是一個冗餘字段。

至於冗餘字段的存在究竟是好仍是壞呢?

這是一個很差說的問題。可能在有人看來,這是一個很蹩腳的數據庫設計。由於在數據庫設計領域,有一個被你們奉爲圭臬的數據庫設計範式,這個範式理論上要求數據庫設計邏輯清晰、關係明確。

好比,」用戶暱稱」字段」nickname」原本屬於表」user」,那麼,表示」用戶暱稱」的字段就惟一的只應該屬於」user」表的」nickname」字段,這樣,當用戶要修改暱稱的時候,程序就只須要修改 user.nickname這個字段就好了,瞧,很方便。不過問題也隨之而來,我在其餘數據表(如訂單orders表)裏只存儲了用戶的ID,我要經過這個ID值獲得用戶暱稱該怎麼辦呢?一個廣泛的解決方法是經過聯接(join),在查詢時,經過id這個惟一條件聯接兩個表,從而取到用戶的暱稱。

這樣確實是沒問題,我也一直以爲這樣是最好的方案,擴展方便,當要更新用戶信息時,程序中要修改的地方不多,可是隨着數據庫裏數據不斷增長,百萬,千萬,同時,用戶表的數據確定也在不斷的增長的,它多是十萬,百萬。這個時候,你會發現兩個表經過聯接來取數據就顯得至關費力了,可能你只須要取一個nickname這個用戶暱稱屬性,你就不得不去聯一下那個已經幾十萬的用戶表進行檢索,其速度可想而知了。

這個時候,你能夠嘗試把nickname這個字段加到orders這個訂單表中,這樣作的好事是,當你要經過訂單表呈現一個訂單列表時,涉及用戶的部分可能就不須要再進行聯接查詢了。固然,有利就有弊,這樣作的弊端就是,當你嘗試更新用戶信息時,你必須記得用戶信息表裏當前被更新的字段中,有哪些是冗餘字段,分別屬於哪些表,找到他們,而後加入到你的更新程序段中來。這個是程序中的開銷,開銷在開發人員的時間上了。至於這樣作是否值得,就得看具體狀況而定了。

因此,目前要建立一個關係型數據庫設計,咱們有兩種選擇:

1,儘可能遵循範式理論的規約,儘量少的冗餘字段,讓數據庫設計看起來精緻、優雅、讓人心醉。

2,合理的加入冗餘字段這個潤滑劑,減小join,讓數據庫執行性能更高更快。

選擇哪種呢?若是你是一個美學狂人,而且財大氣粗,非要使用第一種方案,也不要緊,這種方案的短板並不是不可救藥的。好比,你能夠增長服務器,從數據庫集羣入手,進行讀寫分離,讀的時候能夠將壓力分散到不一樣的數據庫服務器上,這樣也能夠得到很好的性能,只是多付出了硬件成本和維護成本。或者,你能夠在數據庫前端架設Memcached之類的緩存服務,減小讀寫數據庫的次數,也能夠達到一樣的效果。問題在於你肯定你須要緩存之類的東西。

若是作不到上面的只能選擇第二種了,當涉及到修改的時候就須要將全部相關的數據進行修改了。

空間換取時間,到底值不值得,看業務需求與取捨了。

相關文章
相關標籤/搜索