mysql數據儲存


從磁盤讀取或者寫入數據時,我們通常會指定一個緩沖區大小,達到緩沖區域大小才會寫入一次數據,較少IO操作次數。同樣的從磁盤讀取數據時候,就操作系統而言,讀取一條較小的數據時,並不是只會返回我們需要的數據,而是會將這個數據前后的部分數據一並讀取到內存中,以備之后使用。這個從磁盤讀取的最小量的數據被稱為頁,操作系統一頁的大小是4K,而MySQL一頁的大小為16k。每一次讀取至少都是一頁大小的數據。

數據儲存

MySQL是一個行數據庫,以一張表為例,當我定義好字段信息后,只需要按照字段約束一行行添加數據即可,每一條數據就是一行。為了方便查詢,每一行數據都有一個唯一主鍵標識(自定義或者使用默認的row_id),並按照數據主鍵進行排序。排序的好處就是能夠方便的快速查詢,例如使用二分的手段,大大減少查詢次數。而MySQL使用的手段的B+樹索引,顧名思義,索引就是一個目錄的存在。

數據是一頁一頁的被查詢,而一頁大小為16k,一行行記錄在一個頁中的管理大致如下:

在這樣一頁中保存了10行數據(主要根據一行數據的大小而定),並建立一個頁索引方便查詢,查詢時會先從頁索查找,而不用直接遍歷一個個頁,減少查詢次數。從上面的方式可以從頁中查詢數據,但是在大量的數據中如何定位一條數據的所在的頁呢,這就需要使用B+樹索引

B+樹索引

主鍵索引

在索引的各個節點中,只會保存主鍵的id值,這通常是一個非常小的數字,所以一個16K的頁通常就能保存這個二叉樹的數據,這樣就構成了一個索引頁(目錄頁),這個索引頁通常可以直接緩存在內存中的,當我們查詢一個條數據時候,根據id值的與二叉樹各個節點進行比較,只需要通過幾次查詢能找出數據所在的頁位置,讀取即可。

普通索引

除了主鍵索引的其他索引我們都將其看作普通索引,普通索引會將該索引列的值進行排序,在建立一個B+索引樹,和主鍵的B+樹不同的是,主鍵索引的葉子節點上的主鍵值直接關聯行數據,而普通索引葉子節點關聯的數據是主鍵的值,還需要再次通過主鍵進行查詢。

通過主鍵直接可以找到這個主鍵關聯的數據,而使用普通的索引,首先會找到目標數據的主鍵,在通過主鍵索引獲取,需要進行一個回表的操作。當然,如果想要查詢的數據在可以在這個普通索引的葉子節點中就包含,則不需要回表,而是直接索引覆蓋。

例如有5個字段,a,b,c,d,e,a為主鍵,b為普通索引。如果使用select a,b,c from table where b=1,首先會使用b字段的索引找到對應數據的主鍵,在通過主鍵查詢到數據中的a,b,c字段各自的值。這就需要一個個回表操作。而使用select a,b from table where b=1 查詢時,我們只需要a,b兩個字段的數據,首先依然通過字段b的索引查找主鍵,找到后,由於b字段和主鍵值已經得到,將不會再根據主鍵去找到全部數據,從而避免了回表操作,加快了查詢速度。

唯一索引

唯一索引在普通索引的基礎上對索引增加了唯一值約束,要求索引列的值必須唯一。在插入數據時候,會查詢通過比較保證該值是唯一的,由於比較的操作,每次插入或者更新數據就必須讀取磁盤中的數據進行比較,然后將數據進行寫入。而普通索引在插入數據時,並不會直接插入數據,而是先將本次插入寫入內存中的change buffer,等待寫入的數據足夠多時候,才會正真到磁盤中寫入數據。這樣在大量的寫操作時,比唯一索引更加有效率。而每次讀取數據時候,讀取的數據需要同change buffer中的內容進行一次merge操作,所以在大量讀取的情況下,反而增加change bufffer的維護成本。

聯合索引

聯合索引是指使用多個字段聯合建立索引,例如有5個字段,a,b,c,d,e,使用cde字段聯合建立一個索引。同樣的,將三個字段的值合並到一起進行排序,然后建立索引B+樹,葉子節點關聯主鍵值。聯合索引建立和多個字段的指定順序有關,當使用這個聯合索引查詢時,需要優先使用第一個字段進行匹配,如果第一個字段不存在,查詢過程中無法通過二叉樹的比較快速定位數據,只能通過全表掃描的方式。使用普通索引時候,如果不是唯一索引,那么可能再b+樹的節點中會出現重復的值,為了區分,重復的值會帶上主鍵值以示區分。保證數據按照規則排序。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM