每日三道面試題,通往自由的道路14——MySQL

太子爺哪吒發表於2021-08-01

茫茫人海千千萬萬,感謝這一秒你看到這裡。希望我的面試題系列能對你的有所幫助!共勉!

願你在未來的日子,保持熱愛,奔赴山海!

每日三道面試題,成就更好自我

昨天我們是不是聊到了鎖,而你提到了MySQL?既然這樣

1. 講講你認識MySQL鎖吧

我想我就隨口一提,有必要這樣互相傷害嗎?

辛苦我早有準備,看我表演吧!

對於資料庫來講,讀寫都是非常頻繁的吧,在併發量來的時候,在進行讀寫操作時,可能會產生資料的不一致,這時候需要一些機制來保證訪問的次序,所以鎖就可以在一定限度保護它的一致性。

首先我們可以按鎖的粒度分:

  1. 表級鎖:它上鎖是鎖住的整張表,當下一個事務來訪問的時候,必須等到當前事務把鎖釋放了,才能對錶進行操作訪問。

    特點:表鎖開銷小,加鎖快,然後它的鎖的粒度最大,不會出現死鎖的現象,傳送鎖的衝突的概率最高,併發度最低。

  2. 行級鎖:它上鎖是鎖住一行或者多行的記錄,當下個事務訪問的時候,只有被鎖住的欄位不能訪問,其他可以正常的訪問操作。

    特點:行鎖開銷大,加鎖滿,然後它的鎖的粒度最小,會出現死鎖的現象,傳送鎖的衝突的概率最低,併發度最高。

  3. 頁面鎖:它是介於表鎖和行鎖之間的一種鎖,它鎖住的是相鄰的行記錄。

    特點:因為它是介於表鎖和行鎖之間的,開銷大、加鎖、鎖的粒度、傳送鎖的衝突的概率、併發度都是中等一般的。也會出現死鎖的現象。

我們也可以按鎖的類別分類:

  1. 共享鎖:也稱為讀鎖,簡稱s鎖,當使用者對資料訪問時,對資料加上讀鎖,其他的事務只能對資料也加上讀鎖,而不能加上寫鎖,知道所有的讀鎖釋放完成後,才能對資料進行加寫鎖的操作。然後主要的特性就是加上讀鎖後,支援併發的讀取資料,讀取資料的時候不能進行修改資料,避免重複讀的出現,所以讀鎖也可以加多個。
  2. 排它鎖:也稱為寫鎖,簡稱x鎖,當使用者對資料進行寫入的時候,對資料加上一個寫鎖,其他事務對資料不能加任何鎖包括讀鎖和寫鎖,只能等待寫鎖的釋放才能對資料進行讀取或者寫入操作。主要的特性就是在資料修改的時候,不允許任何進行訪問或修改,可以避免髒資料和髒讀的出現,寫鎖只能加一個,並且和其他的排它鎖和共享鎖互斥。
  3. 意向共享鎖:當一個事務試圖對整個表加上共享鎖時,會首先需要獲取到這個表的意向共享鎖。
  4. 意向排它鎖:當一個事務試圖對整個表加上排它鎖時,會首先需要獲取到這個表的意向排它鎖。

不錯呀!這你也能答得出來?看我後面怎麼治你!

2. 你知道什麼是事務、四大特性、隔離級別嗎?

事務

是資料庫從一種一致性狀態到另一種一致性的狀態,即事務的操作,要麼都執行,要麼都不執行。比如事務是將一組業務操作中的多條SQL語句當做一個整體,那麼這個多條語句要麼都成功執行,要麼都執行失敗。而這資料庫引擎中,InnoDB是支援事務,而MyIASM就不支援啦。

四大特性

  • Atomicity原子性:事務中的各項操作,要麼全部執行成功,要麼全部執行失敗。
  • Consistency一致性:資料庫總是從一個一致性狀態轉換為另一個一致性的狀態。表示事務結束後系統狀態一致。
  • Isolation隔離性:表示多個事務併發訪問時,事務之間是隔離的不可見的。一個事務不會影響到其他事務的執行。
  • Durabilty永續性:表示一個事務一旦提交成功,他對資料庫的資料操作是永久性的。

而這ACID主要是由什麼保證呢?

  • A原子性是由undo log 日誌保證的,它記錄了需要回滾的日誌資訊,事務回滾撤銷時就會執行已經成功的SQL語句
  • C一致性是由其他三大特性保證,並且程式程式碼要保證業務的一致性
  • I隔離性是由MVCC保證
  • D永續性是由記憶體+redo log保證,mysql修改資料的同時在記憶體和redo log日誌中記錄這次操作,如果資料庫當機的話,就可以從redo log中恢復。

隔離級別

  • read-uncommitted讀取未提交:最低的隔離級別,讀取尚未的提交的資料,也被為髒讀,它可能會發生就是髒讀現象和不可重複讀和幻讀現象。

  • read-committed讀已提交:可以讀取併發事務中已經提交的資料,可以有效的阻止髒讀,但是每次讀取的值發生了改變,所以不可重複讀和幻讀仍有可能發生。

  • repeatable-read可重複讀:mysql的預設隔離級別,對同一欄位的讀取多次結果是一致的,可以阻止髒讀和不可重複讀,但是幻讀仍會發生。那幻讀就是本來我讀取的只有一行的資料,此時再次讀取可能多了一行,此時就是幻讀了。

  • serializable可序列化:最高的隔離級別,可以有效的解決髒讀、不可重複讀、幻讀現象。但是效率會比較低。

隔離級別 髒讀 不可重複讀 幻讀
read-uncommitted讀取未提交 可能會出現 可能會出現 可能會出現
read-committed讀已提交 可以解決 可能會出現 可能會出現
repeatable-read可重複讀 可以解決 可以解決 可能會出現
serializable可序列化 可以解決 可以解決 可以解決

對於資料一致性來說,隔離級別越高,越能夠保證資料的完整性和一致性,但是對併發的效能影響越大。大多數資料庫的預設級別是read-committed讀已提交,比如Oracle ,但是 對於MySQL 的預設隔離級別是 repeatable-read可重複讀

不錯,既然知道引擎,就順著問一點唄!

3. MyISAM 和 InnoDB 儲存引擎的區別

對於引擎來說,我們可以使用一個命令來檢視:

SHOW ENGINES;

比較重要的就是這兩個MyISAM和InnoDB。為什麼呢,對於MySQL來說,5版本之前就是使用的MyISAM,而現在預設就是InnoDB了。

MyISAM

對於MyISAM來說併發性比較差,並且不支援事務,所以相對來說,應用的場景會比較少,主要特點有:

  • 不支援事務操作,ACID四大特性也就不存在了。

  • 不支援外來鍵操作,如果強行增加外來鍵,MySQL 不會報錯,只不過外來鍵不起作用。

  • MyISAM 支援的鎖是表級鎖,所以併發效能比較差,加鎖比較快,鎖衝突比較高,但是可以避免死鎖的情況。

  • 儲存結構中,MyISAM會在磁碟上儲存三個檔案,檔名和表名相同,副檔名分別是儲存表定義、儲存資料、儲存索引。

  • MyISAM 支援的索引型別有 全域性索引、B-Tree 索引

  • 效能來說:SELECT 效能較高,適用於查詢較多的情況

InnoDB

現在MySQL預設的儲存引擎,相對於 MyISAM,InnoDB 儲存引擎有了較大的改變,主要特點有:

  • 支援事務操作,具備事務 ACID 隔離特性。

  • InnoDB 支援外來鍵操作。

  • InnoDB 支援鎖不僅有行級鎖也支援表級鎖,行級鎖併發效能比較好,會發生死鎖的情況。

  • 儲存結構中,InnoDB 也有儲存表結構 定義,但是不同的是,InnoDB 的表資料與索引資料是儲存在一起的,都位於 B+ 數的葉子節點上,而 MyISAM 的表資料和索引資料是分開的。

  • InnoDB 有安全的日誌檔案,這個日誌檔案用於恢復因資料庫崩潰或其他情況導致的資料丟失問題,保證資料的一致性。

  • InnoDB 和 MyISAM 支援的索引型別相同,但具體實現因為檔案結構的不同有很大差異。

  • 效能來說,如果需要執行大量的增刪改操作,推薦使用 InnoDB 儲存引擎。

兩者區別

  1. 事務:MYISAM不支援事務,但是每次查詢都是原子性的,而Innodb是支援事務的。
  2. 鎖:MYISAM支援表級鎖,即每次操作都會對整個表枷鎖,而Innodb支援行級鎖,支援寫時高併發
  3. 外來鍵:MYSIAM不支援外來鍵,而Innodb支援外來鍵約束
  4. 儲存表的總行數:MYISAM支援儲表的總行數,而Innodb不支援儲表的總行數
  5. 儲存檔案:MYISAM儲存表有三個檔案,索引檔案,表結構檔案,資料檔案,而Innodb是儲存一個共享檔案,索引和資料儲存在一起,大小會受作業系統檔案大小限制
  6. 場景:MYISAM適合讀比較多,而Innodb適合寫多。

小夥子不錯嘛!今天就到這裡,期待你明天的到來,希望能讓我繼續保持驚喜!

注: 如果文章有任何錯誤和建議,請各位大佬盡情留言!如果這篇文章對你也有所幫助,希望可愛親切的您給個三連關注下,非常感謝啦!也可以微信搜尋太子爺哪吒公眾號私聊我,感謝各位大佬!

相關文章