1. 前言
在校招或者社招面試中,無論你是 Java 后端、Cpp 后端、Python 后端,面試官都會詳細地考察各種語法細節、框架知識,但是大多數候選人入職之后,都會體會到 "面試造火箭,上班擰螺絲"。面試時我們熟悉各種知識細節,入職后卻發現大部分工作都是重復的 CRUD(Create - 增加,Retrieve - 查詢,Update - 更新,Delete - 刪除),這種現象其實很正常。后端開發的核心職責就是倒騰數據,面臨的基礎問題例如如何設計數據的存儲結構并且選擇合適的數據庫進行存儲,如何在各種限制條件下查詢數據。當我們負責的系統非常龐大之后,還會面臨如何解決分布式系統的數據一致性這類更復雜的問題。
總結來說,操作數據庫是后端程序員的必備技能。數據庫按照存儲數據結構的方式,可以分為關系型數據庫以及非關系型數據庫。關系型數據庫中數據都是以二維表的形式存儲,最常用的數據庫有 Oracle、MySQL,非關系型數據庫中數據都是以結構化的形式存儲,最常用的數據庫有 Redis、MongoDB、Hbase 等。目前互聯網一二線大廠的校招要求,MySQL 基本是必備技能,非關系性數據庫例如 Redis 這類不是必考內容,當然掌握了會是錦上添花。
本小節中會介紹關于 MySQL 常見高頻面試題,以及核心回答思路解析。
2. MyISAM 和 InnoDB
面試官提問: 介紹下 InnoDB 和 MyISAM 存儲引擎的區別,以及具體的應用場景?
題目解析:
首先要明確存儲引擎的定義:MySQL 提供不同的技術存儲數據,這些技術使用不同的數據存儲機制、索引建立方式、鎖方式來完成數據的構建,這些技術統稱為存儲引擎。
MySQL Client 終端輸入 show engines
可查看支持的存儲引擎類型。
如圖可見 MySQL 至少支持 9 種存儲引擎,而面試中最受關注的是 InnoDB 和 MyISAM 存儲引擎,一般的面試場景是這樣的:
在上圖的實驗結果中,我們會發現在 MySQL 的所有存儲引擎中,只有 InnoDB 支持 Transaction(事務)、XA(分布式事務),其他引擎均不支持,關于事務的支持能力是需要強調的點。關于兩種引擎之間的區別,可以按下表進行分點闡述。
InnoDB | MyISAM | |
---|---|---|
事務 | 支持,強調的是保持數據一致性的高級功能 | 不支持,強調的是性能,查詢速度比 InnoDB 快 |
外鍵 | 支持 | 不支持 |
索引 | 使用聚集索引,索引文件和數據文件綁定 | 使用非聚集索引,索引文件和數據文件分開存儲,索引中保存的是數據文件的指針 |
鎖 | 支持表級鎖、行級鎖; 行級鎖粒度小,處理并發的能力更強 |
支持表級鎖,用戶在執行 insert、update、select、delete 時都會給表自動加鎖,效率低 |
主鍵 | 表必須有唯一索引(例如用戶規定 id 作為主鍵),沒有的話會用默認隱藏列 row_id 作為唯一索引 | 沒有要求 |
存儲文件 | 在操作系統中的存儲文件: .frm:表定義文件 .ibd:數據文件 |
在操作系統中的存儲文件: .frm:表定義文件 .myd:數據文件 .myi:索引文件 |
在闡述完兩種存儲引擎的區別之后,再根據兩者的特點,枚舉一些使用場景:
-
MyISAM 對于不支持事務并且存在大量 SELECT 的讀場景比較合適;
-
如果業務代碼中要支持事務,必須選擇 InnoDB 存儲引擎;
-
如果業務代碼中要支持外鍵,必須選擇 InnoDB 存儲引擎;
-
例如對電商公司來說,大部分的業務情況是要支持事務回滾的,例如下單流程失敗之后要回滾已有的 Insert 語句,并且數據并發量高,這種場景肯定都是選擇 InnoDB,筆者在生產環境中從未看到使用 MyISAM 存儲引擎,兩者對比更側重考察候選人的理論知識。
3. 小結
本章節介紹了 MySQL 中兩種不同的數據存儲引擎,面試官針對回答可能會涉及到一些擴展性的問題,例如當談到 InooDB 對事務的支持時,面試官很可能轉為考察候選人對事務的理解程度。上述提到了聚集索引和非聚集索引,面試官可能會特意考察這兩種索引的實現區別。MySQL 的外鍵定義,枚舉使用場景和案例。這些問題也是候選人需要掌握的知識點。