資料庫八股文自述

2021-10-19 16:40:40 字數 3471 閱讀 5662

1.mysql索引有哪些資料結構?

答:b+tree,以及hash。hash索引比較適合單值的查詢,但不適合範圍查詢,hash索引的單值查詢時間複雜度為o(1).b+tree查詢的時間複雜度為o(logn),但是b+適合範圍查詢以及掃表。innodb和myisam是不支援hash索引的。

2.mysql索引結構為什麼不用b,而用b+?

答:b樹是每個節點都會存放資料,而b+的資料只會存放在葉子節點的鍊錶上,且該鍊錶是個雙向鍊錶,因此b+相對於b來說,最大的優勢就是適合掃表。具體原因為,因為b每個節點都存放資料,因此當範圍查詢的時候由於每個節點都可能存在符合我們要求的資料,所以需要從根節點向下遍歷子樹,這樣會帶來大量隨機的io,這也是b最大的問題,而b+則可以通過雙向鍊錶,只會產生固定的io。且鍊錶的遍歷本來就是樹簡單的嘛。

3.mysql為什麼不用二叉樹(紅黑)呢?為啥不用跳表?為啥不用鍊錶?

答:mysql不用二叉樹的原因是,根據計算機著名的區域性性原理,當乙個資料被用到時,其周圍的資料很大概率會被馬上用到,所以就有磁碟的預讀,但是二叉樹不能利用預讀,因為樹在磁碟中是以堆的形式存在,所以在二叉樹中,看似是父子節點,但是實際儲存位置可能會隔著非常遠,因此會造成大量的io,io是非常耗時的,所以mysql不用二叉樹作為索引。

4.b+每個節點的大小為多少?

答:一般乙個節點設定為磁碟乙個頁的大小,可以充分利用磁碟預讀原理,不浪費

5.回表

答:談到回表,首先要談一下非主鍵索引,非主鍵索引的b+樹的葉子節點中不止存著索引的值,也存著索引值對應的主鍵,這也是不建議主鍵設定太長的原因,然後會通過主鍵回到主鍵索引樹中查詢,這就是回表。

6.覆蓋索引

答:為了避免回表,我們可以建立覆蓋索引。覆蓋索引就是比如我們要通過非主鍵索引查詢主鍵時,當找到對應的索引時不用回表在查詢主鍵,因為此時非主鍵索引樹中也存放著主鍵的值,可以直接獲取。一次類推,當我們需要通過某個值查詢另乙個值得時候,我們可以將這兩個值的列建乙個聯合索引,可以直接通過乙個找到另乙個而不用回表。

7.最左匹配原則

答:就是當我們建立聯合索引(a,b,c,d)時,最左匹配原則要求時當我們匹配到a時,才能繼續匹配b,就是先命中索引a,才能繼續命中後續(注意:where a=1 and b=2和where b=1 and a=1都可以命中,優化器會幫我們調整a,b的順序與索引一致),且會被範圍查詢中斷,如where a=1 and b=1 and c<1 and d=1,此時索引在命中c之後不會繼續往後匹配。這個原因就是聯合索引的樹中,只有第乙個元素是全域性有序的,而其餘都是區域性有序,所謂的區域性有序就是當確定a之後,對應的b是有序的,確定b之後對應的c是有序的,而當c是範圍的時候,d就無法確定順序,故無法繼續匹配。

8.mysql的基本架構

答:mysql的基本架構由聯結器、查詢快取器(mysql8.0版本後移除了這個功能)、分析器、優化器、執行器、以及儲存引擎。可以這樣分聯結器,快取,分析器,優化器,執行器屬於server層,還有儲存引擎。其中聯結器負責連線客戶端,分析器進行語法分析,優化器進行sql「優化」,執行器呼叫引擎介面,儲存引擎負責資料儲存與讀取。

9.雜談待總結

答:我認為mysql最重要的就是它的儲存引擎架構,這種架構設計將資料的查詢處理、系統其他任務、資料的儲存相分離。這種儲存和處理相分離的設計可以讓程式設計師根據不同的業務場景進行不同的選擇,如我們可以選擇不同的儲存引擎。

10,acid

答:原子性,一致性,隔離性,永續性

11.併發的事務帶來的問題

答:髒讀,丟失修改,不可重複讀,幻讀

12.事務的隔離級別

答:讀未提交,讀已提交,可重複讀,序列化。讀未提交無法解決髒讀問題,讀已提交可以解決髒讀問題,可重複讀可以解決不可重複讀問題,但是無法解決幻讀,序列化可以解決幻讀問題,因為序列化會對所有讀取的行加鎖。但是innode的可重複讀級別使用的是next-key lock,可以解決幻讀問題。

13.innodb與myisam的區別

答:myisam是表鎖,innodb支援行鎖,innode支援事務且支援崩潰後的安全恢復,innode支援mvcc(mvcc只工作在讀已提交和可重複讀兩個級別)

14.mvcc

答:mvcc又叫多版本併發控制,mvcc只工作在讀已提交和可重複讀兩個隔離級別。mvcc的實現可以使得資料庫的大部分操作不用加鎖。mvcc的實現機理是在每行後面加兩個標誌。分別代表著建立版本號以及過期版本號。就拿可重複讀級別下mvcc舉例。select操作只會查詢早於當前事務版本號的行,或過期版本號大於當前版本號的行。insert操作會向該行賦值當前版本號。delete操作會向改行的過期賦值當前版本號。update操作則會插入一條新的行,並賦值當前版本號,並向舊的行賦值過期版本號。且mvcc分為快照讀和當前讀,快照讀就是普通的讀,不加鎖;當前讀就讀的最新的資料,select * from where lock in share mode;(共享鎖) select * from where for update;(排他鎖);其餘update,instert,delete都預設加鎖,且加的是排他鎖。共享鎖更新的時候會產生死鎖,只有乙個共享鎖的事務提交以後另乙個才可以。讀不加鎖,讀寫不衝突。spring 關閉資料庫中自動提交:在方法執行前關閉自動提交,方法執行完畢後再開啟自動提交

12.儲存高效能

答:無論我們的資料庫,我們的表設計的多麼優秀,總是會存在乙個繞不開的問題,就是單台資料庫是有瓶頸的,如一般的資料庫只能達到三千左右的qps,且當一張表數量過於龐大的時候,儘管有索引,效能還是會下降,且資料庫備份恢復會耗費大量時間,且資料丟失風險很高。一般實現儲存高效能的方式有兩種,分別為讀寫分離以及分庫分表。讀寫分離採用了主從集群,一台主機多台從機,從機定時向主機同步資料。主機可以讀寫,從機只用來讀。由於資料同步有一定延遲,所以會導致一些問題。如乙個使用者剛剛註冊就立刻登入,此刻使用者的資料還未同步到從機,因此會返回該使用者未註冊的異常。解決方法就是關鍵業務都在主機操作(如註冊登入),非關鍵業務在從機讀(使用者的自我介紹啊,簽名啊等等)。讀寫分離緩解了資料庫讀的壓力,但是沒有緩解寫的壓力。還有一種方法就是分庫分表。既可以緩解讀的壓力,也可以緩解儲存的壓力。分庫一般按照業務分。分庫也會造成一些問題比如我們有些簡單的連表操作就會變得複雜,還有就是事務問題,還需要我們程式介入實現多個庫之間事務性。分表,則是分為水平拆分一垂直拆分。垂直拆分則是將將一些不經常用的且比較大的(比如描述)欄位分出去,待需要時候在讀,水平拆分則是將一張表分為多張表,一般一張表的資料達到五千萬左右就需要水平分表了,但是不一定,這個要按表的複雜程度,有些複雜的表達到一千萬就需要分表了,有些簡單的表達到一億也不需要分表。水平分表需要查詢路由,可以按照id來分,如1-999999分發到表1,100000-99999分發到表2,但是該方法有個缺點就是分布不均勻,有些表是滿的,有些表則是只有幾行,還有hash法,就是將一列或幾列的值進行hash然後分配,該問題就是表的初始數量不好確定,其次當擴充表的時候,都需要重新計算分配,還有乙個配置路由法,就是採用一張表記錄路由資訊,但是這個也存在問題,就會導致路由表很大。

面試八股文之TCP的三次握手

三次握手的主要目的是確認自己和對方的傳送和接收都是正常的,從而保證了雙方能夠進行可靠通訊。若採用兩次握手,當第二次握手後就建立連線的話,此時客戶端知道伺服器能夠正常接收到自己傳送的資料,而伺服器並不知道客戶端是否能夠收到自己傳送的資料。我們知道網路往往是非理想狀態的 存在丟包和延遲 當客戶端發起建立...

資料庫學習筆記八 資料庫索引

一 索引 索引 index 是幫助 mysql 高效獲取資料的資料結構。常見的查詢演算法,順序查詢,二分查詢,二 叉排序樹查詢,雜湊雜湊法,分塊查詢,平衡多路搜尋樹 b 樹 b tree 二 選擇唯一性索引 1 唯一性索引的值是唯一的,可以更快速的通過該索引來確定某條記錄。2 為經常需要排序 分組和...

Oracle資料庫 八 游標

游標 資料的快取區 什麼是游標 游標的使用可以讓使用者想運算元組一樣操作查詢出來的資料集,實際上,它提供了一種從集合性質的結果中提取單挑記錄的手段。游標 cursor 形象地看出乙個變動的游標。它實際上是乙個指標,它在一段oracle存放資料查詢結果集的記憶體中,它可以指向結果集中的任意記錄,初始是...