數(shù)據(jù)庫設(shè)計(jì)三大范式
- 1NF:數(shù)據(jù)表每一列不可拆分(原子性)
- 2NF:每一列都與主鍵相關(guān)(只描述一件事)
- 3NF:每張表都只與主鍵直接相關(guān)
Left join/Right join
使用事務(wù)保持?jǐn)?shù)據(jù)一致性和完整性
Begin:
Commit
使用外鍵
在頻繁進(jìn)行排序分組的列上建立索引
事務(wù)
- 原子性:事務(wù)包含的操作要么全部成功猖闪,要不全部失敗回滾
- 一致性:事務(wù)執(zhí)行前后處于一致性狀態(tài)
- 隔離性:當(dāng)多個(gè)用戶并發(fā)訪問數(shù)據(jù)庫時(shí),數(shù)據(jù)庫為每個(gè)用戶開啟的事務(wù)不被其他事務(wù)的操作所干擾肌厨,多個(gè)并發(fā)事務(wù)之間要相互隔離
- 持久性:事務(wù)一旦提交了培慌,改變就是永久性的
MVCC(多版本并發(fā)控制):保存數(shù)據(jù)的多個(gè)版本來實(shí)現(xiàn)并發(fā)控制
當(dāng)需要更新某條數(shù)據(jù)時(shí),不會(huì)立即用新的數(shù)據(jù)覆蓋原始數(shù)據(jù)夏哭,而是創(chuàng)建該記錄的一個(gè)新的版本检柬。(MySQL是悲觀鎖機(jī)制)
四種隔離級(jí)別
- Serializable:串行化:不會(huì)幻讀,重復(fù)度竖配,臟讀
- Repeatable:可重復(fù)讀:會(huì)幻讀
- Read Committed:讀已提交:僅能讀取到已經(jīng)提交的數(shù)據(jù)(默認(rèn))何址,會(huì)不可重復(fù)讀,會(huì)幻讀
- Read Uncommitted:讀未提交
事務(wù)并發(fā)調(diào)度問題
- 臟讀:讀取未提交进胯,使用version
- 不可重復(fù)讀:讀取之前提交的用爪,更改的數(shù)據(jù)
- 幻讀:讀取之前提交的整批數(shù)據(jù),新增與刪除的數(shù)據(jù)
隔離級(jí)別 | 臟讀 | 不可重復(fù)讀 | 幻讀 |
---|---|---|---|
讀未提交 | 會(huì) | 會(huì) | 會(huì) |
讀已提交 | 不會(huì) | 會(huì) | 會(huì) |
可重復(fù)讀 | 不會(huì) | 不會(huì) | 會(huì) |
串行化 | 不會(huì) | 不會(huì) | 不會(huì) |
數(shù)據(jù)庫的鎖:
- 共享鎖:讀鎖胁镐,阻止其他事務(wù)修改表數(shù)據(jù)
- 排他鎖:寫鎖偎血,阻止其他事務(wù)讀寫
- 行級(jí)鎖(開銷大,枷鎖慢盯漂,會(huì)出現(xiàn)死鎖颇玷,粒度小,并發(fā)度高)就缆,表級(jí)鎖(開銷小帖渠,加鎖塊,不會(huì)出現(xiàn)死鎖竭宰,粒度大空郊,并發(fā)度低)份招,頁鎖
- 意向鎖:先申請(qǐng)意向共享鎖,成功之后申請(qǐng)行鎖:判斷表是否被其他事務(wù)用表鎖鎖定狞甚;發(fā)現(xiàn)表上有共享意向鎖锁摔,表明表中有些行被鎖定了,因此寫鎖會(huì)被阻塞
封鎖協(xié)議
- 一級(jí)封鎖協(xié)議:如果事務(wù)有寫操作哼审,在讀操作之前加排他鎖谐腰,事務(wù)結(jié)束后釋放
- 二級(jí)封鎖協(xié)議:事務(wù)讀取之前加上共享鎖,讀完之后釋放
- 三級(jí)封鎖協(xié)議:事務(wù)讀取數(shù)據(jù)之前加共享鎖棺蛛,事務(wù)完成以后釋放
死鎖-相互等待
- 一次封鎖法
- 順序封鎖法
- 超時(shí)等待
MySQL數(shù)據(jù)庫引擎
MyISAM | InnoDB |
---|---|
不支持事務(wù) | 支持 |
不支持外鍵 | 支持 |
支持全文索引 | 5.6以后版本支持 |
只有表鎖 |
MySQL主備模式
主服務(wù)器會(huì)將每次改動(dòng)寫入到日志中
從服務(wù)器會(huì)讀取日志并執(zhí)行一遍
MySQL的特點(diǎn):
- 核心完全多線程怔蚌,支持多處理器
- 能夠工作在不同的平臺(tái)上
- 通過高度優(yōu)化的類庫實(shí)現(xiàn)SQL函數(shù)庫并能夠快速,查詢初始化以后沒有內(nèi)存分配和內(nèi)存泄漏
索引
索引的存儲(chǔ)類型:B樹索引(Innodb,MyISAM)和哈希索引(MEMORY)
- 普通索引:不加任何條件限制的索引旁赊,可以創(chuàng)建在任何數(shù)據(jù)字段上
- 主鍵索引:根據(jù)主鍵構(gòu)成的索引桦踊,不允許重復(fù),不允許空值
- 唯一索引:限制索引值必須是唯一的(自動(dòng)索引-完整性約束時(shí)創(chuàng)建的索引终畅,設(shè)置為主鍵或者為唯一時(shí)和手動(dòng)索引)
- 全文索引:在數(shù)據(jù)類型為CHAR籍胯,VARCHAR,TEXT上离福,不區(qū)分大小寫杖狼,為二進(jìn)制數(shù)據(jù)類型時(shí)區(qū)分大小寫
- 多列索引:多個(gè)字段構(gòu)成的索引,只有查詢條件使用了鎖關(guān)聯(lián)字段中的第一個(gè)字段妖爷,多列索引才會(huì)使用(最左前綴原則)
BTree索引 度為2d蝶涩,高為h
- 每個(gè)葉子節(jié)點(diǎn)的高度一樣,等于h
- 每個(gè)非葉子節(jié)點(diǎn)由n-1個(gè)key和n個(gè)指針組成絮识,d<=n<=2d绿聘,節(jié)點(diǎn)兩端一定是key
- 葉子節(jié)點(diǎn)的指針都是null
- 非葉子節(jié)點(diǎn)的key都是[key,data]二元組,其中key表示作為索引的鍵次舌,data為鍵值所在行的數(shù)據(jù)
- 查找復(fù)雜度為hlog(n)
B+Tree索引 d為樹的度數(shù)熄攘,h為樹的高度
- B+Tree的非葉子節(jié)點(diǎn)不存儲(chǔ)數(shù)據(jù),只存儲(chǔ)鍵值
- B+Tree的葉子節(jié)點(diǎn)沒有指針彼念,所有的鍵值都會(huì)出現(xiàn)在葉子節(jié)點(diǎn)上挪圾,且key存儲(chǔ)的鍵值對(duì)應(yīng)data數(shù)據(jù)的物理地址
- B+Tree的每個(gè)非葉子節(jié)點(diǎn)由n個(gè)鍵值key和point組成
對(duì)比
- 磁盤讀寫代價(jià)更低:盡可能的減少磁盤IO來加快讀取速度
- 查詢速度更穩(wěn)定:B+Tree非葉子節(jié)點(diǎn)不存儲(chǔ)數(shù)據(jù),因此所有的數(shù)據(jù)都要查詢至葉子節(jié)點(diǎn)逐沙,葉子節(jié)點(diǎn)的高度是相同的
MyISAM-非聚簇索引
- 非聚簇索引的主索引和輔助索引(如果查詢條件不是主鍵)幾乎一樣哲思,只是主索引不允許重復(fù),不允許空值吩案,葉子節(jié)點(diǎn)的key都存儲(chǔ)指向鍵值對(duì)應(yīng)的數(shù)據(jù)的物理地址
- 非聚簇索引的數(shù)據(jù)表和索引表是分開存儲(chǔ)的
- 非聚簇索引的數(shù)據(jù)是根據(jù)數(shù)據(jù)的插入順序保存也殖,因此非聚簇索引更適合單個(gè)數(shù)據(jù)的查詢
圖
image.png
InnoDB-聚簇索引
- 聚簇索引的主索引的葉子節(jié)點(diǎn)存儲(chǔ)的是鍵值對(duì)應(yīng)的數(shù)據(jù)本身,輔助索引的葉子節(jié)點(diǎn)存儲(chǔ)的是鍵值對(duì)應(yīng)的數(shù)據(jù)的主鍵鍵值,因此主鍵的值長度越小越好忆嗜,類型越簡單越好
- 聚簇索引的數(shù)據(jù)和主鍵索引存儲(chǔ)在一起
- 聚簇索引的數(shù)據(jù)是根據(jù)主鍵的順序保存,因此合適按主鍵索引的區(qū)間查找崎岂。
- InnoDB表是基于聚簇索引建立的捆毫,輔助索引搜索需要檢索兩遍索引:首先檢索輔助索引獲得主鍵,然后用主鍵到主索引中檢索獲得記錄冲甘。過長的主索引會(huì)導(dǎo)致輔助索引變得過大
圖
image.png
image.png
char和varchar
- char定義從列的長度是固定的绩卤,右邊以空格填充,檢索時(shí)刪去空格江醇,不進(jìn)行大小寫轉(zhuǎn)換(0-255)
- varchar變長(0-65535,除去起始符和結(jié)束符最大65532)濒憋,保存時(shí)只保存需要的字符數(shù),然后一個(gè)字節(jié)來保存大小陶夜,超過255時(shí)需要兩個(gè)字節(jié)