马士兵mysql_MYSQL相关总结(马士兵教育)
MySQL的邏輯結(jié)構(gòu)
客戶端+服務器+存儲引擎
存儲引擎
查看存儲引擎: show engines.我的電腦里默認的是InnoDB;
InnoDB和MyISAM索引采用的是B+樹, MEMORY采用的是Hash索引.
MySql中最常用的的存儲引擎是InnoDB和MyISAM.
前者在磁盤中會落2個文件,分別是.frm和.ibd..frm代表form files,代表格式文件..ibd中包含真實數(shù)據(jù)和索引數(shù)據(jù).
而myISAM中會落3個文件,分別是.frm,.MYD和.MYI,其中后面兩種格式代表真實數(shù)據(jù)和索引數(shù)據(jù).
內(nèi)存和磁盤交互:
磁盤預讀:預讀的長度一般是頁的整數(shù)倍.頁是存儲器(包括內(nèi)存和磁盤)的邏輯塊,通常為4KB,內(nèi)存和磁盤以頁來為單位交換數(shù)據(jù).InnoDB默認一次預讀16KB的數(shù)據(jù).
索引:
為什么要創(chuàng)建索引:
如果沒有索引,查找數(shù)據(jù)是全表掃描,而如果有索引的話,會按照B+樹的結(jié)構(gòu)去查找數(shù)據(jù).
創(chuàng)建索引是個什么過程?
就是把數(shù)據(jù)組織成數(shù)據(jù)結(jié)構(gòu)的過程.
存儲在文件系統(tǒng)中,存儲形式和存儲引擎有關(guān),索引文件的結(jié)構(gòu)包括hash,二叉樹,B樹和B+樹.
hash表:是數(shù)組+鏈表的結(jié)構(gòu).
hash作為索引存在的問題 :
1.哈希函數(shù)不容易選擇
2.hash存儲需要將所有的數(shù)據(jù)文件添加到內(nèi)存(why?待后知后覺),浪費內(nèi)存空間.
3.等值查詢用hash比較快,但是實際中范圍查詢更多,hash不太合適.
以上問題使得hash沒有作為大部分存儲引擎(查找數(shù)據(jù)是與磁盤進行交互)的數(shù)據(jù)結(jié)構(gòu).而MEMORY存儲引擎是在內(nèi)存中進行的,使用它的時候就接受它占內(nèi)存的問題了,另外在內(nèi)存中查找速度很快.
二叉樹,紅黑樹存在的問題:
樹中元素存儲的是數(shù)據(jù)值,樹在物理結(jié)構(gòu)上是數(shù)組進行存放的,可能邏輯結(jié)構(gòu)上很近的數(shù)據(jù)(比如父子)在物理結(jié)構(gòu)上會相差很遠(比如當樹很大時).因此,每次讀取磁盤頁的數(shù)據(jù)很多是用不上的.可能需要進行很多次的IO交互才能夠找到要找的數(shù)據(jù).
都會因為樹的深度太深而造成io次數(shù)變多(指的是內(nèi)存和磁盤交互的次數(shù)),影響讀取的效率.
提升IO效率的兩個方法:
1.減少IO的次數(shù)
2.減少IO的大小
eg:不推薦使用select(*)的原因,是因為它會把磁盤中全表的數(shù)據(jù)都拉到內(nèi)存(mysql的服務)中,然后在內(nèi)存中去進行篩選,篩選完畢后給到客戶端中.
B樹:
樹中節(jié)點存儲的是數(shù)據(jù)塊.
圖中紫色的代表鍵值,它可能是記錄的主鍵.
樹的階數(shù)(degree)等于它可以最多存儲指針的個數(shù)(數(shù)據(jù)的個數(shù)比指針個數(shù)少1).
比如下面的這個示意圖,它最多能夠存3個指針,兩個data,它的degree是3.
假如當前磁盤塊的大小為16KB,每個data占1KB的內(nèi)存,忽略鍵值和指針,一個磁盤塊中可以存16個data,即階為17.那么三層樹可以存儲的數(shù)據(jù)量16+17*16+17*17*16=16*(1+17+17*17)=4912條數(shù)據(jù).從這里可以看出來影響存儲數(shù)據(jù)多少的因素是data的大小,而這個時候B+樹就比較合適了.
B+樹:
同樣的3層樹,如果前兩層只存儲鍵值和指針的話,那么對應存儲的指針數(shù)就會大大增加,假如前兩層每個磁盤可以存儲1600個指針,第三層仍然是存儲16個數(shù)據(jù),那么三層樹總共可以存儲的數(shù)據(jù)量=1600*1600*16 = 40960000,差不多數(shù)據(jù)容量增加了1萬倍.
注意這里為什么特別在意樹的層數(shù)呢?因為樹的層數(shù)越深,查找樹的次數(shù)就越多(最壞情況,單枝退化成了鏈表).
B+樹中有兩種查找方式:一種是對于主鍵的范圍查找和分頁查找,另一種是從根節(jié)點開始,進行隨機查找.
InnoDB和MyISAM所以創(chuàng)建的區(qū)別:
InnoDB,葉子節(jié)點中放置的是數(shù)據(jù),對應.ibd, 聚簇/聚集索引.
注意:
1.InnoDB對主鍵創(chuàng)建索引,也就是把主鍵作為B+樹中的Key,如果沒有主鍵,會選擇唯一鍵,如果沒有唯一鍵,會生成一個6字節(jié)的row_id(不可見)來作為主鍵(都是為了保證key的唯一性).
2.如果創(chuàng)建索引的鍵是其他字段,那么在葉子節(jié)點中存儲的是該記錄的主鍵,然后再通過主鍵索引找到對應的記錄,這個過程叫做回表.
比如下圖中又對表中的name建立了索引(稱為二級索引/輔助索引),如果要執(zhí)行select * from table where name = "ma",根據(jù)"ma"找到了主鍵1,這個時候還需要根據(jù)主鍵回到表中查找所有的列.而如果select id from table where name = "ma"的話,則不會觸發(fā)回表.
MyISAM中葉子節(jié)點沖存儲的是地址,然后根據(jù)地址去查找數(shù)據(jù).所以存儲文件是.MYI,.MYD. 非聚簇索引.
MySQL的B+樹三層還是四層,取決于數(shù)據(jù)量的多少.
主鍵自增:
分布式不推薦(分布式中有自己的主鍵生成策略),
非分布式推薦.
主鍵自增,能夠保證后面插入的數(shù)據(jù)在建立索引時從添加到樹的結(jié)尾.如果主鍵是亂序的話,在創(chuàng)建索引時,會插入到中間位置.如果中間位置滿了,會導致頁分裂,會造成維護上很麻煩.(添加到結(jié)尾,如果數(shù)據(jù)滿了也會造成頁分裂,但沒有中間插入的那種情況嚴重).
索引優(yōu)化相關(guān):
1.盡量用int來存儲索引,它只占4個字節(jié),而varchar會占用比較多的字節(jié).
2.
總結(jié)
以上是生活随笔為你收集整理的马士兵mysql_MYSQL相关总结(马士兵教育)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 可汗学院的数学从零开始学习顺序?
- 下一篇: linux cmake编译源码,linu