數(shù)據(jù)庫(kù)的三大范式
A:第一范式
??數(shù)據(jù)庫(kù)表中不能出現(xiàn)重復(fù)的記錄俭正,每個(gè)字段是原子性的不能再分
學(xué)生編號(hào) | 學(xué)生姓名 | 聯(lián)系方式 |
---|---|---|
1001 | 張三 | zs@gmail.com,1359999999 |
1002 | 李四 | ls@gmail.com,13699999999 |
1001 | 王五 | [ww@163.net,13488888888 |
存在問題:
1: 最后一條記錄和第一條重復(fù)(不唯一奸鬓,沒有主鍵)
2: 聯(lián)系方式字段可以再分,不是原子性的
B:第二范式
??第二范式是建立在第一范式基礎(chǔ)上的掸读,另外要求所有非主鍵字段完全依賴主鍵串远,不能產(chǎn)生部分依賴
學(xué)生編號(hào) | 學(xué)生姓名 | 教師編號(hào) | 教師姓名 |
---|---|---|---|
1001 | 張三 | 001 | 王老師 |
1002 | 李四 | 002 | 趙老師 |
1003 | 王五 | 001 | 王老師 |
1001 | 張三 | 002 | 趙老師 |
確實(shí)主鍵:
學(xué)生編號(hào)(PK) | 學(xué)生姓名(PK) | 教師編號(hào) | 教師姓名 |
---|---|---|---|
1001 | 張三 | 001 | 王老師 |
1002 | 李四 | 002 | 趙老師 |
1003 | 王五 | 001 | 王老師 |
1001 | 張三 | 002 | 趙老師 |
以上雖然確定了主鍵,但此表會(huì)出現(xiàn)大量的冗余儿惫,主要涉及到的冗余字段為“學(xué)生姓名”和“教師姓名”澡罚,出現(xiàn)冗余的原因在于,學(xué)生姓名部分依賴了主鍵的一個(gè)字段學(xué)生編號(hào)姥闪,而沒有依賴教師編號(hào),而教師姓名部門依賴了主鍵的一個(gè)字段教師編號(hào)砌烁,這就是第二范式部分依賴筐喳。
學(xué)生信息表
學(xué)生編號(hào)(PK) | 學(xué)生姓名 |
---|---|
1001 | 張三 |
1002 | 李四 |
1003 | 王五 |
教師信息表
教師編號(hào)(PK) | 教師姓名 |
---|---|
001 | 王老師 |
002 | 趙老師 |
教師和學(xué)生的關(guān)系表
學(xué)生編號(hào)(PK) fk->學(xué)生表的學(xué)生編號(hào) | 教師編號(hào)(PK) fk->教師表的教師編號(hào) |
---|---|
1001 | 001 |
1002 | 002 |
1003 | 001 |
1001 | 002 |
如果一個(gè)表是單一主鍵,那么它就復(fù)合第二范式函喉,部分依賴和主鍵有關(guān)系
以上是一種典型的“多對(duì)多”的設(shè)計(jì)
C:第三范式
??建立在第二范式基礎(chǔ)上的避归,非主鍵字段不能傳遞依賴于主鍵字段。(不要產(chǎn)生傳遞依賴)
學(xué)生編號(hào)(PK) | 學(xué)生姓名 | 班級(jí)編號(hào) | 班級(jí)名稱 |
---|---|---|---|
1001 | 張三 | 01 | 一年一班 |
1002 | 李四 | 02 | 一年二班 |
1003 | 王五 | 03 | 一年三班 |
1004 | 趙六 | 03 | 一年三班 |
從上表可以看出管呵,班級(jí)名稱字段存在冗余梳毙,因?yàn)榘嗉?jí)名稱字段沒有直接依賴于主鍵,班級(jí)名稱字段依賴于班級(jí)編號(hào)捐下,班級(jí)編號(hào)依賴于學(xué)生編號(hào)账锹,那么這就是傳遞依賴,解決的辦法是將冗余字段單獨(dú)拿出來建立表坷襟,如:
學(xué)生信息表
學(xué)生編號(hào)(PK) | 學(xué)生姓名 | 班級(jí)編號(hào) | 班級(jí)名稱 |
---|---|---|---|
1001 | 張三 | 01 | 一年一班 |
1002 | 李四 | 02 | 一年二班 |
1003 | 王五 | 03 | 一年三班 |
1004 | 趙六 | 03 | 一年三班 |
班級(jí)信息表
班級(jí)編號(hào)(PK) | 班級(jí)名稱 |
---|---|
01 | 一年一班 |
02 | 一年二班 |
03 | 一年三班 |
以上設(shè)計(jì)是一種典型的一對(duì)多的設(shè)計(jì)奸柬,一存儲(chǔ)在一張表中,多存儲(chǔ)在一張表中婴程,在多的那張表中添加外鍵指向一的一方的主鍵
總結(jié):
??第一范式:有主鍵廓奕,具有原子性,字段不可分割
??第二范式:完全依賴,沒有部分依賴
??第三范式:沒有傳遞依賴
數(shù)據(jù)庫(kù)設(shè)計(jì)盡量遵循三范式桌粉,但是還是根據(jù)實(shí)際情況進(jìn)行取舍蒸绩,有時(shí)可能會(huì)拿冗余換速度,最終用目的要滿足客戶需求铃肯。
數(shù)據(jù)庫(kù)的存儲(chǔ)引擎
1.查看存儲(chǔ)引擎
- 數(shù)據(jù)庫(kù)中的各表均被(在創(chuàng)建表時(shí))指定的存儲(chǔ)引擎來處理
- 服務(wù)器可用的引擎依賴于以下因素:
? MySQL的版本
? 服務(wù)器在開發(fā)時(shí)如何被配置
? 啟動(dòng)選項(xiàng)
查看當(dāng)前數(shù)據(jù)庫(kù)有哪些存儲(chǔ)引擎可用患亿,使用mysql> SHOW ENGINES\G
? 在創(chuàng)建表時(shí),可使用ENGINE選項(xiàng)為CREATE TABLE語句顯式指定存儲(chǔ)引擎缘薛。CREATE TABLE TABLENAME (NO INT) ENGINE = MyISAM;
? 如果在創(chuàng)建表時(shí)沒有顯式指定存儲(chǔ)引擎窍育,則該表使用當(dāng)前默認(rèn)的存儲(chǔ)引擎
? 默認(rèn)的存儲(chǔ)引擎可在my.ini配置文件中使用default-storage-engine選項(xiàng)指定。
? 現(xiàn)有表的存儲(chǔ)引擎可使用ALTER TABLE語句來改變:ALTER TABLE TABLENAME ENGINE = INNODB;
? 為確定某表所使用的存儲(chǔ)引擎宴胧,可以使用SHOW CREATE TABLE或SHOW TABLE STATUS語句:
mysql> SHOW CREATE TABLE tablename\G
mysql> SHOW TABLE STATUS LIKE 'tablename' \G
2.常用的存儲(chǔ)引擎
MyISAM存儲(chǔ)引擎
? MyISAM存儲(chǔ)引擎是MySQL最常用的引擎漱抓。
? 它管理的表具有以下特征:
??–使用三個(gè)文件表示每個(gè)表:
????? 格式文件 — 存儲(chǔ)表結(jié)構(gòu)的定義(mytable.frm)
????? 數(shù)據(jù)文件 — 存儲(chǔ)表行的內(nèi)容(mytable.MYD)
????? 索引文件 — 存儲(chǔ)表上索引(mytable.MYI)
??– 靈活的AUTO_INCREMENT字段處理
??– 可被轉(zhuǎn)換為壓縮、只讀表來節(jié)省空間
InnoDB存儲(chǔ)引擎
? InnoDB存儲(chǔ)引擎是MySQL從5.5版本的缺省引擎恕齐。
? 它管理的表具有下列主要特征:
??– 每個(gè)InnoDB表在數(shù)據(jù)庫(kù)目錄中以.frm格式文件表示
??– InnoDB表空間tablespace被用于存儲(chǔ)表的內(nèi)容
??– 提供一組用來記錄事務(wù)性活動(dòng)的日志文件
??– 用COMMIT(提交)乞娄、SAVEPOINT及ROLLBACK(回滾)支持事務(wù)處理
??– 提供全ACID兼容
??– 在MySQL服務(wù)器崩潰后提供自動(dòng)恢復(fù)
??– 多版本(MVCC)和行級(jí)鎖定
??– 支持外鍵及引用的完整性,包括級(jí)聯(lián)刪除和更新
MEMORY存儲(chǔ)引擎
? 使用MEMORY存儲(chǔ)引擎的表显歧,其數(shù)據(jù)存儲(chǔ)在內(nèi)存中仪或,且行的長(zhǎng)度固定,這兩個(gè)特點(diǎn)使得MEMORY存儲(chǔ)引擎非呈恐瑁快范删。
? MEMORY存儲(chǔ)引擎管理的表具有下列特征:
??– 在數(shù)據(jù)庫(kù)目錄內(nèi),每個(gè)表均以.frm格式的文件表示拷肌。
??– 表數(shù)據(jù)及索引被存儲(chǔ)在內(nèi)存中到旦。
??– 表級(jí)鎖機(jī)制。
??– 不能包含TEXT或BLOB字段巨缘。
? MEMORY存儲(chǔ)引擎以前被稱為HEAP引擎添忘。
選擇合適的存儲(chǔ)引擎
? MyISAM表最適合于大量的數(shù)據(jù)讀而少量數(shù)據(jù)更新的混合操作。MyISAM表的另一種適用情形是使用壓縮的只讀表若锁。
? 如果查詢中包含較多的數(shù)據(jù)更新操作搁骑,應(yīng)使用InnoDB。其行級(jí)鎖機(jī)制和多版本的支持為數(shù)據(jù)讀取和更新的混合操作提供了良好的并發(fā)機(jī)制又固。
? 可使用MEMORY存儲(chǔ)引擎來存儲(chǔ)非永久需要的數(shù)據(jù)仲器,或者是能夠從基于磁盤的表中重新生成的數(shù)據(jù)。
數(shù)據(jù)庫(kù)的隔離級(jí)別
1. 數(shù)據(jù)庫(kù)的四大特性
(1)原子性(Atomicity):原子性是指事務(wù)包含的所有操作必須是一個(gè)整體仰冠,要么全部成功娄周,要么全部失敗。不能事務(wù)中某一條或幾條操作的失敗而其他操作影響到數(shù)據(jù)庫(kù)沪停。
(2) 一致性(Consistency):指數(shù)據(jù)庫(kù)只能有一個(gè)一致性狀態(tài)變?yōu)榱硪粋€(gè)一致性狀態(tài)煤辨。臥槽裳涛,這個(gè)用語言怎么說嘛!V诒妗端三!舉個(gè)栗子,銀行轉(zhuǎn)賬A,B兩個(gè)用戶一共5000塊錢鹃彻,那么不管他們?cè)趺崔D(zhuǎn)都只有5000塊錢郊闯。
(3) 隔離性(Isolation):指當(dāng)同時(shí)進(jìn)行多個(gè)事務(wù)時(shí)。一個(gè)事務(wù)不能被另一個(gè)事務(wù)的操作干擾蛛株。
(4) 持久性(Durability): 指一旦一個(gè)事務(wù)提交之后团赁,對(duì)數(shù)據(jù)庫(kù)的操作是永久的,不能因?yàn)槠渌驅(qū)е聛G失所做的操作谨履。
2.問題
(1)由于很多情況是在并發(fā)的環(huán)境下訪問數(shù)據(jù)庫(kù)欢摄,可能會(huì)帶來一下幾個(gè)問題:
臟讀: 一個(gè)事務(wù)中讀取到另一個(gè)事務(wù)未提交的數(shù)據(jù)。如轉(zhuǎn)賬是A正在給B賬戶轉(zhuǎn)錢笋粟,而B正好查看賬戶怀挠,此時(shí)A并未提交事務(wù),就會(huì)導(dǎo)致A.B兩看到的賬戶的錢有問題害捕。
不可重復(fù)讀:不可重復(fù)讀是指在對(duì)于數(shù)據(jù)庫(kù)中的某個(gè)數(shù)據(jù)绿淋,一個(gè)事務(wù)范圍內(nèi)多次查詢卻返回了不同的數(shù)據(jù)值,這是由于在查詢間隔尝盼,被另一個(gè)事務(wù)修改并提交了吞滞。如AB有一個(gè)公共賬戶。A 不停的向這個(gè)賬戶轉(zhuǎn)錢盾沫,B不停的查看賬戶(有病),會(huì)導(dǎo)致B每次看到的錢都不一樣(媽的裁赠,加錢還想怎樣)。
虛讀(幻讀): 解釋不來疮跑。大概就是A修改了賬戶组贺,B也在修改凸舵,A修改在B之后祖娘,然而B修改后查看表發(fā)現(xiàn)并不是自己修改的數(shù)據(jù),就懷疑眼睛花了啊奄,就幻覺了渐苏。。菇夸。琼富。
四種隔離級(jí)別
針對(duì)這幾種問題,MySQL提供了四種隔離級(jí)別來對(duì)應(yīng):
① Serializable (串行化):可避免臟讀庄新、不可重復(fù)讀鞠眉、幻讀的發(fā)生薯鼠。太慢⌒堤#基本不用出皇,鎖,只能一個(gè)一個(gè)來哗戈。
② Repeatable read (可重復(fù)讀):可避免臟讀郊艘、不可重復(fù)讀的發(fā)生。
③ Read committed (讀已提交):可避免臟讀的發(fā)生唯咬。
④ Read uncommitted (讀未提交):最低級(jí)別纱注,任何情況都無法保證。