1.mysql將所有資料都邏輯地存放在ib_data1檔案中,我們稱之為表空間。當然,你也可以乙個表對應乙個物理檔案,將innodb_file_per_table設定成on即可。 2.表空間又劃為成段,有資料段(leaf node segment),索引段(none-leaf node segment),回滾段(rollback segment)。表空間由這些段和頁組成,比如32頁碎片頁。 3.每段又劃為成區,innodb每次最多可以申請4個區,即4m的儲存空間。 4.每個區又劃為成頁,乙個區劃分成64頁,每個頁的大小是16kb,大小不能夠改,這也固定了乙個區的大小為4m。頁是mysql操作的最小邏輯單位。 5.innodb是面向行的,這就意味著資料行存放在頁中,每頁最多能記錄7992行資料。 6.mysql定義了不同作用的頁型別,比如b-tree page, undo log page等,我們最關心的是b-tree page(資料頁)。實際資料就以這樣的頁邏輯實體存在於表空間,總是以b+樹結構索引組織的。 7.換句話就說,實際資料一行一行地存放在b-tree頁中,這些頁都放在資料段leaf node segment中。b-tree page是b+樹的葉子節點。 8.乙個b-tree樹,由7部分構成
8-2.page header, 這裡記錄了頁本身的一些儲存資訊。比如第乙個記錄的位置,記錄數,最後插入記錄行的位置,該頁的索引id等等
8-3.infimum & supermum records, mysql虛擬的二個行記錄,用來界定記錄的邊界。分別代表此頁中任何pk值還小的值和任何pk值還大的值。
8-4.user records, 實際儲存的行記錄。
8-5.free space,空閒空間,同樣是鍊錶結構。當乙個資料記錄刪除後,就會加入到空閒鍊錶中
8-6.page directory, 存放了記錄的相對位置。注:聚集索引本身找不到具體的一條記錄。而是通過 聚集索引找到該記錄所在的頁,然後再通過page directory進行二分查詢找到具體資料。
8-7.file trailer, mysql innodb利用它來保證頁完整地寫入磁碟。
b+樹,由b樹和索引順序訪問方法演化面來的一種資料結構,較為複雜,常用於磁碟等儲存裝置的一種平衡查詢樹(所謂平衡,請查閱二叉樹和平衡二叉樹)。在b+樹中,所有記錄節點都按鍵值的大小順序存放在同一層葉子節點中,各葉節子節點指標進行鏈結,每個葉子節點到達根節點的距離都是一樣的。下圖分別演示了g和h記錄查詢過程。
mysql innodb一般按照每張表的主鍵構造一顆b+樹,存放在表空間,其中整張表的行記錄就是這顆b+樹的葉子節點,存放在表空間的資料段(leaf node segment)。這就意味著資料行在表空間儲存是有序的。mysql通過b+樹查詢演算法能夠加速資料的訪問,避免掃瞄整個表,大大減少了i/o邏輯操作。mysql innodb查詢某行資料的時候,通常先從root節點,找到子節點,直到找到葉子節點。葉子節點就是資料頁,即(b-tree型別頁),然後通過該頁的page directory進行二分查詢,找到資料行(上文有提到過,mysql是不能通過b-tree索引找到使用者資料行)。
執行select * from user where uid = 92這樣的一句查詢。mysql依照主鍵uid建立的b+樹索引,mysql從這顆b+樹的根節點查詢,一直找到葉子頁的上一層節點,比較鍵值92>91(右邊)最終找到資料葉,在資料葉中找到資料行。當然,也有可能找不到資料行(資料行根本不存在)。
mysql有沒有支援聚集索引,取決於採用哪種儲存引擎。mysql innodb一定會建立聚集索引,所謂聚集,指實際資料行和相關的鍵值儲存在一塊(如上圖),這也決定了乙個表只能有乙個聚集索引,即mysql不會一次把資料行儲存在二個地方。innodb通常根據主鍵值(primary key)進行聚集,但是當乙個表沒有pk怎麼辦?innodb選取聚集索引參照列的順序是 1.如果聲宣告了主鍵(primary key),則這個列會被做為聚集索引 2.如果沒有宣告主鍵,則會用乙個唯一且不為空的索引列做為主鍵,成為此表的聚集索引 3.上面二個條件都不滿足,innodb會自己產生乙個虛擬的聚集索引。優點與缺點聚集索引的優點,就是提高資料訪問效能。聚集索引把索引和資料都儲存到同一棵b+樹資料結構中,並且同時將索引列與相關資料行儲存在一起。這意味著,當你訪問同一資料頁不同行記錄時,已經把頁載入到了buffer中,再次訪問的時候,會在記憶體中完成訪問,不必訪問磁碟。不同於myisam引擎,它將索引和資料沒有放在一塊,放在不同的物理檔案中,這樣索引對應的是磁碟位置,不得不通過磁碟位置訪問磁碟資料。
聚集索引的缺點同他的優點一樣明顯: 1.建立索引比較昂貴,尤其是插入新行或者主鍵被更新導至要分頁(page split)的時候。建議在插入新行後,負載較低的夜間,通過optimize table優化表,因為必須被移動的行資料可能造成碎片。 2.聚集索引有可能比全表掃瞄還慢,尤其是儲存得比較稀疏的時候。這要求設計的時候,盡量避免將uuid做為主鍵,推薦使用int auto_increment列做為**鍵。 3.次要索引(second index)可能會比預想的大,因為它們的葉子節點包含了被索引的主鍵列值。所以,不推薦使用64位的uuid,或者過長的pk值,會導致none-leaf segment占用更多的物理空間。 4.次要索引訪問資料始終需要二次查詢,而不是一次。次要索引葉子節點儲存的不再是行的物理位置,而是主鍵值。通過次要索引首先找到的是pk值,再通過pk值找到數行據的資料葉,再通過資料葉中的page directory找到資料行。設計tips根據上文描述,當你在做innodb表設計的時候,如果不需要任何特定列的聚集,就可以定義乙個**鍵(surrogate key)作為聚集索引的鍵值,該值與應用程式無關,推薦使用auto_increment列。這樣會保證行是順序插入並且能提高使用主鍵聯接的效能。盡可能地避免隨機(亂序)聚集鍵,像uuid,或者md5乙個值。這樣的鍵值會破壞聚集索引帶來的效能幫助。
mysql 資料結構 Mysql索引資料結構
mysql索引資料結構 當慢查詢時,看sql是否走索引。索引的本質 索引是幫助mysql高效獲取資料的排好序的資料結構。mysql若不建立索引,查詢某條資料時則會逐行掃瞄,每掃瞄一行資料就會做一次磁碟io。b tree 葉節點具有相同的深度,葉節點的指標為空。所有索引元素不重複。葉節點中的資料索引從...
mysql資料結構
在剛才新建表的過程中,我們提到了資料型別,mysql 的資料型別和其他程式語言大同小異,下表是一些 mysql 常用資料型別 整數型 整數除了 int 外,還有 tinyint smallint mediumint bigint。字元型 char 和 varchar 的區別 char 的長度是固定的...
MySQL三維資料結構 MySQL資料結構
索引 索引是對資料庫表中一列或多列的值進行排序的一種結構,使用索引可快速訪問資料庫表中的特定資訊。是一種單獨的 物理的對資料庫表中一列或多列的值進行排序的一種儲存結構,它是某個表中一列或若干列值的集合和相應的指向表中物理標識這些值的資料頁的邏輯指標清單。mysql索引的資料結構是b 樹,mongod...