1. 程式人生 > 實用技巧 >mysql相關筆記

mysql相關筆記

mysql面試題

區域性性原理

取資料會多取一些資料出來放到記憶體中,通常為一頁,一頁4kb大小。

mysql兩種儲存引擎對比

innodb資料頁結構

innodb頁單位,16kb

innodb聚集索引

如果沒有定義主鍵,那麼innodb會判斷有沒有唯一索引,如果存在唯一索引,那麼就會把這個唯一索引當作主鍵,如果連唯一索引都沒有,就會自動生成一個欄位(row_id),自增ID。

row_id是一個隱藏列,只有在select語句時才會被查詢出來。

b+樹:

葉子結點:只存資料

非葉子結點:存主鍵+指標

innodb採用的是聚集索引,索引和資料是在同一份檔案儲存。

create index idx_t1_bcd on t1(b, c, d);

b,c,d為輔助索引,通過對比各索引上的資料的大小進行排序。

先比b的大小,b相等再比c,c相等再比d,以此類推。得到排序後的“序號”,和該序號對應的主鍵索引的值,最後通過回表查詢,獲取主鍵索引對應的真實的資料。

![](https://borinboy.oss-cn-shanghai.aliyuncs.com/huan/20200718095136.png style="zoom:33%;" /)

輔助索引,葉子結點儲存資料和主鍵索引的值,再通過回表查詢,查詢主鍵索引查詢真實的資料

通過查詢輔助索引查出來主鍵索引的個數佔主鍵索引總數的80%以上,走全表查詢

正常utf8是0到4個位元組大小

mysql utf8是0到3個位元組大小,有些字元是不支援的,mysql中的utf8mb4是標準的utf8編碼格式

最左字首原則

b,c,d是索引
1,*,*,走索引,1**肯定比644小
*,1,*,不走索引,因為無法判斷*1*和644哪個大哪個小
# 不走索引
select b from t1 group by b,c,d
# 走索引,相當於還是最左字首原則
select b from t1 where b=1 group by b,c,d

事務

ACID

原子性

隔離性

一致性

完整性

mysql事務中有autocommit屬性

隱式提交

update之後,沒有commit,再執行create,alter等ddl操作,會隱式的commit

mysql事務儲存點

四種隔離級別:

  • 讀未提交:一個事務可以讀到其他事務還未提交的資料,髒讀(不可重複讀)。

    用得不多,不嚴謹,違背事務的特性。

  • 讀已提交:一個事務只能讀到另一個已經提交的事務修改過的資料,並且其他事務每對該資料修改並進行提交後,該事務都能查詢到最新的值,會出現不可重複讀,幻讀

    read commit級別,一個事務加了寫鎖時,其他事務可以對已加鎖的事務所查出來的資料做插入操作。

    前一個事務提交資料之後,第二個事務讀取到最新的值,前一個事務再次更新資料,第二個事務讀取到的值發生改變,好像是出現了幻覺。

  • 可重複讀(mysql預設的隔離級別

    一個事務第一次讀取過某條記錄之後,即使其他事務修改了該記錄的值並且提交,該事務之後再讀該條記錄後,讀到的資料依然還是第一次讀取的值,而不是每次都讀到不同的資料,這就是可重複讀,這種隔離級別解決了不可重複讀,但是還是會出現幻讀

    repeatable read加寫鎖時,其他事務不能對已查出來的資料進行插入操作。

  • 序列化

    一個事務在修改某些資料的時候,其他事務操作該資料會出現阻塞,必須等修改資料的事務提交之後才能操作。用得很少。

版本鏈

對於使用InnoDB儲存引擎的表來說,它的聚簇索引記錄中都包含兩個必要的隱藏列(row_id並不是必要的,我們 建立的表中有主鍵或者非NULL唯一鍵時都不會包含row_id列):

  • trx_id:每次對某條記錄進行改動時,都會把對應的事務id賦值給trx_id隱藏列。
  • roll_pointer:每次對某條記錄進行改動時,這個隱藏列會存一個指標,可以通過這個指標找到該記 錄修改前的資訊。(版本,最新的版本會指向之前的一個版本)

readview

m_ids:已修改還未提交的事務,會儲存其id至m_ids內,

可重複讀是即使其他事務修改並提交了資料,但是m_ids依然保持不變,仍然認為這些是活躍的事務id。

MVCC(多併發版本控制)

MVCC(Multi-Version Concurrency Control ,多版本併發控制)指的就是在使用READ COMMITTD、 REPEATABLE READ這兩種隔離級別的事務在執行普通的SEELCT操作時訪問記錄的版本鏈的過程。可以使不同 事務的讀-寫、寫-讀操作併發執行,從而提升系統性能。READ COMMITTD、REPEATABLE READ這兩個隔離級 別的一個很大不同就是:生成ReadView的時機不同,READ COMMITTD在每一次進行普通SELECT操作前都會 生成一個ReadView,而REPEATABLE READ只在第一次進行普通SELECT操作前生成一個ReadView,之後的查 詢操作都重複使用這個ReadView就好了

間隙加鎖

repeatable read加寫鎖時,其他事務不能對已查出來的相關資料進行插入操作。