MySQL數據庫常見面試問題

MyISAM和InnoDB區別

MyISAM是MySQL的默認數據庫引擎(5.5版之前)。雖然性能極佳,而且提供了大量的特性,包括全文索引、壓縮、空間函數等,但MyISAM不支持事務和行級鎖,而且最大的缺陷就是崩潰後無法安全恢復。不過,5.5版本之後,MySQL引入了InnoDB(事務性數據庫引擎),MySQL 5.5版本後默認的存儲引擎爲InnoDB。

大多數時候我們使用的都是 InnoDB 存儲引擎,但是在某些情況下使用 MyISAM 也是合適的比如讀密集的情況下。(如果你不介意 MyISAM 崩潰恢復問題的話)。

兩者的對比:

  1. 是否支持行級鎖 : MyISAM 只有表級鎖(table-level locking),而InnoDB 支持行級鎖(row-level locking)和表級鎖,默認爲行級鎖。
  2. 是否支持事務和崩潰後的安全恢復: MyISAM 強調的是性能,每次查詢具有原子性,其執行速度比InnoDB類型更快,但是不提供事務支持。但是InnoDB 提供事務支持事務,外部鍵等高級數據庫功能。 具有事務(commit)、回滾(rollback)和崩潰修復能力(crash recovery capabilities)的事務安全(transaction-safe (ACID compliant))型表。
  3. 是否支持外鍵: MyISAM不支持,而InnoDB支持。
  4. 是否支持MVCC :僅 InnoDB 支持。應對高併發事務, MVCC比單純的加鎖更高效;MVCC只在 READ COMMITTED 和 REPEATABLE READ 兩個隔離級別下工作;MVCC可以使用 樂觀(optimistic)鎖 和 悲觀(pessimistic)鎖來實現;各數據庫中MVCC實現並不統一。推薦閱讀:MySQL-InnoDB-MVCC多版本併發控制
  5. ......

什麼是事務?

事務是邏輯上的一組操作,要麼都執行,要麼都不執行。

事務最經典也經常被拿出來說例子就是轉賬了。假如小明要給小紅轉賬1000元,這個轉賬會涉及到兩個關鍵操作就是:將小明的餘額減少1000元,將小紅的餘額增加1000元。萬一在這兩個操作之間突然出現錯誤比如銀行系統崩潰,導致小明餘額減少而小紅的餘額沒有增加,這樣就不對了。事務就是保證這兩個關鍵操作要麼都成功,要麼都要失敗。

事物的四大特性(ACID)

事物的特性

  1. 原子性(Atomicity): 事務是最小的執行單位,不允許分割。事務的原子性確保動作要麼全部完成,要麼完全不起作用;
  2. 一致性(Consistency): 執行事務前後,數據保持一致,多個事務對同一個數據讀取的結果是相同的;
  3. 隔離性(Isolation): 併發訪問數據庫時,一個用戶的事務不被其他事務所幹擾,各併發事務之間數據庫是獨立的;
  4. 持久性(Durability): 一個事務被提交之後。它對數據庫中數據的改變是持久的,即使數據庫發生故障也不應該對其有任何影響。

 

併發事務帶來哪些問題?

在典型的應用程序中,多個事務併發運行,經常會操作相同的數據來完成各自的任務(多個用戶對同一數據進行操作)。併發雖然是必須的,但可能會導致以下的問題。

  • 髒讀(Dirty read): 當一個事務正在訪問數據並且對數據進行了修改,而這種修改還沒有提交到數據庫中,這時另外一個事務也訪問了這個數據,然後使用了這個數據。因爲這個數據是還沒有提交的數據,那麼另外一個事務讀到的這個數據是“髒數據”,依據“髒數據”所做的操作可能是不正確的。
  • 丟失修改(Lost to modify): 指在一個事務讀取一個數據時,另外一個事務也訪問了該數據,那麼在第一個事務中修改了這個數據後,第二個事務也修改了這個數據。這樣第一個事務內的修改結果就被丟失,因此稱爲丟失修改。 例如:事務1讀取某表中的數據A=20,事務2也讀取A=20,事務1修改A=A-1,事務2也修改A=A-1,最終結果A=19,事務1的修改被丟失。
  • 不可重複讀(Unrepeatableread): 指在一個事務內多次讀同一數據。在這個事務還沒有結束時,另一個事務也訪問該數據。那麼,在第一個事務中的兩次讀數據之間,由於第二個事務的修改導致第一個事務兩次讀取的數據可能不太一樣。這就發生了在一個事務內兩次讀到的數據是不一樣的情況,因此稱爲不可重複讀。
  • 幻讀(Phantom read): 幻讀與不可重複讀類似。它發生在一個事務(T1)讀取了幾行數據,接着另一個併發事務(T2)插入了一些數據時。在隨後的查詢中,第一個事務(T1)就會發現多了一些原本不存在的記錄,就好像發生了幻覺一樣,所以稱爲幻讀。

不可重複讀和幻讀區別:

不可重複讀的重點是修改比如多次讀取一條記錄發現其中某些列的值被修改,幻讀的重點在於新增或者刪除比如多次讀取一條記錄發現記錄增多或減少了。

事務隔離級別有哪些?MySQL的默認隔離級別是?

SQL 標準定義了四個隔離級別:

  • READ-UNCOMMITTED(讀取未提交): 最低的隔離級別,允許讀取尚未提交的數據變更,可能會導致髒讀、幻讀或不可重複讀
  • READ-COMMITTED(讀取已提交): 允許讀取併發事務已經提交的數據,可以阻止髒讀,但是幻讀或不可重複讀仍有可能發生
  • REPEATABLE-READ(可重複讀): 對同一字段的多次讀取結果都是一致的,除非數據是被本身事務自己所修改,可以阻止髒讀和不可重複讀,但幻讀仍有可能發生
  • SERIALIZABLE(可串行化): 最高的隔離級別,完全服從ACID的隔離級別。所有的事務依次逐個執行,這樣事務之間就完全不可能產生干擾,也就是說,該級別可以防止髒讀、不可重複讀以及幻讀

隔離級別 髒讀 不可重複讀 幻影讀
READ-UNCOMMITTED
READ-COMMITTED ×
REPEATABLE-READ × ×
SERIALIZABLE × × ×

MySQL InnoDB 存儲引擎的默認支持的隔離級別是 REPEATABLE-READ(可重讀)。我們可以通過SELECT @@tx_isolation;命令來查看

 

鎖機制與InnoDB鎖算法

MyISAM和InnoDB存儲引擎使用的鎖:

  • MyISAM採用表級鎖(table-level locking)。
  • InnoDB支持行級鎖(row-level locking)和表級鎖,默認爲行級鎖

表級鎖和行級鎖對比:

  • 表級鎖: MySQL中鎖定 粒度最大 的一種鎖,對當前操作的整張表加鎖,實現簡單,資源消耗也比較少,加鎖快,不會出現死鎖。其鎖定粒度最大,觸發鎖衝突的概率最高,併發度最低,MyISAM和 InnoDB引擎都支持表級鎖。
  • 行級鎖: MySQL中鎖定 粒度最小 的一種鎖,只針對當前操作的行進行加鎖。 行級鎖能大大減少數據庫操作的衝突。其加鎖粒度最小,併發度高,但加鎖的開銷也最大,加鎖慢,會出現死鎖。

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章