MySQL面試
事務
邏輯上的一組操作,要么全部執行,要么都不執行。
事務的4大特性(ACID):
- A:atomic原子性
事務是最小的執行單位,不允許分割,要么全部成功,要么全部失敗
- C:consistency一致性
執行事務前后,數據保持一致,多個事務對統一數據的讀取應該是相同的
- I:Isolation獨立性
並發訪問數據庫時,多個事務之間應該是獨立的
- D:determined持久性
事務提交后造成的數據影響是永久的
並發事務帶來的問題:
- 臟讀:dirty read
一個事務修改來了數據未提交,另一個數據讀取了未提交的數據。
- 丟失修改:lost to modify
兩個事務都修改了數據之后,第一個數據修改就會丟失。如數據A=10,事務1:A=A-1;
事務2:A=A-1,最后結果發現為19;
- 不可重復讀:Unrepeatable Read
A事務在多次修改數據之間,B事務讀取了數據,但是B在A事務執行之間讀取的時候,可能會發現讀取同一個數據的時候兩次讀到的不一樣;
- 幻讀:Phantom Read
幻讀與不可重復讀相同,但是是一個事務多次插入或者刪除數據,另一個事務讀取的時候會發現多了或者少了數據。
事務的隔離級別
- Read-Uncommitted(讀未提交)
最低的隔離級別,允許讀取尚未提交的事務,會導致臟讀、幻讀、不可重復讀。
- Read-Committed(讀已提交)
允許並發事務讀取已經提交的數據,可以防止臟讀,單有可能幻讀、不可重復讀。
- Repeatable-Read(可重復讀)
mysql的默認隔離級別,對同一字段的多次讀取都是相同的,除非數據是被本身事務修改。可以防止臟讀與不可重復讀,但有可能會有幻讀。
- Serializable(可串行化)
最高的隔離級別,完全按照ACID,所有事務依次執行。
隔離級別 | 臟讀 | 不可重復讀 | 幻讀 |
---|---|---|---|
Read-Uncommitted(讀未提交) | √ | √ | √ |
Read-Committed(讀已提交) | × | √ | √ |
Repeatable-Read(可重復讀) | × | × | √ |
Serializable(可串行化) | × | × | × |
需要注意:InnoDB引擎在Repeatable-Read級別下使用的Next-Key Lock,所以可以在這個級別下防止幻讀,起到了Serializable的效果。
InnoDB在分布式事務的情況下采用的是Serializable隔離級別。
數據庫的索引
索引做了什么:將無需的數據變成相對的有序的數據。
最左前綴匹配原則
MySQL中的索引可以以一定順序引用多列,這種索引叫作聯合索引。如User表的name和city加聯合索引就是(name,city),而最左前綴原則指的是,如果查詢的時候查詢條件精確匹配索引的左邊連續一列或幾列,則此列就可以被用到。如下:
select * from user where name=xx and city=xx ; //可以命中索引
select * from user where name=xx ; // 可以命中索引
select * from user where city=xx ; // 無法命中索引
如何添加索引
- PRIMARY KEY(主鍵索引)
主鍵是索引的一種,是唯一索引的特殊類型。創建主鍵的時候,數據庫默認會為主鍵創建一個唯一索引。
ALTER TABLE `table_name` ADD PRIMARY KEY ( `column` )
- UNIQUE(唯一索引)
ALTER TABLE `table_name` ADD UNIQUE ( `column` )
- INDEX(普通索引)
ALTER TABLE `table_name` ADD INDEX index_name ( `column` )
- FULLTEXT(全文索引)
ALTER TABLE `table_name` ADD FULLTEXT ( `column`)
- 多列索引
ALTER TABLE `table_name` ADD INDEX index_name ( `column1`, `column2`, `column3` )
數據庫引擎
MyISAM和InnoDB區別
MyISAM是MySQL的默認數據庫引擎(5.5版之前)。雖然性能極佳,而且提供了大量的特性,包括全文索引、壓縮、空間函數等,但MyISAM不支持事務和行級鎖,而且最大的缺陷就是崩潰后無法安全恢復。不過,5.5版本之后,MySQL引入了InnoDB(事務性數據庫引擎),MySQL 5.5版本后默認的存儲引擎為InnoDB。
兩者的對比:
- 是否支持行級鎖 : MyISAM 只有表級鎖(table-level locking),而InnoDB 支持行級鎖(row-level locking)和表級鎖,默認為行級鎖。
- 是否支持事務和崩潰后的安全恢復: MyISAM 強調的是性能,每次查詢具有原子性,其執行數度比InnoDB類型更快,但是不提供事務支持。但是InnoDB 提供事務支持事務,外部鍵等高級數據庫功能。 具有事務(commit)、回滾(rollback)和崩潰修復能力(crash recovery capabilities)的事務安全(transaction-safe (ACID compliant))型表。
- 是否支持外鍵: MyISAM不支持,而InnoDB支持。
- 是否支持MVCC :僅 InnoDB 支持。應對高並發事務, MVCC比單純的加鎖更高效;MVCC只在
READ COMMITTED
和REPEATABLE READ
兩個隔離級別下工作;MVCC可以使用 樂觀(optimistic)鎖 和 悲觀(pessimistic)鎖來實現;各數據庫中MVCC實現並不統一。
表級鎖和行級鎖對比:
- 表級鎖: Mysql中鎖定 粒度最大 的一種鎖,對當前操作的整張表加鎖,實現簡單,資源消耗也比較少,加鎖快,不會出現死鎖。其鎖定粒度最大,觸發鎖沖突的概率最高,並發度最低,MyISAM和 InnoDB引擎都支持表級鎖。
- 行級鎖: Mysql中鎖定 粒度最小 的一種鎖,只針對當前操作的行進行加鎖。 行級鎖能大大減少數據庫操作的沖突。其加鎖粒度最小,並發度高,但加鎖的開銷也最大,加鎖慢,會出現死鎖。
InnoDB存儲引擎的鎖的算法有三種:
- Record lock:單個行記錄上的鎖
- Gap lock:間隙鎖,鎖定一個范圍,不包括記錄本身
- Next-key lock:record+gap 鎖定一個范圍,包含記錄本身