MySQL系列之一:資料庫設計
前言
這裡將以前不怎麼熟悉的資料庫設計知識重新拾起,做一個簡單的知識梳理。之前一直認為資料庫設計無非就是建立資料庫、建表、新增欄位、確定欄位型別(這點隨意性很大),諸如此類。當系統地對資料庫知識重新學習的時候才發現數據庫設計也有一套類似軟體開發流程的規範,並且每一個步驟都是有不同的側重點的。
資料庫設計的概念
簡單來說,資料庫設計就是對需求進行分析、邏輯設計、物理設計以及維護和優化的過程。可以看到,資料庫設計不僅僅體現在軟體開發過程中,還體現在軟體後期的維護上。(時間週期)
這裡的軟體需求分析與軟體開發過程中的需求分析不太一樣,資料庫設計中的需求分析更側重資料來源(什麼資料)、資料的屬性以及資料和屬性的特點。
資料庫設計的一系列過程都需要結合我們現有的DBMS,設計表以及表之間聯絡,從而對資料進行有限的儲存以及高效訪問。
資料庫設計的步驟
在此之前還有一個問題沒有弄清楚,為什麼要進行資料庫設計?就我自己總結而言,有以下好處:
良好的資料庫設計對減少資料冗餘和操作異常、對資料有限儲存和高效訪問有很大幫助。之前自己做的畢業設計實現的實驗管理系統就是由於沒有對資料庫好好設計,導致後面資料查詢的困難,事實是,你寫一大堆SQL程式碼還不一定得到你想要的結果,所以這就是糟糕的資料庫設計的後果。各位小夥伴要引以為鑑吶。
資料庫設計的步驟
OK,言歸正傳,資料庫設計包括四個步驟:
- 需求分析
- 邏輯設計
- 物理設計
- 維護與優化
作為一名非專業DBA,本著實用即王道的原則,認為周邊知識瞭解即可,不求深入。所以對最後的維護和優化不做詳細的介紹,如果有小夥伴對這塊比較感興趣,可以參考資料庫設計教程。
需求分析
需求分析需要解決三個問題:軟體需要哪些資料
、資料有哪些屬性
以及資料屬性的特點
。首先,軟體需要的資料是由軟體業務決定的,這點可以從前期的需求文件中看到;資料的屬性就是資料庫每個表中的欄位,資料的屬性是構成資料的不可缺少的元素,在資料庫中一行資料成為資料的基本單元,也稱為元組;資料屬性的特點就是分析該資料是否需要永久儲存,如果是則資料將一直存在資料庫中,如果否,則該資料不能永久存在資料庫中(這類資料一直是時間敏感的,涉及頻繁的讀寫操作)。
邏輯設計
邏輯設計承接需求分析,要解決的核心問題就一個:繪製E-R圖。E-R圖就是把需求分析的結果轉換成邏輯模型的過程。E-R圖由三個要素組成:實體集、屬性集和聯絡集。實體集都是具有相同屬性的,屬性集是實體所具有的,聯絡集則是由實體之間的聯絡組成的(這裡的聯絡包括多種聯絡,後面的文章將詳細說明這點,敬請期待)。所謂“邏輯設計”,就是與具體的DBMS無關。要繪製E-R圖需要了解以下幾個概念:
- 關係:一個關係對應資料庫中的一張表
- 實體:具有一組相同屬性的資料庫管理物件
- 元組:表的一行資料
- 屬性:每個屬性對應資料庫表的一列
- 主關鍵字:可以唯一標識實體的一條或多條屬性
- 候選關鍵字:特指需要多條屬性才能標識實體的情況
說完基本概念,下面就是例項講解了,下面以我自己正在做的專案加以說明:
整個系統是學生資訊管理系統,具有很多模組,我負責的模組是住宿資訊管理,經過需求分析,最終確定該模組具有三部分的功能:學生物品報修、學生查詢水電資訊、宿管登記住宿資訊、物業處理物品報修和後勤分配住宿資訊。
學生: {學號,姓名,性別,聯絡方式,宿舍號}
宿管: {宿管ID,姓名,性別,聯絡方式}
物業: {物業管理人員ID,姓名,性別,聯絡方式}
後勤: {後勤管理人員ID,姓名,性別,聯絡方式}
住宿資訊表: {id,姓名,學號,性別,宿舍號,專業,班級號,聯絡方式}
宿舍: {宿舍ID,樓棟號,宿舍號}
物品報修資訊表: {id,物品名稱,損壞情況,報修人,聯絡方式,宿舍號,報修時間,緊急程度,是否處理}
用水資訊: {id,宿舍號,用水量,本月剩餘水量,剩餘金額,欠費狀態}
用電資訊: {id,宿舍號,用電量,本月剩餘電量,剩餘金額,欠費狀態}
根據上面這些資料,可以繪製下面的E-R圖:
由於原圖過大所以,只展示了部分。下面簡要說明一下圖的內容,每一個矩形代表一個實體,每個實體都有屬性集,<M>
代表該欄位不能為空,<pi>
代表該欄位是實體的主鍵,<ai>
代表該欄位是實體的候選關鍵字。實體之間存在各種聯絡,圖中的線條就表示了實體與實體的具體聯絡。下面就簡要說說這個聯絡是什麼鬼:
在資料庫設計中,存在4種基本的聯絡(Relationship):一對多、一對一、多對一。舉例來說,老師可以帶多個學生上課,學生也有多個多個老師,所以老師和學生是多對多的聯絡;一個學生只能在一個班級,而一個班級可以有多個學生,所以學生與班級是多對一的聯絡。反正分析思路就是一個和多個的對應關係能否成立。繼承(Inheritance):例如學生、老師都是人,所以“學生”和“老師”這兩個實體和“人”之間構成繼承關係。繼承關係的存在是為了以後更好的擴充套件。連線:具有連線關係的實體之間的地位是平等的,請仔細思考下圖:
下面是開發人員、專家與講座之間的關係:
從圖中可以看出,如果兩者不是連線關係就意味著地位的不平等。所以連線關係也挺好理解的。Ok,next,依賴:依賴就是某個實體不能單獨存在,必須和另一個實體共存才有存在的意義。舉例來說:門窗必須依賴房子而存在,沒有房子,就沒有門窗存在的必要。
物理設計
物理設計是最終的資料庫設計的核心,也是可見成果的關鍵步驟。那麼物理設計要解決什麼問題呢?
- 選擇合適的DBMS
- 規定資料庫、表和欄位的命名規範
- 根據所選的DBMS確定具體欄位的欄位型別
選擇合適的資料庫
目前,企業級資料庫有Oracle和SQL Server,這類資料庫對資料的安全性和容量有較高要求。網際網路專案使用的一般都是MySQL、PgSQL,所以根據需要根據自己專案的型別選擇合適的資料庫。
規定命名規範
命名規範需要遵循欄位可讀性原則和見名知義原則,不然隨意的欄位名還要建立資料字典,增加額外的工作量,沒什麼必要。
確定欄位型別
就我自己而言,覺得最不好判斷的是char和var char型別,兩種資料型別特別容易選擇,所以一般情況都是選擇更保守的varchar型別。但是隻要仔細分析發現兩種型別首先在表達的範圍就存在限制,char型別不能超過255個位元組,所以只要不是那種常文字一般都可以容納,這點上講,varchar比char節省空間,但是varchar比char效率更差,這一點可以這麼理解:當對varchar型別的資料進行修改的時候,可能因為資料長度的不同(以字串”abc”為例,char型別需要5個位元組,而varchar只需要3個位元組)導致“行遷移(Row Migration)”,下面Oracle對行遷移的官方解釋:
當一行的記錄初始插入時是可以儲存在block(block是磁碟儲存的最小單位)中的,由於更新操作導致行增加了,而block的自由空間已經滿了,這個時候就產生了行遷移。在這種情況下,oracle將會把正行資料遷移到一個新的block中,oracle會保留被遷移的行的原始指標指向新的存放行資料的block,這意味著被遷移的ROW ID是不會改變的。
說的有點複雜,但總結起來可以知道varchar和char型別的差距不大,當然在大資料開發應用中除外。