1 數據庫設計概述
數據庫設計要求設計人員對數據庫有深入的理解,才能設計出高質量的數據庫。數據庫設計一般分爲6個階段,分別是需求分析、概念數據庫設計、邏輯數據庫設計、物理數據庫設計、數據庫實施、數據庫運行和維護。
(1)需求分析
在需求分析階段,數據庫設計人員需要分析用戶的需求,將分析結果記錄下來,形成需求分析報告。在這個階段中,雙方需要進行深入的溝通,以避免理解不準確導致後續的工作出現問題。在需求分析中有許多瑣碎、耗時的工作,常見的工作如下。
(1)收集數據。一個企業內的數據可能分散、零碎,由不同人員負責管理。爲了使用數據庫系統管理這些數據,需要儘可能多地收集數據,並理解企業的業務過程和數據處理流程,理解數據處理的性能需求。可以利用數據流圖等工具輔助分析與理解。
(2)解決衝突,包括命名衝突(同名異義、異名同義)屬性衝突、結構衝突。例如,商品庫存數量是否包含已下訂單未出庫數量;到貨數量和入庫數量以哪一個爲準;用戶名和暱稱、真實姓名如何區分;性別使用男、女,還是0、1或f、m來表示。
(3)爲數據形成一些標準,如商品編號一共有多少位,未來是否會增加位數,每一位的含義是什麼;訂單編號按照什麼規則生成,如何避免編號重複,編號中包含哪些信息,是否加入一些隨機數防止被推測等。
(2)概念數據庫設計
在概念數據庫設計階段,將對用戶的需求進行綜合、歸納、抽象,形成概念模型。概念模型使設計人員擺脫數據庫系統的具體技術問題,將精力集中在分析數據及數據之間聯繫等方面。一般通過繪製E-R圖,直觀呈現數據庫設計人員對用戶需求的理解。
(3)邏輯數據庫設計
邏輯數據庫設計面向數據庫系統,在概念數據庫設計中完成E-R圖等成果後,將其轉換爲DBMS支持的數據模型(如關係模型),完成實體、屬性和聯繫的轉換。
在進行邏輯數據庫設計時,應遵循一些規範化理論,如範式(將在後面的小節中詳細講解)。不規範的設計可能會導致數據庫出現大量冗餘、插入異常、刪除異常等問題。
(4)物理數據庫設計
物理數據庫設計階段需要確定數據庫的存儲結構、文件類型等。通常DBMS爲了保證其獨立性與可移植性,承擔了大部分任務,數據庫設計人員只需要考慮硬件、操作系統的特性,爲數據表選擇合適的存儲引擎,爲字段選擇合適的數據類型等,以及評估磁盤空間需求等工作。
(5)數據庫實施
數據庫實施就是將前面那些工作的成果實施起來,比如使用SQL語句創建數據庫、數據表,編寫與調試應用程序等。
(6)數據庫運行和維護
數據庫運行和維護就是將數據庫系統正式投入運行,在運行後進行一些維護、調整、備份、升級等工作。
2 數據庫設計範式
數據庫設計對數據的存儲性能、數據的操作都有很大的關係。爲了避免不規範的數據庫出現數據冗餘,造成插入、刪除、更新操作異常等情況,就要滿足一定的規範化要求,這就是範式(Normal Form)。
根據要求的程度不同,範式有多種級別,最常用的有第一範式(1NF)、第二範式(2NF)和第三範式(3NF),它們由Edgar Frank Codd於1971年相繼提出。後來,又有人提出了Boyce-Codd範式(BCNF)、第四範式(4NF)和第五範式(5NF)等。一般來說,數據庫設計只需滿足第三範式(3NF)就可以了,下面對前三範式進行詳細講解。
(1)第一範式(1NF)
第一範式(1NF)是指數據庫表的每一列都是不可分割的基本數據項,同一列中不能有多個值,即實體中的某個屬性不能有多個值,或不能有重複的屬性。簡而言之,第一範式遵從原子性,屬性不可再分。
爲了使讀者更好地理解,下面通過表1和表2演示不滿足第一範式的情況(表格中的列標題“編號”表示主鍵,用下劃線標註)。
表1 用戶聯繫方式表
編號 | 聯繫方式 |
---|---|
1 | 張三 郵箱:[email protected],手機號:18900000000 |
2 | 李四 郵箱:[email protected],手機號:15900000000、17300000000 |
表2 用戶聯繫方式表
編號 | 用戶名 | 郵箱 | 手機號 | 手機號 |
---|---|---|---|---|
1 | 張三 | [email protected] | 18900000000 | |
2 | 李四 | [email protected] | 15900000000 | 17300000000 |
表1的問題在於“聯繫方式”包含了多個值,可以再細分;表2的問題在於“手機號”屬性重複。
爲了滿足第一範式,應將用戶和聯繫方式分成兩個表保存,兩個表是一對多的聯繫。具體如表3和表4所示。
表3 用戶表
用戶編號 | 用戶名 |
---|---|
1 | 張三 |
2 | 李四 |
表4 聯繫方式表
編號 | 用戶編號 | 聯繫方式 | 具體值 |
---|---|---|---|
1 | 1 | 郵箱 | [email protected] |
2 | 1 | 手機號 | 18900000000 |
3 | 2 | 郵箱 | [email protected] |
4 | 2 | 手機號 | 15900000000 |
5 | 2 | 手機號 | 17300000000 |
通過表4-3和表4-4可以看出,無論一個用戶有多少個聯繫方式,都可以使用這兩張表來保存。
(2)第二範式(2NF)
第二範式(2NF)是在第一範式的 基礎上建立起來的,滿足第二範式必須先滿足第一範式。第二範式要求實體的屬性完全依賴於主鍵,不能僅依賴主鍵的一部分(對於複合 主鍵而言)。簡而言之,第二範式遵從唯一性,非 主鍵字段需完全依賴主鍵。
爲了使讀者更好地理解,下面通過表5和表6演示不滿足第二範式的情況。
表5 訂單表
訂單編號 | 訂單商品 | 購買件數 | 下單時間 |
---|---|---|---|
1 | 鉛筆 | 3 | 2019-01-20 8:30:15 |
2 | 鋼筆 | 2 | 2019-01-20 8:30:15 |
3 | 圓珠筆 | 1 | 2019-02-12 9:20:16 |
表6 用戶表
用戶編號 | 訂單編號 | 用戶名 | 付款狀態 |
---|---|---|---|
1 | 1 | 張三 | 已支付 |
1 | 2 | 張三 | 未支付 |
2 | 3 | 李四 | 已支付 |
在表6中,用戶編號和訂單編號組成了複合主鍵,付款狀態完全依賴複合主鍵,而用戶名只依賴用戶編號。
採用上述方式設計的用戶表存在如下問題。
插人異常:如果一個用戶沒有下過訂單,則該用戶無法插人;
刪除異常:如果刪除一個用戶所有的訂單,則該用戶也會被刪除;
更新異常:由於用戶名冗餘,修改一個用戶時需要修改多條記錄。如果稍有不慎,漏改某些記錄,會出現更新異常。
爲了滿足第二範式,將複合主鍵移動到訂單表中,如表7和表8所示。
表7 用戶表
用戶編號 | 用戶名 |
---|---|
1 | 張三 |
2 | 李四 |
表8 訂單表
訂單編號 | 用戶編號 | 訂單商品 | 購買件數 | 下單時間 | 付款狀態 |
---|---|---|---|---|---|
1 | 1 | 鉛筆 | 3 | 2019-01-20 8:30:15 | 已支付 |
2 | 1 | 鋼筆 | 2 | 2019-01-20 8:30:15 | 未支付 |
3 | 2 | 圓珠筆 | 1 | 2019-02-12 9:20:16 | 已支付 |
(3)第三範式(3NF)
第三範式(3NF)是在第二範式的基礎上建立起來的,即滿足第三範式必須先滿足第二範式。第三範式要求一個數據表中每一列數據都和主鍵直接相關,而不能間接相關。簡而言之,第三範式就是非主鍵字段不能相互依賴。
爲了使讀者更好地理解,下面通過表9演示不滿足第三範式的情況。
表9 用戶表
用戶編號 | 用戶名 | 用戶等級 | 享受折扣 |
---|---|---|---|
1 | 張三 | 1 | 0.95 |
2 | 李四 | 1 | 0.95 |
3 | 王五 | 2 | 0.85 |
在表9中,用戶享受的折扣與用戶等級相關,兩者存在依賴關係。採用這種方式設計的用戶表存在如下問題。
- 插入異常:新插人用戶的等級如果在1.2之外,其享受的折扣無處參考;
- 刪除異常:如果刪除某個等級下所有的用戶,該等級對應的折扣也被刪除;
- 更新異常:如果修改某個用戶的等級,折扣也必須隨之修改;如果修改某個等級的折扣,又因爲折扣存在冗餘,容易發生漏改。
爲了滿足第三範式,將等級與折扣拆分到單獨的表中,如表10和表11所示。
表10 用戶表
用戶編號 | 用戶名 | 用戶等級 |
---|---|---|
1 | 張三 | 1 |
2 | 李四 | 1 |
3 | 王五 | 2 |
表11 折扣表
用戶等級 | 享受折扣 |
---|---|
1 | 0.95 |
2 | 0.85 |
多學一招:函數依賴
函數依賴(Functional Dependency)是由數學派生的術語,是數據依賴的一種類型。它表示根據一個屬性(或屬性集)的值,可以找到另一個屬性(或屬性集)的值。例如,將商品關係模式中的屬性“商品id”設爲X,屬性集(商品名稱,商品價格)設爲Y,根據X可以找到Y,說明X決定了Y,Y函數依賴於X,記爲X→Y。
函數依賴根據依賴屬性的不同可以分爲完全函數依賴、部分函數依賴和傳遞函數依賴,具體如下。
完全函數依賴。以表8爲例,使用訂單編號和用戶編號可以決定付款狀態,而若只有訂單編號,無法決定是哪一個用戶創建了訂單,只有用戶編號,無法決定是哪一個訂單。因此,付款狀態這個屬性函數依賴(訂單編號,用戶編號)屬性集。
(2)部分函數依賴。以表6爲例,用戶名依賴用戶編號,但不依賴訂單編號,因此用戶名這個屬性部分函數依賴(訂單編號,用戶編號)屬性集。
(3)傳遞函數依賴。以表9爲例,享受折扣依賴用戶等級,用戶等級依賴用戶編號,所以享受折扣傳遞函數依賴用戶編號。
由此可見,在第一範式限定了一個關係模式的所有屬性都是不可分的基本數據項以後,第二範式消除了部分函數依賴,第三範式消除了傳遞函數依賴。
多學一招:反範式
反範式是一種逆規範化設計,其目的主要是爲了提高查詢效率。範式雖然減少了數據冗餘,但是增加了表的數量,這會使查詢變得複雜,尤其是連接多張表查詢數據時,會使查詢性能降低。例如,商品銷量可以通過查詢訂單表中的購買記錄計算出來,當需要查詢大量商品的銷量時,就需要花費許多時間去計算銷量。
爲了提高查詢效率,不必每次查詢計算銷量,可以違反範式的要求,在商品表中增加一個銷量字段,當商品被購買時就增加銷量字段。這種方式的缺點是容易出現數據不一致的問題。例如,用戶購買商品後,程序出現意外沒有增加銷量,銷量數據就有誤了。
在實際開發中,若選擇採取反範式的設計,應該提前評估其可能出現的問題,並準備一套解決方案。例如,通過存儲過程進行操作,定期檢查數據的一致性等。
超全面的測試IT技術課程,0元立即加入學習!有需要的朋友戳:
騰訊課堂測試技術學習地址
歡迎轉載,但未經作者同意請保留此段聲明,並在文章頁面明顯位置給出原文鏈接。