數(shù)據(jù)庫設(shè)計(理論篇)

第一章 需求分析


設(shè)計簡介

根據(jù)業(yè)務需要,結(jié)合選用的DBMS,設(shè)計出最有的數(shù)據(jù)存儲模型并建立好數(shù)據(jù)庫中的表結(jié)構(gòu)及表與表之間的關(guān)系使之有效的存儲和高效的訪問。?

數(shù)據(jù)庫設(shè)計

在系統(tǒng)設(shè)計開始就應該對數(shù)據(jù)庫進行良好的設(shè)計,這樣才能保證以后對業(yè)務發(fā)展的需要進行改進,保證系統(tǒng)的穩(wěn)定性。?

設(shè)計步驟


? ? 需求分析:數(shù)據(jù)庫需求的作用點(數(shù)據(jù)是什么,數(shù)據(jù)有哪些屬性,數(shù)據(jù)屬性的特點)

? ? 邏輯設(shè)計:用ER圖進行建模

? ? 物理設(shè)計:選擇數(shù)據(jù)庫管理系統(tǒng),根據(jù)數(shù)據(jù)庫自身的特點把邏輯設(shè)計轉(zhuǎn)換為物理設(shè)計

? ? 維護優(yōu)化:對新需求進行見表,索引優(yōu)化,大表拆分

需求分析重要性


? ? 1、了解系統(tǒng)中所要存儲的數(shù)據(jù)

? ? 2、了解數(shù)據(jù)存儲的特點

? ? 3、了解數(shù)據(jù)的生命周期

需要了解的問題:

? ? 實體與實體之間的關(guān)系(一對一,一對多,多對多)

? ? 實體所包含的屬性

? ? 哪些屬性或?qū)傩缘慕M合可以唯一標識一個實體

實例:小型電子商務網(wǎng)站


模塊:用戶模塊,商品模塊,訂單模塊,購物車模塊,供應商模塊

用戶模塊:用于記錄注冊用戶信息

? ? 包括屬性:用戶名、密碼、電話、郵箱、身份證號、地址、姓名、昵稱

? ? 可選唯一標識屬性:用戶名、身份證、電話

? ? 存儲特點:隨系統(tǒng)上線時間逐漸增加,需要永久存儲

商品模塊:用于記錄網(wǎng)站中所有銷售的商品信息

? ? 包括屬性:商品編碼、商品名稱、商品描述、商品品類、供應商名稱、重量、有效期、價格。。。

? ? 可選唯一標識屬性:(商品名稱、供應商名稱)組合、(商品編碼)

? ? 存儲特點:對于下線商品可以歸檔存儲

訂單模塊:用于用戶訂購商品的信息

? ? 包括屬性:訂單號、用戶姓名、用戶電話、收貨地址、商品編號、商品名稱、數(shù)量、價格、訂單狀態(tài)、支付狀態(tài)、訂單類型。。。

? ? 可選唯一標識屬性:訂單號

? ? 存儲特點:永久存儲(分表、分庫存儲)

購物車模塊:用于 保存用戶購物時選擇的商品

? ? 包括屬性:用戶名、商品編號、商品名稱、商品價格、商品描述、商品分類、加入時間、商品數(shù)量。。。

? ? 可選唯一標識:(用戶名、商品編號、加入時間)、(購物車編號)

? ? 存儲特點:不用永久存儲(設(shè)置歸檔、清理規(guī)則)

供應商模塊:用于保存所銷售商品的供應商信息

? ? 包括屬性:供應商編號、供應商名稱、聯(lián)系人、電話、營業(yè)執(zhí)照號、地址、法人。。。

? ? 可選唯一標識:(供應商編號),(營業(yè)執(zhí)照號)

? ? 存儲特點:永久存儲


第二章 邏輯設(shè)計


E-R圖


邏輯設(shè)計是做什么的

? ? 1、將需求轉(zhuǎn)化為數(shù)據(jù)庫的邏輯模型

? ? 2、通過E-R圖的形式對邏輯模型進行展示

? ? 3、同所選用的具體的DBMS系統(tǒng)無關(guān)

名詞解釋

? ? 關(guān)系:一個關(guān)系對應通常所說的一張表

? ? 元組:表中的一行即為一個元組

? ? 屬性:表中的一列即為一個屬性;每一個屬性都有一個名稱,稱為屬性名

? ? 候選碼:表中的某個屬性組,它可以確定一個元組

? ? 主碼:一個關(guān)系有多個候選碼,選定其中一個為主碼

? ? 域:屬性的取值范圍

? ? 分量:元組中的一個屬性值

E-R圖例說明?


實例演示(加下劃線的是主鍵)

設(shè)計范式概要

什么是數(shù)據(jù)庫設(shè)計范式

常見的數(shù)據(jù)庫設(shè)計范式包括:第一范式,第二范式,第三范式,BC范式,第四、第五范式

這也是目前我們大多數(shù)數(shù)據(jù)庫設(shè)計所要遵循的范式

數(shù)據(jù)操作異常及數(shù)據(jù)冗余

? 操作異常:

? ? 插入異常:如果某實體隨著另一個實體的存在而存在,即缺少某個實體時無法表示這個實體,那么這個表就存在插入異常

? ? 更新異常:如果更改表所對應的某個實體實例的單獨屬性時,需要將多行更新,那么就說這個表存在更新異常。

? ? 刪除異常:如果刪除表中的某一行來反應某實體實例,失效時導致另一個不同實體實例信息丟失,那么這個表中就存在刪除異常。

? 數(shù)據(jù)冗余:

? ? 是指相同的數(shù)據(jù)在多個地方存在,或者說表中的某個列可以由其他列計算得到,這樣就說表中存在著數(shù)據(jù)冗余。

第一范式(1NF):


定義:數(shù)據(jù)庫表中的所有字段都是單一屬性,不可再分的。這個單一屬性是由基本的數(shù)據(jù)類型所構(gòu)成的,如整數(shù),浮點數(shù),字符串等;

換句話說 ?第一范式要求數(shù)據(jù)庫中的表都是二維表。

第二范式(2NF)

? 定義:數(shù)據(jù)庫中的表中不存在非關(guān)鍵字段對任一候選關(guān)鍵字段的部分函數(shù)依賴。

部分函數(shù)依賴是指存在著組合關(guān)鍵字中的某一關(guān)鍵字決定非關(guān)鍵字的情況。

換句話說:所有單關(guān)鍵字段的表都符合第二范式

由于供應商和商品之間是多對多的關(guān)系,所以只有使用商品名稱和供應商名稱才可以唯一標識出一件商品。也就是商品名稱和供應商名稱是一組組合關(guān)鍵字。

上表中存在以下的部分函數(shù)依賴關(guān)系

(商品名稱)->(價格,描述,重量,商品有效期)

(供應商名稱)->(供應商電話)

存在的問題:插入異常、刪除異常、更新異常、數(shù)據(jù)冗余

第三范式(3NF)?


定義:第三范式是在第二范式的基礎(chǔ)上定義的,如果數(shù)據(jù)表中不存在非關(guān)鍵字段,對任意候選關(guān)鍵字段的傳遞函數(shù)依賴則符合第三范式。

存在以下傳遞函數(shù)依賴關(guān)系:

(商品名稱)->(分類)->(分類描述)

也就是說存在非關(guān)鍵字段“分類描述”

對關(guān)鍵字段“商品名稱”的傳遞函數(shù)依賴

存在問題:(分類,分類描述)對于每一個商品都會進行記錄,所以存在著數(shù)據(jù)冗余。同時也存在著數(shù)據(jù)的插入,更新及刪除異常

拆分

BC范式


Boyce.Codd范式(BCNF)

定義:在第三范式的基礎(chǔ)上,數(shù)據(jù)庫表中如果不存在任何字段對任一候選關(guān)鍵字段的傳遞函數(shù)依賴則符合BC范式。

也就是說如果是復合關(guān)鍵字,則復合關(guān)鍵字之間也不能存在函數(shù)依賴關(guān)系。

(以商品同供應商的關(guān)系表來說明BCNF)

假定:供應商聯(lián)系人只能受雇于一家供應商,每家供應商可以供應多個商品,則存在如下決定關(guān)系:

(供應商,商品ID)->(聯(lián)系人,商品數(shù)量)

(聯(lián)系人,商品ID)->(供應商,商品數(shù)量)

存在下列關(guān)系因此不符合BCNF要求:

(供應商)->(供應商聯(lián)系人)

(供應商聯(lián)系人)->(供應商)

并且存在數(shù)據(jù)操作異常及數(shù)據(jù)冗余

拆分

第三章 物理設(shè)計


物理設(shè)計要做什么

? ? 1、選擇合適的數(shù)據(jù)庫管理系統(tǒng)

? ? 2、定義數(shù)據(jù)庫、表及字段的命名規(guī)范

? ? 3、根據(jù)所選的DBMS系統(tǒng)選擇合適的字段類型(效率,功能,需求)

? ? 4、反范式化設(shè)計(冗余)

選擇哪種數(shù)據(jù)庫


?

成本、版權(quán)、功能(性能)、操作系統(tǒng)、開發(fā)語言、應用場景

mysql常用的存儲引擎


開源數(shù)據(jù)庫,只要符合mysql存儲協(xié)議,任何人都可以開發(fā)存儲引擎

主要使用Innodb存儲引擎

mysql常用存儲引擎

表及字段的命名規(guī)范


所有對象命名應該遵循下述原則:

? ? 1、可讀性原則:使用大寫和小寫格式化的庫對象名字已獲得良好的可讀性。

例如:使用CustAddress而不是custaddress來提高可讀性。

(這里要注意有些DBS系統(tǒng)對表名的大小寫是敏感的)

? ? 2、表意性原則:對象的名字應該能夠描述它所標識的對象。

例如:對于表,表的名稱應該能夠體現(xiàn)表中存儲的數(shù)據(jù)內(nèi)容;

對于存儲過程,存儲過程名稱應該能夠體現(xiàn)存儲過程的功能。

? ? 3、長名原則:盡可能少使用或者不使用縮寫,適用于數(shù)據(jù)庫(DATABASE)名之外的任一對象。

字段類型選擇原則

生日可選類型

? ? 列的數(shù)據(jù)類型一方面影響數(shù)據(jù)存儲空間的開銷,另一方面也會影響數(shù)據(jù)查詢性能。當一個列可以選擇多種數(shù)據(jù)類型時,應該優(yōu)先考慮數(shù)字類型,其次是日期或者二進制類型,最后是字符類型。對于相同級別的數(shù)據(jù)類型,應該優(yōu)先選擇占用空間小的數(shù)據(jù)類型。

各種類型所占存儲空間

如何具體選擇字段類型


char與varchar如何選擇

? ? 原則:

? ? ? ? 1、如果列中要存儲的數(shù)據(jù)長度差不多是一致的,則應該考慮用char;否則應該考慮用varchar。

? ? ? ? 2、如果劣種的最大數(shù)據(jù)長度小于50Byte,則一般也考慮用char。

? ? ? ? 3、一般不宜定義大于50Byte的char類型列。

utf8每個字符占三個字節(jié)


decimal與float類型如何選擇

? ? 原則:

? ? ? ? 1、decimal用于存儲精確數(shù)據(jù),而float只能用于存儲非精確數(shù)據(jù)。

? ? ? ? 2、由于float的存儲空間開銷一般比decimal小(精確到7位小數(shù)只需要4個字節(jié),而精確到15位小數(shù)只需要8字節(jié))故非精確數(shù)據(jù)優(yōu)先選擇float類型。

數(shù)據(jù)庫設(shè)計的其他注意事項


時間類型存儲:

? ? 1、使用int來存儲時間字段的優(yōu)缺點

? ? ? ? 優(yōu)點:字段長度比datetime小。

? ? ? ? 缺點:使用不方便,要進行函數(shù)轉(zhuǎn)換。

? ? ? ? 限制:只能存儲到2038-1-19 ?11:14:07即2^32為2147483648

? ? 2、需要存儲的時間粒度

? ? ? ? 年 ?月 ?日 ?時 ?分 ?秒 ?周

數(shù)據(jù)庫設(shè)計其他注意事項

? ? 如何選擇主鍵

? ? ? ? 1、區(qū)分業(yè)務主鍵和數(shù)據(jù)庫主鍵,業(yè)務主鍵用于標識業(yè)務數(shù)據(jù),進行表與表之間的關(guān)聯(lián);數(shù)據(jù)庫主鍵為了優(yōu)化數(shù)據(jù)存儲(Inoodb會生成6個字節(jié)的隱含主鍵)

? ? ? ? 2、根據(jù)數(shù)據(jù)庫的類型,考慮主鍵是否要順序增長,有些數(shù)據(jù)庫是按主鍵的順序邏輯存儲的

? ? ? ? 3、逐漸的字段類型所占空間要盡可能的小,對于使用聚集索引方式存儲的表,每個索引后都會附加主鍵信息。

? ? 避免使用外鍵約束

? ? ? ? 1、降低數(shù)據(jù)導入的效率

? ? ? ? 2、增加維護成本

? ? ? ? 3、雖然不建議使用外鍵約束,但是相關(guān)聯(lián)的列上一定要建立索引

? ? 避免使用觸發(fā)器

? ? ? ? 1、降低數(shù)據(jù)導入的效率

? ? ? ? 2、可能會出現(xiàn)意想不到的數(shù)據(jù)異常。

? ? ? ? 3、使業(yè)務邏輯變得復雜

? ? 關(guān)于預留字段

? ? ? ? 1、無法準確的知道預留字段的類型。

? ? ? ? 2、無法準確的知道預留字段中所存儲的內(nèi)容。

? ? ? ? 3、后期維護預留字段所需要的成本,同增加一個字段所需要的成本是相同的。

? ? ? ? 4、嚴禁使用預留字段

反范式化表設(shè)計


? ? 什么是反范式化

? ? ? ? 反范式化是針對范式化而言的,所謂的反范式化就是為了性能和讀取效率的考慮而適當?shù)膶Φ谌妒降囊筮M行違反,而允許存在少量的數(shù)據(jù)冗余。換句話說反范式化就是使用空間來換取時間。


? ? 為什么反范式化

? ? ? ? 1、減少表的關(guān)聯(lián)數(shù)量

? ? ? ? 2、增加數(shù)據(jù)的讀取效率

? ? ? ? 3、反范式化一定要適度

第四章 維護和優(yōu)化


維護和優(yōu)化要做什么


? ? 1、維護數(shù)據(jù)字典

? ? 2、維護索引

? ? 3、維護表結(jié)構(gòu)

? ? 4、在適當?shù)臅r候?qū)Ρ磉M行水平拆分或垂直拆分

如何維護數(shù)據(jù)字典


? ? 1、使用第三方工具對數(shù)據(jù)字典進行維護

? ? 2、利用數(shù)據(jù)庫本身的備注字段來維護數(shù)據(jù)字典。以mysql為例

CREATE TABLE costomer(

cust_id INT AUTO_INCREMENT NOT NULL COMMENT '自增ID',

cust_name VARCHAR(10) NOT NULL COMMENT '客戶姓名',

PRIMARY KEY (cust_id)

) COMMENT '客戶表'

? ? 3、導出數(shù)據(jù)字典

SELECT

a.table_name,b.TABLE_COMMENT,a.COLUMN_NAME,

a.COLUMN_TYPE,a.COLUMN_COMMENTFROM

information_schema.COLUMENS a JOIN information_schema.

TABLE b ON a.table_schema=b.table_schema AND

a.table_name=b.table_name

WHERE a.table_name='customer'

如何維護索引


? ? 如何選擇合適的列建立索引?

? ? ? ? 1、出現(xiàn)在WHERE從句,GROUP BY 從句,ORDER BY 從句中的列

? ? ? ? 2、可選擇性高的列要放到索引的前面

? ? ? ? 3、索引中不要包括太長的數(shù)據(jù)類型

? ? 注意事項

? ? ? ? 1、索引并不是越多越好,過多的索引不但會降低寫效率,而且會降低讀的效率

? ? ? ? 2、頂起維護索引碎片

? ? ? ? 3、在SQL語句中不要使用強制索引關(guān)鍵字

數(shù)據(jù)庫中適合的操作


如何維護表結(jié)構(gòu)

注意事項:

? ? 1、使用在線變更表結(jié)構(gòu)的工具

? ? ? ? MySql5.5之前可以使用pt-online-schema-change

? ? ? ? MySql5.6之后本身支持在線表結(jié)構(gòu)的變更

? ? 2、同時對數(shù)據(jù)字典進行維護

? ? 3、控制表的寬度和大小

數(shù)據(jù)庫中適合的操作

? ? 1、批量操作VS逐條操作

? ? 2、禁止使用SELECT *這樣查詢

? ? 3、控制使用用戶自定義函數(shù)

? ? 4、不要使用數(shù)據(jù)庫中的全文索引

表的垂直拆分和水平拆分




最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內(nèi)容