資料庫設計-閉環

來源:互聯網
上載者:User

資料庫設計中的忌諱

閉環(closed path)
假設現在有一個小公司,其下包含很多項目組,各項目組被安排在不同的房間辦公。一個員工只服務於一個項目組。但是,因為房間人數有限,有的項目群組成員可能會被安排在不同的房間。我們可能會建立下面的模型:

三個實體之間形成了一個封閉的環。這在很多實際情況下會存在問題。從上面的模型,我們可以得到如下資訊一個房間包含多重專案組、一個項目組包含多名員工、一名員工只屬於一個項目組、一個員工只能在一個房間、一個房間裡有多名員工。我們要求能查出員工所在的項目組,每個房間有哪些員工、有哪些項目組在此房間辦公,每個員工的房間的聯絡電話等等資訊。假設我們現在想查詢某個員工的房間聯絡電話,我們可能會直接通過employee和room連接得到,也可能會通過員工所在的項目組找到其所屬項目組所在房間的聯絡電話。資料存在冗餘時,當對資料進行更新就會有額外的操作。如果這時調整了員工所在的項目組或是所在項目組挪動了辦公地點,這時都要對employee和group進行更新。如果一旦出現錯誤,則就會出現資料不一致現象。這也應該被稱為資料丟失。

那如果現實情況真的是一個項目組被分到了兩個房間裡,應該如何表示呢?可能你要建立一個虛擬組,然後分別指示其所在的房間了。當然這並不是一種理想的方法,客戶可能並不想這樣做。就像不能把所有能自動完成的任務都自動化一樣,有時只能取一種折中的辦法。

上面模型表示一個員工只服務於一個項目組,若是同時服務於多重專案組時,在employee與room之間建立關係是必要的。模型稍有修改,但同樣存在閉環。

這時為了能找到員工所有房間的電話,就只能通過employee和room的關係進行尋找了。這無疑給資料的錄入和尋找帶來負面影響,而且資料有丟失的風險。這是無法避免的,但我們如果看到有閉環存在時,一定要謹慎對待了!
假設上面的模型中包含了公司實體,公司下麵包含了很多重專案組。有的員工是直屬於公司的,服務於所有項目組。我們很可能會建立下面的模型:

我們在employee、company、group之間又看到了封閉的環。你該去掉哪個關係呢?像是works for和belong to都沒有辦法去掉。這時你就又要考慮虛擬項目組了,你可以建立一個administrator組來表示服務於所有項目組的員工,他們同樣屬於公司。從而可以把employee與company之間的關係去掉。

上面的例子你可能很容易想到解決的辦法,但當業務比較複雜時,可能很容易就掉進這樣的陷阱裡。因此,當你看到這樣封閉的環時,就要認真的思考一下你對資料是不是真正的理解了,不要為了資料而資料!

資料泛化

假設現在公司為了提高員工技術水平,聘請了一些講師對員工進行週期性培訓,他們每個人負責一部分課程的教授。同時,公司還提供一定的停車位給員工及這些專家免費使用。我們很容易的建立了下面的模型:

同樣的問題出現了,你一眼就可以看出,又存在閉環!同時,員工與講師共用了停車位。如果仔細查看employee與lecturer兩個實體,你會發現裡面其實有很多屬性是相同的。你的模型裡屬性可能不會像這裡一樣完全相同,這就要看你是否對每個屬性的意義真正理解了!那這些相同的屬性我們該如何處理呢?OO強調繼承,這裡我們也使用繼承來解決這個問題。新的模型如下:

這時如果又有新的類型的員工加進來,我們可以再增加一個實體來描述該類型員工所特有的屬性了。同時也解決了閉環的問題。

現在又有個問題,有一部分講師正式加入了公司,也成了公司的員工負責一部分工作。他同時也肩負著培訓的工作,拿兩份工資。你該如何來描述這種關係呢?這時我們看到變化的是一個人的角色功能,因此你需要添加一個新的實體來表示這種角色,新的模型如下所示:

Contract最後只是一個關聯的實體,表示一個人可以和多個角色發生關係。但是,如果在資料庫中大量使用繼承來表示這種關係的話,會帶來很多額外的小表。因此,在實際項目中可能要根據實際情況決定是否要採用這種方式。

表中欄位的選擇

經常我們在一張表裡會看到有很多的欄位,而且有很多欄位都被設成允許NULL。對於NULL的理解,可以為是、否或不確定。但資料庫只適應於處理二值邏輯,這種三值邏輯處理起來會比較麻煩。OO裡還特定為了處理資料庫中的NULL而單獨存在了一種模式。因此,在對欄位進行設定時,應盡量的避免允許為NULL。如果有太多的不確定的屬性,只能說明你對客戶的需求還沒有真正瞭解清楚。大家都知道資料庫中的每個資料頁只有8K的大小,如果一條記錄所包含的欄位越少,內容越少。每個資料頁所能包含的行數就會越多,因此在進行查詢時所發生的I/O就會越小,而I/O正是影響效能最關鍵的因素。因此你可能需要把一個實體中的屬性分別儲存於不同的表中。

 

以上所述,其實歸根結底只是強調了一個問題:資料的正常化。最後所建立的物理表中,應該沒有冗餘的資訊。有人會覺得使用冗餘來減少表的串連會帶來效能的提高,但這在很多情況下是適得其反的。我現在對幾個資料庫進行過最佳化,因為不瞭解業務,所以只能通過改改索引,某些不複雜的SQL語句調整一下寫法。但這並不能解決資料庫設計的缺陷所帶來的影響,因此大家以後在修改資料庫這個公用的環境時一定要慎之又慎。雖然現在有很多技術可以支援多個資料庫提供服務,但基本都是提供高可用性的,對於高擴充性或多或少都會對程式有一定的影響。因此,在你每寫一條SQL語句時,哪怕能提高0.1秒的時間也不要小看。這0.1秒對於一個常用的查詢來說,一天所節省的時間是相當可觀的!經常在網上看到什麼通用的資料庫分頁預存程序,方便的代價就是效能的損失。因此,對資料庫而言,我覺得沒有什麼是可以通用的。你的查詢只能根據表中的資料分布情況來決定如何檢索更有效。

更多內容,歡迎大家分享!

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.