mysql 文件组织_数据库如何组织数据?
DBMS設(shè)計(jì)之初便假定數(shù)據(jù)主要位于非易失性的磁盤(pán)上,畢竟內(nèi)存容量有限。而磁盤(pán)的訪問(wèn)速度遠(yuǎn)遠(yuǎn)大于內(nèi)存訪問(wèn)速度,因此數(shù)據(jù)庫(kù)存儲(chǔ)引擎一項(xiàng)重要工作便是:管理數(shù)據(jù)在內(nèi)存與非易失性存儲(chǔ)之間移動(dòng),提高數(shù)據(jù)訪問(wèn)速度和效率。
1.數(shù)據(jù)的組織方式
數(shù)據(jù)在磁盤(pán)上以文件形式存儲(chǔ),數(shù)據(jù)庫(kù)的存儲(chǔ)引擎通常以固定大小的page(有的數(shù)據(jù)庫(kù)稱為block)為單位組織文件,讀寫(xiě)磁盤(pán)均以page為單位。page里可以存放tuples貨metadata貨indexes等。每個(gè)page都有一個(gè)唯一標(biāo)識(shí),DBMS會(huì)維護(hù)page id到物理地址的映射關(guān)系。不同數(shù)據(jù)庫(kù)DBMS產(chǎn)品page大小不同,比如:SQLite 1KB, Oracle/DB2 4KB, SQL Server/PG 8KB, MySQL 16KB。
不同的DBMS組織page的方式也不同,目前較常見(jiàn)的方式是Heap File Organization,page以鏈表(下圖左)或page目錄(下圖右)的形式組織。
鏈表的方式可以通過(guò)記錄header page,維護(hù)data page list和free page list。目錄的方式(樹(shù))則維護(hù)特殊索引頁(yè),記錄數(shù)據(jù)頁(yè)位置。當(dāng)然這兩種方式是可以混合用,綜合他們各自的優(yōu)勢(shì),例如MySQL的默認(rèn)存儲(chǔ)引擎InnoDB B+樹(shù)索引的實(shí)現(xiàn)。
目前還有另一種流行的組織方式Log Structued File Organization。這種方式存儲(chǔ)log記錄,而非傳統(tǒng)意義上的tuple。當(dāng)有insert/update/delete操作發(fā)生時(shí),相應(yīng)的記錄會(huì)追加到數(shù)據(jù)庫(kù)中。其中insert存儲(chǔ)tuple,delete標(biāo)記要?jiǎng)h除的tuple,update只包含被更改的那部分信息。當(dāng)需要去查詢某個(gè)記錄時(shí),會(huì)根據(jù)對(duì)同一條記錄的操作“組裝”出最終結(jié)果,當(dāng)然這里有很多優(yōu)化策略和手段(建索引、compact等),LevelDB,Hbase,RocksDB都是以這種形式存儲(chǔ)組織數(shù)據(jù)的。
2.DBMS如何在內(nèi)存和磁盤(pán)之間移動(dòng)數(shù)據(jù)
數(shù)據(jù)以page為單位讀入內(nèi)存、寫(xiě)入磁盤(pán),那么數(shù)據(jù)的移動(dòng)何時(shí)發(fā)生,如何操作呢?OS的mmap功能可以將文件映射到內(nèi)存,那么能不能直接利用OS的換頁(yè)機(jī)制來(lái)處理page移動(dòng)呢?這么做的問(wèn)題在于(1)0DBMS喪失了對(duì)page的控制權(quán),無(wú)法合理調(diào)度讀取/刷盤(pán)。(2)OS在處理一個(gè)不在內(nèi)存的OS page時(shí)會(huì)stall線程。當(dāng)然一些數(shù)據(jù)庫(kù)有辦法在一定程度上規(guī)避部分問(wèn)題,如早期的MongoDB。但完善的數(shù)據(jù)庫(kù)系統(tǒng)一般會(huì)選擇自己處理數(shù)據(jù)的移動(dòng)、管理內(nèi)存中的page。
數(shù)據(jù)庫(kù)在內(nèi)存的buffer pool便是用來(lái)緩存磁盤(pán)中讀取上來(lái)的page。buffer pool 同樣以page大小管理組織內(nèi)存塊,這樣一塊內(nèi)存被稱為frame。當(dāng)DBMS需要時(shí),會(huì)將磁盤(pán)中的page拷貝到一個(gè)frame中。當(dāng)然有一個(gè)page table會(huì)記錄內(nèi)存中的所有page及相關(guān)的元信息(Dirty Flag、PIN counter等)。不少數(shù)據(jù)庫(kù)不只有一個(gè)buffer pool。
那么哪些page會(huì)被載入內(nèi)存呢?當(dāng)查詢的目標(biāo)數(shù)據(jù)所在page不在內(nèi)存時(shí),會(huì)去磁盤(pán)讀取,并放入buffer pool緩存,以備后用。這其中有很多優(yōu)化策略。例如:(1)pre-fetch,即根據(jù)數(shù)據(jù)排列順序或索引順序預(yù)取后續(xù)page到內(nèi)存,這對(duì)scan查詢有很好的優(yōu)化效果。(2)scan sharing,查詢結(jié)果被多個(gè)相似的查詢重用或某個(gè)表的cursor被多個(gè)查詢復(fù)用。
而buffer pool滿了后需要換頁(yè),一般選擇LRU及其各類(lèi)優(yōu)化版本。
總結(jié)
以上是生活随笔為你收集整理的mysql 文件组织_数据库如何组织数据?的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 猜画小歌是什么?谷歌AI首款微信小程序《
- 下一篇: mysql的natural join_M