用了這么久mysql,你mysql中一行數(shù)據(jù)是怎么存儲的嗎?
眾所周知,mysql的數(shù)據(jù)文件是保存在磁盤上的,但中間的數(shù)據(jù)具體保存在哪個文件夾下面呢?
其實不然,了解過數(shù)據(jù)庫索引的小伙伴都知道,mysql中有不同種類的索引,哪這些索引與mysql存儲數(shù)據(jù)又有什么關(guān)系?今天就解決這個問題
一、mysql數(shù)據(jù)存放在哪?
在本地mysql中建了leetcode庫,中間創(chuàng)建了實例表t_order,具體如下圖所示:
在存儲表數(shù)據(jù)的目錄中會出現(xiàn)如下的文件:
其中:
db.opt:存儲了當前數(shù)據(jù)庫的默認字符集和字符校驗規(guī)則
t_order.frm:存儲了表結(jié)構(gòu),在mysql的InnoDB引擎規(guī)則下,新建一張表,就會生成一個以表名開頭,以.frm結(jié)尾的文件;
t_order.ibd:會存儲該表中的具體數(shù)據(jù),每一張表的數(shù)據(jù)都存存放在該文件夾下,新建一張表,就會生成一個以表名開頭,以.ibd結(jié)尾的文件;
二、數(shù)據(jù)以什么樣的形式存放?
在InnoDB引擎中,表空間由段(segment),區(qū)(extent),頁(page),行(row)組成,他們之間的關(guān)系是:一個段由多個區(qū)組成,一個區(qū)由多個頁組成,一個頁由多個行組成
行:數(shù)據(jù)庫表中的記錄都是按照行來存儲的,根據(jù)不同的引擎,有不同的存儲結(jié)構(gòu)
頁:在讀取數(shù)據(jù)的時候,是按照頁為單位進行讀取的,并不以行讀取;一個頁默認大小是16kb,也就是最多能保證16kb的連續(xù)存儲;當我們客戶端讀取數(shù)據(jù)的時候,并不是把行數(shù)據(jù)讀取,而是把該行所在的頁全部讀取到內(nèi)存中;在這里,我們只需要知道數(shù)據(jù)讀取的最小單位是頁即可;
區(qū):在B+數(shù)中,每一層都是通過雙向鏈表進行鏈接;在頁的定義中,我們知道,一個頁里面的數(shù)據(jù)一定是連續(xù),頁與頁之間不一定是連續(xù)的,如果頁與頁之間的物理位置并不是連續(xù)的,那么讀取數(shù)據(jù)時候就會產(chǎn)生大量的磁盤IO,導致性能下降;那么該怎么解決這個問題?
??既然不相鄰會產(chǎn)生大量的磁盤IO,那么我們讓頁與頁之間彼此相鄰,不就解決了嗎?為此,在表中數(shù)據(jù)量很大的時候,為某個索引分配空間的時候就不再按照以頁為單位進行分配,而是以區(qū)為單位進行分配,每個區(qū)的大小默認為1MB,對于16kb大小的頁來說,連續(xù)的64頁會被分到同一個區(qū)中,這樣就使得鏈表中相鄰的頁的物理位置相鄰,減少磁盤IO
??段:包括數(shù)據(jù)段(B+樹種葉子節(jié)點的集合),索引段(B+樹中非葉子節(jié)點的集合),回滾段
#??蛣?chuàng)作賞金賽##懸賞#不定期分享大數(shù)據(jù)相關(guān)技術(shù)面經(jīng),本著免費原則,隨意白嫖