2015-12-11 114 views
1

目前我在閱讀關於B+ Tree的基礎知識,並且對聚集和非聚集索引的空間分配感到困惑。保存B +樹的聚簇索引和非聚簇索引的位置?

當我們在B+ tree上創建聚簇索引時,索引存儲在主存儲器中,樹葉包含指向實際塊的數據指針。塊存儲在磁盤中,塊包含記錄。

  • 通常聚集索引上創建主鍵
  • 只能有一個聚集索引

現在假設我們有一個表(ID,姓名,班級),我創建了兩個非集羣索引nameclass我的疑問是非聚集索引將被存儲在哪裏

  • 由於ID字段是主密鑰,以便首先使用聚簇索引將ID = 3
  • :以及如何搜索將要 query

    select id, name, class from table where id = 3, name='Leo' and class='10' 
    

    enter image description here

    我的假設來執行

  • 現在使用nameclass上的非聚簇索引,我們會發現其餘的域

你認爲我的假設是正確的嗎?你能詳細解釋一下關於存儲聚集索引嗎? 這兩個索引(聚簇和非聚簇形成一個n-ary樹?)。我無法將聚集索引和非聚集索引一起可視化。

回答

1

我對InnoDB中明確地說......

PRIMARY KEY是(像你說的)聚集與數據。該數據(數據+ PK)的整個BTree存儲在磁盤(而不是「主存儲器」)上的一組塊中。 '葉'節點包含所有列。

輔助密鑰是一個單獨的BTree。在結構上,兩個BTrees與葉節點中的內容除外。對於輔助鍵,將PRIMARY KEY的副本放入葉節點。因此,當使用二級索引查找一行(「點查詢」)時,有兩個BTree下鑽 - 一個用於二級索引,另一個用於PK。

所有塊都'緩存'在'buffer_pool'中,所以它們在主內存中有有時,但始終在磁盤上保持(遲早)。 (交易日誌等)確保「稍後」不違反數據總是存在的規則。)

您的兩張照片是一個不錯的開始。但是...

  • 非葉節點鏈接在一起(如您所示),但它們不一定在磁盤上相鄰。當插入一個新行(或新的索引條目)時,一個塊可能會因爲已滿而「分裂」。這導致塊散落在磁盤周圍。
  • 葉節點也鏈接在一起,但可能是分散的。
  • 對於非集羣,那麼,建議你重新開始,考慮到PK的問題,等等。

你需要知道比照片更高的水平有什麼要表達的:

  • 甲點查詢向下鑽取一個B樹
  • 輔助查找必須做2個鑽取
  • 「範圍」掃描 - 無論是數據,或索引的 - 是非常有效的,因爲它們通過一個塊進行掃描和然後轉到(邏輯上)下一個塊通過底層的塊之間的雙向鏈接。因此,它確實是一個B +樹,而不僅僅是一個BTree。
  • (更多的範圍)WHERE clustered_key BETWEEN ...是非常有效的
  • (更多的範圍)WHERE secondary_key BETWEEN ...是在發現的PK值,它需要非常有效的,但隨後變成一束(潛在的)隨機點的查詢。
  • 所有塊對於緩存來說都非常相當。但是(很明顯?)由於「最近最少使用」算法,非葉節點傾向於生存在緩存中。 (我遺漏了很多細節。)
  • 只能有一個Clustered索引。 (除非你願意複製所有的數據,這是在InnoDB以外的幾個引擎中完成的。)
  • 塊包含儘可能多的'記錄'(數據或索引或非葉)時刻 - 從1到數百之間的任何地方。
  • 默認情況下,塊是16KB。 (並且不容易改變)
  • 隨着innodb_file_per_table = ON,給定表的所有BTrees都存在於一個.ibd'表空間'中。
  • 隨着innodb_file_per_table = OFF,所有表的所有BTrees都存在於一個名爲ibdata1的全局「表空間」中。 (同樣,過於簡單化。)

現在對MyISAM:

  • 爲一個表的生活中的數據在一個文件中(.MYD)。
  • 一個表的所有索引(包括PRIMARY KEY)都存在於一個文件中(.MYI)
  • 所有索引都是BTrees。 (數據不是。)
  • 索引的葉節點「點」到數據文件中。
  • 索引塊爲1KB。
  • 數據文件只是一個隨機訪問流。

(還有很多更多的細節。)

+0

到目前爲止,我已閱讀:)我一直在尋找類似的東西,最好的事情。它極大地澄清了我的疑問 – python

+0

感謝您的讚揚。 「澄清我的疑問」是什麼意思? –

+0

該評論是非常有幫助的。 – python

相關問題