Mysql+innodb數據存儲邏輯

Mysql+innodb數據存儲邏輯。

表空間由段,區,頁組成

ibdata1:共享表空間。即全部的數據都存放在這個表空間內。若是用戶啓用了innodb_file_per_table,則每張表內的數據能夠單獨放到一個表空間內。(只是數據,索引和插入緩衝Bitmap頁面。其餘數據仍是放到共享表中。)mysql

表空間是由各個段組成,有數據段,索引段,回滾段等。數據與索引段都是用B+樹數據結構。sql

是由連續頁組成的空間,在任何狀況下每一個區的大小都是1M,每一個區由64個連續的大小爲16K的頁組成。固然64個這個數目也是要以改變的。但區的大小1M是不能變的,當用記啓用了參數innodb_file_per_table後建立的表大小默認爲96K。前提是先用32個頁大小的碎片頁後。再申請64個連續頁。充分利用碎片頁提升存儲效率。但會犧牲查找效率。數據庫

innodb默認每一個大小爲16K,1.2.X版本後能夠設置>innodb_page_size將頁大小設置爲4K,8K,16K。數組

常見的頁類型有數據結構

  • 數據頁
  • undo頁
  • 系統頁
  • 事務數據頁
  • 插入緩衝位圖頁
  • 插入緩衝空閒列表頁
  • 未壓縮的二進制大對象頁(blog)
  • 壓縮的二進制大對照頁(blog)

頁是由n行組成的,這個抽象跟現實生活中的書本的頁是同樣的。因此數據的記錄格式是也是行格式。
mysql有compact和redundant兩種格式來存放。mysql 5.1默認compact。行與行以前用鏈表結構鏈接起來,redundant主要是用偏移量還肯定數據的順序。
行溢出問題:當行的數據超過16K頁的大小,就是溢出。varchar因爲數據庫不同,頁的大小也不同的。oracle是varchar2是4000字節,mssql的varchar是8000,mysql的varchar是65532字節。數據庫是這樣處理的:將溢出的類型數據放到blog頁中。問題來了。
數據頁的大小16K。即16384字節。爲何varchar能夠存儲65532字節呢?
mysql是這樣處理的:裝溢出的數據放到4個未壓縮blog中。4*16384=65535。將減去3位指針位就是65532。oracle

總結觸類旁通

計算機全部的存儲結構不外乎:數組,鏈表,哈希表,樹,或是幾種組合使用。
如:hashmap是哈希表,1.8後鏈表那塊改爲樹減小了時間複雜度。內存管理,磁盤管理,編譯器的語法樹等。
建議非計算機專業的能夠看看《數據結構》。不少代碼的核心原理在裏面均可以找到。指針

相關文章
相關標籤/搜索