7 個 yyds 的高頻 MySQL 面試題
MySQL 索引使用什么數(shù)據(jù)結(jié)構(gòu)?為什么用 B+做索引?
使用B+樹。

如果是用AVL平衡二叉樹,樹高度太高,索引查詢需要訪問磁盤,每次訪問以節(jié)點為單位進(jìn)行磁盤I/O ,需要盡量減少數(shù)據(jù)讀取的I/O操作,所以樹高度一定不能太高,存儲千萬級別的數(shù)據(jù),實踐中 B+ 樹的高度也就 4或者5。
B+樹經(jīng)常用來比較的是B樹,B+樹相比B樹有個很大的特點是B+樹所有關(guān)鍵字都出現(xiàn)在葉子結(jié)點的鏈表中(稠密索引),且鏈表中的關(guān)鍵字恰好是有序的,對于范圍查找,比如15~50,B樹需要中序遍歷二叉樹,但是B+樹直接在葉子節(jié)點順序訪問就可以了。
什么是最左匹配原則?

我們查詢的where 條件如果只傳入了班級,是走不到聯(lián)合索引的,但是如果只傳了學(xué)院編號,是可能會走到聯(lián)合索引的。(為什么說可能,MYSQL的執(zhí)行計劃和查詢的實際執(zhí)行過程并不完全吻合,比如你數(shù)據(jù)庫數(shù)據(jù)量很少,可能直接全量遍歷速度更快,就不走索引了)
在建表的時候如何設(shè)計索引的?有沒有做過索引優(yōu)化 ?
如果我們select 獲取的字段是學(xué)號,直接在手機(jī)號的索引表就能獲取到數(shù)據(jù),不需要回表;
如果我們select 的時候還有其他字段,我們查詢的時候流程是這樣的,先根據(jù)手機(jī)號查到學(xué)號,再根據(jù)學(xué)號去主鍵索引表查詢數(shù)據(jù),這個過程叫回表。
2、業(yè)務(wù)上具有唯一特性的字段,即使是組合字段,也建議建成唯一索引。說明:不要以為唯一索引影響了insert速度,這個速度損耗可以忽略,但提高查找速度是明顯的;另外,即使在應(yīng)用層做了非常完善的校驗和控制,只要沒有唯一索引,根據(jù)墨菲定律,必然有臟數(shù)據(jù)產(chǎn)生。
1)const 單表中最多只有一個匹配行(主鍵或者唯一索引),在優(yōu)化階段即可讀取到數(shù)據(jù)。
2)ref 指的是使用普通的索引。(normal index)
3)range 對索引進(jìn)行范圍檢索。反例:explain表的結(jié)果,type=index,索引物理文件全掃描,速度非常慢,這個index級別比較range還低,與全表掃描是小巫見大巫。
8、防止因字段類型不同造成的隱式轉(zhuǎn)換,導(dǎo)致索引失效。
MyBatis用過嗎? 一二級緩存清楚嗎?
一級緩存 Mybatis的一級緩存是指SQLSession,一級緩存的作用域是SQlSession, Mabits默認(rèn)開啟一級緩存。在同一個SqlSession中,執(zhí)行相同的SQL查詢時;第一次會去查詢數(shù)據(jù)庫,并寫在緩存中,第二次會直接從緩存中取。當(dāng)執(zhí)行SQL時候兩次查詢中間發(fā)生了增刪改的操作,則SQLSession的緩存會被清空。每次查詢會先去緩存中找,如果找不到,再去數(shù)據(jù)庫查詢,然后把結(jié)果寫到緩存中。Mybatis的內(nèi)部緩存使用一個HashMap,key為hashcode+statementId+sql語句。Value為查詢出來的結(jié)果集映射成的java對象。SqlSession執(zhí)行insert、update、delete等操作commit后會清空該SQLSession緩存。 二級緩存 二級緩存是 mapper級別的,Mybatis默認(rèn)是沒有開啟二級緩存的。第一次調(diào)用mapper下的SQL去查詢用戶的信息,查詢到的信息會存放在該mapper對應(yīng)的二級緩存區(qū)域。第二次調(diào)用namespace下的mapper映射文件中,相同的sql去查詢用戶信息,會去對應(yīng)的二級緩存內(nèi)取結(jié)果。

MySQL 主從同步怎么做的?binlog清楚嗎?
Master 數(shù)據(jù)庫只要發(fā)生變化,立馬記錄到Binary log 日志文件中
Slave數(shù)據(jù)庫啟動一個I/O thread連接Master數(shù)據(jù)庫,請求Master變化的二進(jìn)制日志
Slave I/O獲取到的二進(jìn)制日志,保存到自己的Relay log 日志文件中。
Slave 有一個 SQL thread定時檢查Realy log是否變化,變化那么就更新數(shù)據(jù)

MySQL 有沒有做分庫分表?怎么設(shè)計的?
拆分中間件,詳細(xì)可以參考:
Sharding-sphere,前身是sharding-jdbc;當(dāng)當(dāng)?shù)姆謳旆直碇虚g件
TDDL:jar,Taobao Distribute Data Layer;
Mycat:中間件。
注:工具的利弊,請自行調(diào)研,官網(wǎng)和社區(qū)優(yōu)先。
按照userId緯度拆分,安琪拉見過的常見的有,根據(jù) userId % 64 取模拆0~63編號的64張表,
固定位拆,取userId 指定二位,例如倒數(shù)2,3位組成00~99 一共100張表的,百庫表表。
hash: userId hash一下,然后 % 表數(shù);
Range: 另外還有按照userId 指定范圍拆的,0-1千萬一張表,這種用的比較少,容易產(chǎn)生熱點。
把不同業(yè)務(wù)域的表拆成不同庫,例如訂單相關(guān)表、用戶信息相關(guān)表、營銷相關(guān)表分開在不同庫;
把大字段獨立存儲到一張表中
把不常用的字段單獨拿出來存儲到一張表
用userId做的分庫分表,現(xiàn)在需要用電話號碼查詢怎么辦?
和回表邏輯一樣,單獨建一個電話號碼索引表,存放電話號碼和userId,查詢時先根據(jù)電話號碼查詢userId,然后再根據(jù)userId查詢數(shù)據(jù)。
最近面試BAT,整理一份面試資料《Java面試BATJ通關(guān)手冊》,覆蓋了Java核心技術(shù)、JVM、Java并發(fā)、SSM、微服務(wù)、數(shù)據(jù)庫、數(shù)據(jù)結(jié)構(gòu)等等。
獲取方式:點“在看”,關(guān)注公眾號并回復(fù) Java 領(lǐng)取,更多內(nèi)容陸續(xù)奉上。
文章有幫助的話,在看,轉(zhuǎn)發(fā)吧。
謝謝支持喲 (*^__^*)

