日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

想进阿里必须啃透的 13 道 MySQL 面试题

發(fā)布時(shí)間:2023/12/29 数据库 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 想进阿里必须啃透的 13 道 MySQL 面试题 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

? 篇幅所限本文只寫了 12 道經(jīng)典 MySQL 面試題,像其他的 Redis,SSM 框架,算法,計(jì)網(wǎng)等技術(shù)棧的面試題后面會(huì)持續(xù)更新,個(gè)人整理的 1000 余道面試八股文會(huì)放在文末給大家白嫖,最近有面試需要刷題的同學(xué)可以直接翻到文末領(lǐng)取。

本文目錄:

1. 能說下 myisam 和 innodb 的區(qū)別嗎?

2. 說下 mysql 的索引有哪些吧,聚簇和非聚簇索引又是什么?

3. 那你知道什么是覆蓋索引和回表嗎?

4. 鎖的類型有哪些呢

5. 你能說下事務(wù)的基本特性和隔離級(jí)別嗎?

6. 那你說說什么是幻讀,什么是 MVCC?

8. 那你知道什么是間隙鎖嗎?

9. 那分表后的 ID 怎么保證唯一性的呢?

10. 你們數(shù)據(jù)量級(jí)多大?分庫分表怎么做的?

11. 分表后非 sharding_key 的查詢?cè)趺刺幚砟?#xff1f;

12. 說說 mysql 主從同步怎么做的吧?

13. 那主從的延遲怎么解決呢?

正文:

1. 能說下 myisam 和 innodb 的區(qū)別嗎?

myisam 引擎是 5.1 版本之前的默認(rèn)引擎,支持全文檢索、壓縮、空間函數(shù)等,但是不支持事務(wù)和行級(jí)鎖,所以一般用于有大量查詢少量插入的場(chǎng)景來使用,而且 myisam 不支持外鍵,并且索引和數(shù)據(jù)是分開存儲(chǔ)的。

innodb 是基于聚簇索引建立的,和 myisam 相反它支持事務(wù)、外鍵,并且通過 MVCC 來支持高并發(fā),索引和數(shù)據(jù)存儲(chǔ)在一起。

2. 說下 mysql 的索引有哪些吧,聚簇和非聚簇索引又是什么?

索引按照數(shù)據(jù)結(jié)構(gòu)來說主要包含 B+樹和 Hash 索引。

假設(shè)我們有張表,結(jié)構(gòu)如下:

create table user( id int(11) not null, age int(11) not null, primary key(id), key(age));

復(fù)制代碼

B+樹是左小右大的順序存儲(chǔ)結(jié)構(gòu),節(jié)點(diǎn)只包含 id 索引列,而葉子節(jié)點(diǎn)包含索引列和數(shù)據(jù),這種數(shù)據(jù)和索引在一起存儲(chǔ)的索引方式叫做聚簇索引,一張表只能有一個(gè)聚簇索引。假設(shè)沒有定義主鍵,InnoDB 會(huì)選擇一個(gè)唯一的非空索引代替,如果沒有的話則會(huì)隱式定義一個(gè)主鍵作為聚簇索引。

這是主鍵聚簇索引存儲(chǔ)的結(jié)構(gòu),那么非聚簇索引的結(jié)構(gòu)是什么樣子呢?非聚簇索引(二級(jí)索引)保存的是主鍵 id 值,這一點(diǎn)和 myisam 保存的是數(shù)據(jù)地址是不同的。

?

最終,我們一張圖看看 InnoDB 和 Myisam 聚簇和非聚簇索引的區(qū)別

?

3. 那你知道什么是覆蓋索引和回表嗎?

覆蓋索引指的是在一次查詢中,如果一個(gè)索引包含或者說覆蓋所有需要查詢的字段的值,我們就稱之為覆蓋索引,而不再需要回表查詢。

而要確定一個(gè)查詢是否是覆蓋索引,我們只需要 explain sql 語句看 Extra 的結(jié)果是否是“Using index”即可。

以上面的 user 表來舉例,我們?cè)僭黾右粋€(gè) name 字段,然后做一些查詢?cè)囋嚒?/p>

explain select * from user where age=1; //查詢的name無法從索引數(shù)據(jù)獲取explain select id,age from user where age=1; //可以直接從索引獲取

復(fù)制代碼

4. 鎖的類型有哪些呢

mysql 鎖分為共享鎖排他鎖,也叫做讀鎖和寫鎖。

讀鎖是共享的,可以通過 lock in share mode 實(shí)現(xiàn),這時(shí)候只能讀不能寫。

寫鎖是排他的,它會(huì)阻塞其他的寫鎖和讀鎖。從顆粒度來區(qū)分,可以分為表鎖行鎖兩種。

表鎖會(huì)鎖定整張表并且阻塞其他用戶對(duì)該表的所有讀寫操作,比如 alter 修改表結(jié)構(gòu)的時(shí)候會(huì)鎖表。

行鎖又可以分為樂觀鎖悲觀鎖,悲觀鎖可以通過 for update 實(shí)現(xiàn),樂觀鎖則通過版本號(hào)實(shí)現(xiàn)。

5. 你能說下事務(wù)的基本特性和隔離級(jí)別嗎?

事務(wù)基本特性 ACID 分別是:

原子性指的是一個(gè)事務(wù)中的操作要么全部成功,要么全部失敗。

一致性指的是數(shù)據(jù)庫總是從一個(gè)一致性的狀態(tài)轉(zhuǎn)換到另外一個(gè)一致性的狀態(tài)。比如 A 轉(zhuǎn)賬給 B100 塊錢,假設(shè)中間 sql 執(zhí)行過程中系統(tǒng)崩潰 A 也不會(huì)損失 100 塊,因?yàn)槭聞?wù)沒有提交,修改也就不會(huì)保存到數(shù)據(jù)庫。

隔離性指的是一個(gè)事務(wù)的修改在最終提交前,對(duì)其他事務(wù)是不可見的。

持久性指的是一旦事務(wù)提交,所做的修改就會(huì)永久保存到數(shù)據(jù)庫中。

而隔離性有 4 個(gè)隔離級(jí)別,分別是:

read uncommit 讀未提交,可能會(huì)讀到其他事務(wù)未提交的數(shù)據(jù),也叫做臟讀。

用戶本來應(yīng)該讀取到 id=1 的用戶 age 應(yīng)該是 10,結(jié)果讀取到了其他事務(wù)還沒有提交的事務(wù),結(jié)果讀取結(jié)果 age=20,這就是臟讀。

read commit 讀已提交,兩次讀取結(jié)果不一致,叫做不可重復(fù)讀。

不可重復(fù)讀解決了臟讀的問題,他只會(huì)讀取已經(jīng)提交的事務(wù)。

用戶開啟事務(wù)讀取 id=1 用戶,查詢到 age=10,再次讀取發(fā)現(xiàn)結(jié)果=20,在同一個(gè)事務(wù)里同一個(gè)查詢讀取到不同的結(jié)果叫做不可重復(fù)讀。

repeatable read 可重復(fù)復(fù)讀,這是 mysql 的默認(rèn)級(jí)別,就是每次讀取結(jié)果都一樣,但是有可能產(chǎn)生幻讀。

serializable 串行,一般是不會(huì)使用的,他會(huì)給每一行讀取的數(shù)據(jù)加鎖,會(huì)導(dǎo)致大量超時(shí)和鎖競(jìng)爭(zhēng)的問題。

6. 那你說說什么是幻讀,什么是 MVCC?

要說幻讀,首先要了解 MVCC,MVCC 叫做多版本并發(fā)控制,實(shí)際上就是保存了數(shù)據(jù)在某個(gè)時(shí)間節(jié)點(diǎn)的快照。

我們每行數(shù)據(jù)實(shí)際上隱藏了兩列,創(chuàng)建時(shí)間版本號(hào),過期(刪除)時(shí)間版本號(hào),每開始一個(gè)新的事務(wù),版本號(hào)都會(huì)自動(dòng)遞增。

還是拿上面的 user 表舉例子,假設(shè)我們插入兩條數(shù)據(jù),他們實(shí)際上應(yīng)該長(zhǎng)這樣。

?

這時(shí)候假設(shè)小明去執(zhí)行查詢,此時(shí) current_version=3

select * from user where id<=3;

復(fù)制代碼

同時(shí),小紅在這時(shí)候開啟事務(wù)去修改 id=1 的記錄,current_version=4

update user set name='張三三' where id=1;

復(fù)制代碼

執(zhí)行成功后的結(jié)果是這樣的

如果這時(shí)候還有小黑在刪除 id=2 的數(shù)據(jù),current_version=5,執(zhí)行后結(jié)果是這樣的。

由于 MVCC 的原理是查找創(chuàng)建版本小于或等于當(dāng)前事務(wù)版本,刪除版本為空或者大于當(dāng)前事務(wù)版本,小明的真實(shí)的查詢應(yīng)該是這樣

select * from user where id<=3 and create_version<=3 and (delete_version>3 or delete_version is null);

復(fù)制代碼

所以小明最后查詢到的 id=1 的名字還是'張三',并且 id=2 的記錄也能查詢到。這樣做是為了保證事務(wù)讀取的數(shù)據(jù)是在事務(wù)開始前就已經(jīng)存在的,要么是事務(wù)自己插入或者修改的

明白 MVCC 原理,我們來說什么是幻讀就簡(jiǎn)單多了。舉一個(gè)常見的場(chǎng)景,用戶注冊(cè)時(shí),我們先查詢用戶名是否存在,不存在就插入,假定用戶名是唯一索引。

  • 小明開啟事務(wù) current_version=6 查詢名字為'王五'的記錄,發(fā)現(xiàn)不存在。

  • 小紅開啟事務(wù) current_version=7 插入一條數(shù)據(jù),結(jié)果是這樣:

  • 小明執(zhí)行插入名字'王五'的記錄,發(fā)現(xiàn)唯一索引沖突,無法插入,這就是幻讀。

  • 7. 那 ACID 靠什么保證的呢?

    A 原子性由 undo log 日志保證,它記錄了需要回滾的日志信息,事務(wù)回滾時(shí)撤銷已經(jīng)執(zhí)行成功的 sql

    C 一致性一般由代碼層面來保證

    I 隔離性由 MVCC 來保證

    D 持久性由內(nèi)存+redo log 來保證,mysql 修改數(shù)據(jù)同時(shí)在內(nèi)存和 redo log 記錄這次操作,事務(wù)提交的時(shí)候通過 redo log 刷盤,宕機(jī)的時(shí)候可以從 redo log 恢復(fù)

    8. 那你知道什么是間隙鎖嗎?



    ....博主太懶了字?jǐn)?shù)太多了,不想寫了....文章已經(jīng)做成PDF,有需要的朋友可以私信我免費(fèi)獲取!
    ?

    ?

    總結(jié)

    以上是生活随笔為你收集整理的想进阿里必须啃透的 13 道 MySQL 面试题的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。