第一章 需求分析
設(shè)計簡介
根據(jù)業(yè)務需要,結(jié)合選用的DBMS,設(shè)計出最有的數(shù)據(jù)存儲模型并建立好數(shù)據(jù)庫中的表結(jié)構(gòu)及表與表之間的關(guān)系使之有效的存儲和高效的訪問。?
在系統(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)系有多個候選碼,選定其中一個為主碼
? ? 域:屬性的取值范圍
? ? 分量:元組中的一個屬性值
設(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存儲引擎
表及字段的命名規(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ù)庫中的全文索引