'史上最全面的數據庫常見筆試面試題(附含答案)中'

"

本文是銜接上文的,內容較多,建議收藏閱讀。

二、索引

1.什麼是索引?

何為索引:

數據庫索引,是數據庫管理系統中一個排序的數據結構,索引的實現通常使用B樹及其變種B+樹。

在數據之外,數據庫系統還維護著滿足特定查找算法的數據結構,這些數據結構以某種方式引用(指向)數據,這樣就可以在這些數據結構上實現高級查找算法。這種數據結構,就是索引。

"

本文是銜接上文的,內容較多,建議收藏閱讀。

二、索引

1.什麼是索引?

何為索引:

數據庫索引,是數據庫管理系統中一個排序的數據結構,索引的實現通常使用B樹及其變種B+樹。

在數據之外,數據庫系統還維護著滿足特定查找算法的數據結構,這些數據結構以某種方式引用(指向)數據,這樣就可以在這些數據結構上實現高級查找算法。這種數據結構,就是索引。

史上最全面的數據庫常見筆試面試題(附含答案)中

2.索引的作用?它的優點缺點是什麼?

索引作用:

協助快速查詢、更新數據庫表中數據。

為表設置索引要付出代價的:

一是增加了數據庫的存儲空間

二是在插入和修改數據時要花費較多的時間(因為索引也要隨之變動)。

3.索引的優缺點?

創建索引可以大大提高系統的性能( 優點 ):

1.通過創建唯一性索引,可以保證數據庫表中每一行數據的唯一性。

2.可以大大加快數據的檢索速度,這也是創建索引的最主要的原因。

3.可以加速表和表之間的連接,特別是在實現數據的參考完整性方面特別有意義。

4.在使用分組和排序子句進行數據檢索時,同樣可以顯著減少查詢中分組和排序的時間。

5.通過使用索引,可以在查詢的過程中,使用優化隱藏器,提高系統的性能。

增加索引也有許多不利的方面( 缺點 ):

1.創建索引和維護索引要耗費時間,這種時間隨著數據量的增加而增加。

2.索引需要佔物理空間,除了數據表佔數據空間之外,每一個索引還要佔一定的物理空間,如果要建立聚簇索引,那麼需要的空間就會更大。

3.當對錶中的數據進行增加、刪除和修改的時候,索引也要動態的維護,這樣就降低了數據的維護速度。

4.哪些列適合建立索引、哪些不適合建索引?

索引是建立在數據庫表中的某些列的上面。在創建索引的時候,應該考慮在哪些列上可以創建索引,在哪些列上不能創建索引。

一般來說,應該在這些列上創建索引:

(1)在經常需要搜索的列上,可以加快搜索的速度;

(2)在作為主鍵的列上,強制該列的唯一性和組織表中數據的排列結構;

(3)在經常用在連接的列上,這些列主要是一些外鍵,可以加快連接的速度;

(4)在經常需要根據範圍進行搜索的列上創建索引,因為索引已經排序,其指定的範圍是連續的;

(5)在經常需要排序的列上創建索引,因為索引已經排序,這樣查詢可以利用索引的排序,加快排序查詢時間;

(6)在經常使用在WHERE子句中的列上面創建索引,加快條件的判斷速度。

對於有些列不應該創建索引:

(1)對於那些在查詢中很少使用或者參考的列不應該創建索引。

這是因為,既然這些列很少使用到,因此有索引或者無索引,並不能提高查詢速度。相反,由於增加了索引,反而降低了系統的維護速度和增大了空間需求。

(2)對於那些只有很少數據值的列也不應該增加索引。

這是因為,由於這些列的取值很少,例如人事表的性別列,在查詢的結果中,結果集的數據行佔了表中數據行的很大比例,即需要在表中搜索的數據行的比例很大。增加索引,並不能明顯加快檢索速度。

(3)對於那些定義為text, image和bit數據類型的列不應該增加索引。

這是因為,這些列的數據量要麼相當大,要麼取值很少。

(4)當修改性能遠遠大於檢索性能時,不應該創建索引。

這是因為,修改性能和檢索性能是互相矛盾的。當增加索引時,會提高檢索性能,但是會降低修改性能。當減少索引時,會提高修改性能,降低檢索性能。因此,當修改性能遠遠大於檢索性能時,不應該創建索引。

"

本文是銜接上文的,內容較多,建議收藏閱讀。

二、索引

1.什麼是索引?

何為索引:

數據庫索引,是數據庫管理系統中一個排序的數據結構,索引的實現通常使用B樹及其變種B+樹。

在數據之外,數據庫系統還維護著滿足特定查找算法的數據結構,這些數據結構以某種方式引用(指向)數據,這樣就可以在這些數據結構上實現高級查找算法。這種數據結構,就是索引。

史上最全面的數據庫常見筆試面試題(附含答案)中

2.索引的作用?它的優點缺點是什麼?

索引作用:

協助快速查詢、更新數據庫表中數據。

為表設置索引要付出代價的:

一是增加了數據庫的存儲空間

二是在插入和修改數據時要花費較多的時間(因為索引也要隨之變動)。

3.索引的優缺點?

創建索引可以大大提高系統的性能( 優點 ):

1.通過創建唯一性索引,可以保證數據庫表中每一行數據的唯一性。

2.可以大大加快數據的檢索速度,這也是創建索引的最主要的原因。

3.可以加速表和表之間的連接,特別是在實現數據的參考完整性方面特別有意義。

4.在使用分組和排序子句進行數據檢索時,同樣可以顯著減少查詢中分組和排序的時間。

5.通過使用索引,可以在查詢的過程中,使用優化隱藏器,提高系統的性能。

增加索引也有許多不利的方面( 缺點 ):

1.創建索引和維護索引要耗費時間,這種時間隨著數據量的增加而增加。

2.索引需要佔物理空間,除了數據表佔數據空間之外,每一個索引還要佔一定的物理空間,如果要建立聚簇索引,那麼需要的空間就會更大。

3.當對錶中的數據進行增加、刪除和修改的時候,索引也要動態的維護,這樣就降低了數據的維護速度。

4.哪些列適合建立索引、哪些不適合建索引?

索引是建立在數據庫表中的某些列的上面。在創建索引的時候,應該考慮在哪些列上可以創建索引,在哪些列上不能創建索引。

一般來說,應該在這些列上創建索引:

(1)在經常需要搜索的列上,可以加快搜索的速度;

(2)在作為主鍵的列上,強制該列的唯一性和組織表中數據的排列結構;

(3)在經常用在連接的列上,這些列主要是一些外鍵,可以加快連接的速度;

(4)在經常需要根據範圍進行搜索的列上創建索引,因為索引已經排序,其指定的範圍是連續的;

(5)在經常需要排序的列上創建索引,因為索引已經排序,這樣查詢可以利用索引的排序,加快排序查詢時間;

(6)在經常使用在WHERE子句中的列上面創建索引,加快條件的判斷速度。

對於有些列不應該創建索引:

(1)對於那些在查詢中很少使用或者參考的列不應該創建索引。

這是因為,既然這些列很少使用到,因此有索引或者無索引,並不能提高查詢速度。相反,由於增加了索引,反而降低了系統的維護速度和增大了空間需求。

(2)對於那些只有很少數據值的列也不應該增加索引。

這是因為,由於這些列的取值很少,例如人事表的性別列,在查詢的結果中,結果集的數據行佔了表中數據行的很大比例,即需要在表中搜索的數據行的比例很大。增加索引,並不能明顯加快檢索速度。

(3)對於那些定義為text, image和bit數據類型的列不應該增加索引。

這是因為,這些列的數據量要麼相當大,要麼取值很少。

(4)當修改性能遠遠大於檢索性能時,不應該創建索引。

這是因為,修改性能和檢索性能是互相矛盾的。當增加索引時,會提高檢索性能,但是會降低修改性能。當減少索引時,會提高修改性能,降低檢索性能。因此,當修改性能遠遠大於檢索性能時,不應該創建索引。

史上最全面的數據庫常見筆試面試題(附含答案)中

5.什麼樣的字段適合建索引

唯一、不為空、經常被查詢的字段

6.MySQL B+Tree索引和Hash索引的區別?

Hash索引和B+樹索引的特點:

Hash索引結構的特殊性,其檢索效率非常高,索引的檢索可以一次定位;

B+樹索引需要從根節點到枝節點,最後才能訪問到頁節點這樣多次的IO訪問;

為什麼不都用Hash索引而使用B+樹索引?

Hash索引僅僅能滿足"=","IN"和""查詢,不能使用範圍查詢,因為經過相應的Hash算法處理之後的Hash值的大小關係,並不能保證和Hash運算前完全一樣;

Hash索引無法被用來避免數據的排序操作,因為Hash值的大小關係並不一定和Hash運算前的鍵值完全一樣;

Hash索引不能利用部分索引鍵查詢,對於組合索引,Hash索引在計算Hash值的時候是組合索引鍵合併後再一起計算Hash值,而不是單獨計算Hash值,所以通過組合索引的前面一個或幾個索引鍵進行查詢的時候,Hash索引也無法被利用;

Hash索引在任何時候都不能避免表掃描,由於不同索引鍵存在相同Hash值,所以即使取滿足某個Hash鍵值的數據的記錄條數,也無法從Hash索引中直接完成查詢,還是要回表查詢數據;

Hash索引遇到大量Hash值相等的情況後性能並不一定就會比B+樹索引高。

補充:

1.MySQL中,只有HEAP/MEMORY引擎才顯示支持Hash索引。

2.常用的InnoDB引擎中默認使用的是B+樹索引,它會實時監控表上索引的使用情況,如果認為建立哈希索引可以提高查詢效率,則自動在內存中的“自適應哈希索引緩衝區”建立哈希索引(在InnoDB中默認開啟自適應哈希索引),通過觀察搜索模式,MySQL會利用index key的前綴建立哈希索引,如果一個表幾乎大部分都在緩衝池中,那麼建立一個哈希索引能夠加快等值查詢。

B+樹索引和哈希索引的明顯區別是:

3.如果是等值查詢,那麼哈希索引明顯有絕對優勢,因為只需要經過一次算法即可找到相應的鍵值;當然了,這個前提是,鍵值都是唯一的。如果鍵值不是唯一的,就需要先找到該鍵所在位置,然後再根據鏈表往後掃描,直到找到相應的數據;

4.如果是範圍查詢檢索,這時候哈希索引就毫無用武之地了,因為原先是有序的鍵值,經過哈希算法後,有可能變成不連續的了,就沒辦法再利用索引完成範圍查詢檢索;

同理,哈希索引沒辦法利用索引完成排序,以及like ‘xxx%’ 這樣的部分模糊查詢(這種部分模糊查詢,其實本質上也是範圍查詢);

5.哈希索引也不支持多列聯合索引的最左匹配規則;

6.B+樹索引的關鍵字檢索效率比較平均,不像B樹那樣波動幅度大,在有大量重複鍵值情況下,哈希索引的效率也是極低的,因為存在所謂的哈希碰撞問題。

7.在大多數場景下,都會有範圍查詢、排序、分組等查詢特徵,用B+樹索引就可以了。

7.B樹和B+樹的區別

B樹,每個節點都存儲key和data,所有節點組成這棵樹,並且葉子節點指針為nul,葉子結點不包含任何關鍵字信息

B+樹,所有的葉子結點中包含了全部關鍵字的信息,及指向含有這些關鍵字記錄的指針,且葉子結點本身依關鍵字的大小自小而大的順序鏈接,所有的非終端結點可以看成是索引部分,結點中僅含有其子樹根結點中最大(或最小)關鍵字。(而B 樹的非終節點也包含需要查找的有效信息)

"

本文是銜接上文的,內容較多,建議收藏閱讀。

二、索引

1.什麼是索引?

何為索引:

數據庫索引,是數據庫管理系統中一個排序的數據結構,索引的實現通常使用B樹及其變種B+樹。

在數據之外,數據庫系統還維護著滿足特定查找算法的數據結構,這些數據結構以某種方式引用(指向)數據,這樣就可以在這些數據結構上實現高級查找算法。這種數據結構,就是索引。

史上最全面的數據庫常見筆試面試題(附含答案)中

2.索引的作用?它的優點缺點是什麼?

索引作用:

協助快速查詢、更新數據庫表中數據。

為表設置索引要付出代價的:

一是增加了數據庫的存儲空間

二是在插入和修改數據時要花費較多的時間(因為索引也要隨之變動)。

3.索引的優缺點?

創建索引可以大大提高系統的性能( 優點 ):

1.通過創建唯一性索引,可以保證數據庫表中每一行數據的唯一性。

2.可以大大加快數據的檢索速度,這也是創建索引的最主要的原因。

3.可以加速表和表之間的連接,特別是在實現數據的參考完整性方面特別有意義。

4.在使用分組和排序子句進行數據檢索時,同樣可以顯著減少查詢中分組和排序的時間。

5.通過使用索引,可以在查詢的過程中,使用優化隱藏器,提高系統的性能。

增加索引也有許多不利的方面( 缺點 ):

1.創建索引和維護索引要耗費時間,這種時間隨著數據量的增加而增加。

2.索引需要佔物理空間,除了數據表佔數據空間之外,每一個索引還要佔一定的物理空間,如果要建立聚簇索引,那麼需要的空間就會更大。

3.當對錶中的數據進行增加、刪除和修改的時候,索引也要動態的維護,這樣就降低了數據的維護速度。

4.哪些列適合建立索引、哪些不適合建索引?

索引是建立在數據庫表中的某些列的上面。在創建索引的時候,應該考慮在哪些列上可以創建索引,在哪些列上不能創建索引。

一般來說,應該在這些列上創建索引:

(1)在經常需要搜索的列上,可以加快搜索的速度;

(2)在作為主鍵的列上,強制該列的唯一性和組織表中數據的排列結構;

(3)在經常用在連接的列上,這些列主要是一些外鍵,可以加快連接的速度;

(4)在經常需要根據範圍進行搜索的列上創建索引,因為索引已經排序,其指定的範圍是連續的;

(5)在經常需要排序的列上創建索引,因為索引已經排序,這樣查詢可以利用索引的排序,加快排序查詢時間;

(6)在經常使用在WHERE子句中的列上面創建索引,加快條件的判斷速度。

對於有些列不應該創建索引:

(1)對於那些在查詢中很少使用或者參考的列不應該創建索引。

這是因為,既然這些列很少使用到,因此有索引或者無索引,並不能提高查詢速度。相反,由於增加了索引,反而降低了系統的維護速度和增大了空間需求。

(2)對於那些只有很少數據值的列也不應該增加索引。

這是因為,由於這些列的取值很少,例如人事表的性別列,在查詢的結果中,結果集的數據行佔了表中數據行的很大比例,即需要在表中搜索的數據行的比例很大。增加索引,並不能明顯加快檢索速度。

(3)對於那些定義為text, image和bit數據類型的列不應該增加索引。

這是因為,這些列的數據量要麼相當大,要麼取值很少。

(4)當修改性能遠遠大於檢索性能時,不應該創建索引。

這是因為,修改性能和檢索性能是互相矛盾的。當增加索引時,會提高檢索性能,但是會降低修改性能。當減少索引時,會提高修改性能,降低檢索性能。因此,當修改性能遠遠大於檢索性能時,不應該創建索引。

史上最全面的數據庫常見筆試面試題(附含答案)中

5.什麼樣的字段適合建索引

唯一、不為空、經常被查詢的字段

6.MySQL B+Tree索引和Hash索引的區別?

Hash索引和B+樹索引的特點:

Hash索引結構的特殊性,其檢索效率非常高,索引的檢索可以一次定位;

B+樹索引需要從根節點到枝節點,最後才能訪問到頁節點這樣多次的IO訪問;

為什麼不都用Hash索引而使用B+樹索引?

Hash索引僅僅能滿足"=","IN"和""查詢,不能使用範圍查詢,因為經過相應的Hash算法處理之後的Hash值的大小關係,並不能保證和Hash運算前完全一樣;

Hash索引無法被用來避免數據的排序操作,因為Hash值的大小關係並不一定和Hash運算前的鍵值完全一樣;

Hash索引不能利用部分索引鍵查詢,對於組合索引,Hash索引在計算Hash值的時候是組合索引鍵合併後再一起計算Hash值,而不是單獨計算Hash值,所以通過組合索引的前面一個或幾個索引鍵進行查詢的時候,Hash索引也無法被利用;

Hash索引在任何時候都不能避免表掃描,由於不同索引鍵存在相同Hash值,所以即使取滿足某個Hash鍵值的數據的記錄條數,也無法從Hash索引中直接完成查詢,還是要回表查詢數據;

Hash索引遇到大量Hash值相等的情況後性能並不一定就會比B+樹索引高。

補充:

1.MySQL中,只有HEAP/MEMORY引擎才顯示支持Hash索引。

2.常用的InnoDB引擎中默認使用的是B+樹索引,它會實時監控表上索引的使用情況,如果認為建立哈希索引可以提高查詢效率,則自動在內存中的“自適應哈希索引緩衝區”建立哈希索引(在InnoDB中默認開啟自適應哈希索引),通過觀察搜索模式,MySQL會利用index key的前綴建立哈希索引,如果一個表幾乎大部分都在緩衝池中,那麼建立一個哈希索引能夠加快等值查詢。

B+樹索引和哈希索引的明顯區別是:

3.如果是等值查詢,那麼哈希索引明顯有絕對優勢,因為只需要經過一次算法即可找到相應的鍵值;當然了,這個前提是,鍵值都是唯一的。如果鍵值不是唯一的,就需要先找到該鍵所在位置,然後再根據鏈表往後掃描,直到找到相應的數據;

4.如果是範圍查詢檢索,這時候哈希索引就毫無用武之地了,因為原先是有序的鍵值,經過哈希算法後,有可能變成不連續的了,就沒辦法再利用索引完成範圍查詢檢索;

同理,哈希索引沒辦法利用索引完成排序,以及like ‘xxx%’ 這樣的部分模糊查詢(這種部分模糊查詢,其實本質上也是範圍查詢);

5.哈希索引也不支持多列聯合索引的最左匹配規則;

6.B+樹索引的關鍵字檢索效率比較平均,不像B樹那樣波動幅度大,在有大量重複鍵值情況下,哈希索引的效率也是極低的,因為存在所謂的哈希碰撞問題。

7.在大多數場景下,都會有範圍查詢、排序、分組等查詢特徵,用B+樹索引就可以了。

7.B樹和B+樹的區別

B樹,每個節點都存儲key和data,所有節點組成這棵樹,並且葉子節點指針為nul,葉子結點不包含任何關鍵字信息

B+樹,所有的葉子結點中包含了全部關鍵字的信息,及指向含有這些關鍵字記錄的指針,且葉子結點本身依關鍵字的大小自小而大的順序鏈接,所有的非終端結點可以看成是索引部分,結點中僅含有其子樹根結點中最大(或最小)關鍵字。(而B 樹的非終節點也包含需要查找的有效信息)

史上最全面的數據庫常見筆試面試題(附含答案)中

8.為什麼說B+比B樹更適合實際應用中操作系統的文件索引和數據庫索引?

1.B+的磁盤讀寫代價更低

B+的內部結點並沒有指向關鍵字具體信息的指針。因此其內部結點相對B樹更小。如果把所有同一內部結點的關鍵字存放在同一盤塊中,那麼盤塊所能容納的關鍵字數量也越多。一次性讀入內存中的需要查找的關鍵字也就越多。相對來說IO讀寫次數也就降低了。

2.B+tree的查詢效率更加穩定

由於非終結點並不是最終指向文件內容的結點,而只是葉子結點中關鍵字的索引。所以任何關鍵字的查找必須走一條從根結點到葉子結點的路。所有關鍵字查詢的路徑長度相同,導致每一個數據的查詢效率相當。

9.聚集索引和非聚集索引區別?

聚合索引(clustered index):

聚集索引表記錄的排列順序和索引的排列順序一致,所以查詢效率快,只要找到第一個索引值記錄,其餘就連續性的記錄在物理也一樣連續存放。聚集索引對應的缺點就是修改慢,因為為了保證表中記錄的物理和索引順序一致,在記錄插入的時候,會對數據頁重新排序。

聚集索引類似於新華字典中用拼音去查找漢字,拼音檢索表於書記順序都是按照a~z排列的,就像相同的邏輯順序於物理順序一樣,當你需要查找a,ai兩個讀音的字,或是想一次尋找多個傻(sha)的同音字時,也許向後翻幾頁,或緊接著下一行就得到結果了。

非聚合索引(nonclustered index):

非聚集索引指定了表中記錄的邏輯順序,但是記錄的物理和索引不一定一致,兩種索引都採用B+樹結構,非聚集索引的葉子層並不和實際數據頁相重疊,而採用葉子層包含一個指向表中的記錄在數據頁中的指針方式。非聚集索引層次多,不會造成數據重排。

非聚集索引類似在新華字典上通過偏旁部首來查詢漢字,檢索表也許是按照橫、豎、撇來排列的,但是由於正文中是a~z的拼音順序,所以就類似於邏輯地址於物理地址的不對應。同時適用的情況就在於分組,大數目的不同值,頻繁更新的列中,這些情況即不適合聚集索引。

根本區別:

聚集索引和非聚集索引的根本區別是表記錄的排列順序和與索引的排列順序是否一致。

"

本文是銜接上文的,內容較多,建議收藏閱讀。

二、索引

1.什麼是索引?

何為索引:

數據庫索引,是數據庫管理系統中一個排序的數據結構,索引的實現通常使用B樹及其變種B+樹。

在數據之外,數據庫系統還維護著滿足特定查找算法的數據結構,這些數據結構以某種方式引用(指向)數據,這樣就可以在這些數據結構上實現高級查找算法。這種數據結構,就是索引。

史上最全面的數據庫常見筆試面試題(附含答案)中

2.索引的作用?它的優點缺點是什麼?

索引作用:

協助快速查詢、更新數據庫表中數據。

為表設置索引要付出代價的:

一是增加了數據庫的存儲空間

二是在插入和修改數據時要花費較多的時間(因為索引也要隨之變動)。

3.索引的優缺點?

創建索引可以大大提高系統的性能( 優點 ):

1.通過創建唯一性索引,可以保證數據庫表中每一行數據的唯一性。

2.可以大大加快數據的檢索速度,這也是創建索引的最主要的原因。

3.可以加速表和表之間的連接,特別是在實現數據的參考完整性方面特別有意義。

4.在使用分組和排序子句進行數據檢索時,同樣可以顯著減少查詢中分組和排序的時間。

5.通過使用索引,可以在查詢的過程中,使用優化隱藏器,提高系統的性能。

增加索引也有許多不利的方面( 缺點 ):

1.創建索引和維護索引要耗費時間,這種時間隨著數據量的增加而增加。

2.索引需要佔物理空間,除了數據表佔數據空間之外,每一個索引還要佔一定的物理空間,如果要建立聚簇索引,那麼需要的空間就會更大。

3.當對錶中的數據進行增加、刪除和修改的時候,索引也要動態的維護,這樣就降低了數據的維護速度。

4.哪些列適合建立索引、哪些不適合建索引?

索引是建立在數據庫表中的某些列的上面。在創建索引的時候,應該考慮在哪些列上可以創建索引,在哪些列上不能創建索引。

一般來說,應該在這些列上創建索引:

(1)在經常需要搜索的列上,可以加快搜索的速度;

(2)在作為主鍵的列上,強制該列的唯一性和組織表中數據的排列結構;

(3)在經常用在連接的列上,這些列主要是一些外鍵,可以加快連接的速度;

(4)在經常需要根據範圍進行搜索的列上創建索引,因為索引已經排序,其指定的範圍是連續的;

(5)在經常需要排序的列上創建索引,因為索引已經排序,這樣查詢可以利用索引的排序,加快排序查詢時間;

(6)在經常使用在WHERE子句中的列上面創建索引,加快條件的判斷速度。

對於有些列不應該創建索引:

(1)對於那些在查詢中很少使用或者參考的列不應該創建索引。

這是因為,既然這些列很少使用到,因此有索引或者無索引,並不能提高查詢速度。相反,由於增加了索引,反而降低了系統的維護速度和增大了空間需求。

(2)對於那些只有很少數據值的列也不應該增加索引。

這是因為,由於這些列的取值很少,例如人事表的性別列,在查詢的結果中,結果集的數據行佔了表中數據行的很大比例,即需要在表中搜索的數據行的比例很大。增加索引,並不能明顯加快檢索速度。

(3)對於那些定義為text, image和bit數據類型的列不應該增加索引。

這是因為,這些列的數據量要麼相當大,要麼取值很少。

(4)當修改性能遠遠大於檢索性能時,不應該創建索引。

這是因為,修改性能和檢索性能是互相矛盾的。當增加索引時,會提高檢索性能,但是會降低修改性能。當減少索引時,會提高修改性能,降低檢索性能。因此,當修改性能遠遠大於檢索性能時,不應該創建索引。

史上最全面的數據庫常見筆試面試題(附含答案)中

5.什麼樣的字段適合建索引

唯一、不為空、經常被查詢的字段

6.MySQL B+Tree索引和Hash索引的區別?

Hash索引和B+樹索引的特點:

Hash索引結構的特殊性,其檢索效率非常高,索引的檢索可以一次定位;

B+樹索引需要從根節點到枝節點,最後才能訪問到頁節點這樣多次的IO訪問;

為什麼不都用Hash索引而使用B+樹索引?

Hash索引僅僅能滿足"=","IN"和""查詢,不能使用範圍查詢,因為經過相應的Hash算法處理之後的Hash值的大小關係,並不能保證和Hash運算前完全一樣;

Hash索引無法被用來避免數據的排序操作,因為Hash值的大小關係並不一定和Hash運算前的鍵值完全一樣;

Hash索引不能利用部分索引鍵查詢,對於組合索引,Hash索引在計算Hash值的時候是組合索引鍵合併後再一起計算Hash值,而不是單獨計算Hash值,所以通過組合索引的前面一個或幾個索引鍵進行查詢的時候,Hash索引也無法被利用;

Hash索引在任何時候都不能避免表掃描,由於不同索引鍵存在相同Hash值,所以即使取滿足某個Hash鍵值的數據的記錄條數,也無法從Hash索引中直接完成查詢,還是要回表查詢數據;

Hash索引遇到大量Hash值相等的情況後性能並不一定就會比B+樹索引高。

補充:

1.MySQL中,只有HEAP/MEMORY引擎才顯示支持Hash索引。

2.常用的InnoDB引擎中默認使用的是B+樹索引,它會實時監控表上索引的使用情況,如果認為建立哈希索引可以提高查詢效率,則自動在內存中的“自適應哈希索引緩衝區”建立哈希索引(在InnoDB中默認開啟自適應哈希索引),通過觀察搜索模式,MySQL會利用index key的前綴建立哈希索引,如果一個表幾乎大部分都在緩衝池中,那麼建立一個哈希索引能夠加快等值查詢。

B+樹索引和哈希索引的明顯區別是:

3.如果是等值查詢,那麼哈希索引明顯有絕對優勢,因為只需要經過一次算法即可找到相應的鍵值;當然了,這個前提是,鍵值都是唯一的。如果鍵值不是唯一的,就需要先找到該鍵所在位置,然後再根據鏈表往後掃描,直到找到相應的數據;

4.如果是範圍查詢檢索,這時候哈希索引就毫無用武之地了,因為原先是有序的鍵值,經過哈希算法後,有可能變成不連續的了,就沒辦法再利用索引完成範圍查詢檢索;

同理,哈希索引沒辦法利用索引完成排序,以及like ‘xxx%’ 這樣的部分模糊查詢(這種部分模糊查詢,其實本質上也是範圍查詢);

5.哈希索引也不支持多列聯合索引的最左匹配規則;

6.B+樹索引的關鍵字檢索效率比較平均,不像B樹那樣波動幅度大,在有大量重複鍵值情況下,哈希索引的效率也是極低的,因為存在所謂的哈希碰撞問題。

7.在大多數場景下,都會有範圍查詢、排序、分組等查詢特徵,用B+樹索引就可以了。

7.B樹和B+樹的區別

B樹,每個節點都存儲key和data,所有節點組成這棵樹,並且葉子節點指針為nul,葉子結點不包含任何關鍵字信息

B+樹,所有的葉子結點中包含了全部關鍵字的信息,及指向含有這些關鍵字記錄的指針,且葉子結點本身依關鍵字的大小自小而大的順序鏈接,所有的非終端結點可以看成是索引部分,結點中僅含有其子樹根結點中最大(或最小)關鍵字。(而B 樹的非終節點也包含需要查找的有效信息)

史上最全面的數據庫常見筆試面試題(附含答案)中

8.為什麼說B+比B樹更適合實際應用中操作系統的文件索引和數據庫索引?

1.B+的磁盤讀寫代價更低

B+的內部結點並沒有指向關鍵字具體信息的指針。因此其內部結點相對B樹更小。如果把所有同一內部結點的關鍵字存放在同一盤塊中,那麼盤塊所能容納的關鍵字數量也越多。一次性讀入內存中的需要查找的關鍵字也就越多。相對來說IO讀寫次數也就降低了。

2.B+tree的查詢效率更加穩定

由於非終結點並不是最終指向文件內容的結點,而只是葉子結點中關鍵字的索引。所以任何關鍵字的查找必須走一條從根結點到葉子結點的路。所有關鍵字查詢的路徑長度相同,導致每一個數據的查詢效率相當。

9.聚集索引和非聚集索引區別?

聚合索引(clustered index):

聚集索引表記錄的排列順序和索引的排列順序一致,所以查詢效率快,只要找到第一個索引值記錄,其餘就連續性的記錄在物理也一樣連續存放。聚集索引對應的缺點就是修改慢,因為為了保證表中記錄的物理和索引順序一致,在記錄插入的時候,會對數據頁重新排序。

聚集索引類似於新華字典中用拼音去查找漢字,拼音檢索表於書記順序都是按照a~z排列的,就像相同的邏輯順序於物理順序一樣,當你需要查找a,ai兩個讀音的字,或是想一次尋找多個傻(sha)的同音字時,也許向後翻幾頁,或緊接著下一行就得到結果了。

非聚合索引(nonclustered index):

非聚集索引指定了表中記錄的邏輯順序,但是記錄的物理和索引不一定一致,兩種索引都採用B+樹結構,非聚集索引的葉子層並不和實際數據頁相重疊,而採用葉子層包含一個指向表中的記錄在數據頁中的指針方式。非聚集索引層次多,不會造成數據重排。

非聚集索引類似在新華字典上通過偏旁部首來查詢漢字,檢索表也許是按照橫、豎、撇來排列的,但是由於正文中是a~z的拼音順序,所以就類似於邏輯地址於物理地址的不對應。同時適用的情況就在於分組,大數目的不同值,頻繁更新的列中,這些情況即不適合聚集索引。

根本區別:

聚集索引和非聚集索引的根本區別是表記錄的排列順序和與索引的排列順序是否一致。

史上最全面的數據庫常見筆試面試題(附含答案)中

三、事務

1.什麼是事務?

事務是對數據庫中一系列操作進行統一的回滾或者提交的操作,主要用來保證數據的完整性和一致性。

2.事務四大特性(ACID)原子性、一致性、隔離性、持久性?

原子性(Atomicity):

原子性是指事務包含的所有操作要麼全部成功,要麼全部失敗回滾,因此事務的操作如果成功就必須要完全應用到數據庫,如果操作失敗則不能對數據庫有任何影響。

一致性(Consistency):

事務開始前和結束後,數據庫的完整性約束沒有被破壞。比如A向B轉賬,不可能A扣了錢,B卻沒收到。

隔離性(Isolation):

隔離性是當多個用戶併發訪問數據庫時,比如操作同一張表時,數據庫為每一個用戶開啟的事務,不能被其他事務的操作所幹擾,多個併發事務之間要相互隔離。同一時間,只允許一個事務請求同一數據,不同的事務之間彼此沒有任何干擾。比如A正在從一張銀行卡中取錢,在A取錢的過程結束前,B不能向這張卡轉賬。

持久性(Durability):

持久性是指一個事務一旦被提交了,那麼對數據庫中的數據的改變就是永久性的,即便是在數據庫系統遇到故障的情況下也不會丟失提交事務的操作。

3.事務的併發?事務隔離級別,每個級別會引發什麼問題,MySQL默認是哪個級別?

從理論上來說, 事務應該彼此完全隔離, 以避免併發事務所導致的問題,然而, 那樣會對性能產生極大的影響, 因為事務必須按順序運行, 在實際開發中, 為了提升性能, 事務會以較低的隔離級別運行, 事務的隔離級別可以通過隔離事務屬性指定。

事務的併發問題

1、髒讀:事務A讀取了事務B更新的數據,然後B回滾操作,那麼A讀取到的數據是髒數據

2、不可重複讀:事務 A 多次讀取同一數據,事務 B 在事務A多次讀取的過程中,對數據作了更新並提交,導致事務A多次讀取同一數據時,結果因此本事務先後兩次讀到的數據結果會不一致。

3、幻讀:幻讀解決了不重複讀,保證了同一個事務裡,查詢的結果都是事務開始時的狀態(一致性)。

例如:事務T1對一個表中所有的行的某個數據項做了從“1”修改為“2”的操作 這時事務T2又對這個表中插入了一行數據項,而這個數據項的數值還是為“1”並且提交給數據庫。而操作事務T1的用戶如果再查看剛剛修改的數據,會發現還有跟沒有修改一樣,其實這行是從事務T2中添加的,就好像產生幻覺一樣,這就是發生了幻讀。

小結:不可重複讀的和幻讀很容易混淆,不可重複讀側重於修改,幻讀側重於新增或刪除。解決不可重複讀的問題只需鎖住滿足條件的行,解決幻讀需要鎖表。

事務的隔離級別

讀未提交:另一個事務修改了數據,但尚未提交,而本事務中的SELECT會讀到這些未被提交的數據髒讀

不可重複讀:事務 A 多次讀取同一數據,事務 B 在事務A多次讀取的過程中,對數據作了更新並提交,導致事務A多次讀取同一數據時,結果因此本事務先後兩次讀到的數據結果會不一致。

可重複讀:在同一個事務裡,SELECT的結果是事務開始時時間點的狀態,因此,同樣的SELECT操作讀到的結果會是一致的。但是,會有幻讀現象

串行化:最高的隔離級別,在這個隔離級別下,不會產生任何異常。併發的事務,就像事務是在一個個按照順序執行一樣

"

本文是銜接上文的,內容較多,建議收藏閱讀。

二、索引

1.什麼是索引?

何為索引:

數據庫索引,是數據庫管理系統中一個排序的數據結構,索引的實現通常使用B樹及其變種B+樹。

在數據之外,數據庫系統還維護著滿足特定查找算法的數據結構,這些數據結構以某種方式引用(指向)數據,這樣就可以在這些數據結構上實現高級查找算法。這種數據結構,就是索引。

史上最全面的數據庫常見筆試面試題(附含答案)中

2.索引的作用?它的優點缺點是什麼?

索引作用:

協助快速查詢、更新數據庫表中數據。

為表設置索引要付出代價的:

一是增加了數據庫的存儲空間

二是在插入和修改數據時要花費較多的時間(因為索引也要隨之變動)。

3.索引的優缺點?

創建索引可以大大提高系統的性能( 優點 ):

1.通過創建唯一性索引,可以保證數據庫表中每一行數據的唯一性。

2.可以大大加快數據的檢索速度,這也是創建索引的最主要的原因。

3.可以加速表和表之間的連接,特別是在實現數據的參考完整性方面特別有意義。

4.在使用分組和排序子句進行數據檢索時,同樣可以顯著減少查詢中分組和排序的時間。

5.通過使用索引,可以在查詢的過程中,使用優化隱藏器,提高系統的性能。

增加索引也有許多不利的方面( 缺點 ):

1.創建索引和維護索引要耗費時間,這種時間隨著數據量的增加而增加。

2.索引需要佔物理空間,除了數據表佔數據空間之外,每一個索引還要佔一定的物理空間,如果要建立聚簇索引,那麼需要的空間就會更大。

3.當對錶中的數據進行增加、刪除和修改的時候,索引也要動態的維護,這樣就降低了數據的維護速度。

4.哪些列適合建立索引、哪些不適合建索引?

索引是建立在數據庫表中的某些列的上面。在創建索引的時候,應該考慮在哪些列上可以創建索引,在哪些列上不能創建索引。

一般來說,應該在這些列上創建索引:

(1)在經常需要搜索的列上,可以加快搜索的速度;

(2)在作為主鍵的列上,強制該列的唯一性和組織表中數據的排列結構;

(3)在經常用在連接的列上,這些列主要是一些外鍵,可以加快連接的速度;

(4)在經常需要根據範圍進行搜索的列上創建索引,因為索引已經排序,其指定的範圍是連續的;

(5)在經常需要排序的列上創建索引,因為索引已經排序,這樣查詢可以利用索引的排序,加快排序查詢時間;

(6)在經常使用在WHERE子句中的列上面創建索引,加快條件的判斷速度。

對於有些列不應該創建索引:

(1)對於那些在查詢中很少使用或者參考的列不應該創建索引。

這是因為,既然這些列很少使用到,因此有索引或者無索引,並不能提高查詢速度。相反,由於增加了索引,反而降低了系統的維護速度和增大了空間需求。

(2)對於那些只有很少數據值的列也不應該增加索引。

這是因為,由於這些列的取值很少,例如人事表的性別列,在查詢的結果中,結果集的數據行佔了表中數據行的很大比例,即需要在表中搜索的數據行的比例很大。增加索引,並不能明顯加快檢索速度。

(3)對於那些定義為text, image和bit數據類型的列不應該增加索引。

這是因為,這些列的數據量要麼相當大,要麼取值很少。

(4)當修改性能遠遠大於檢索性能時,不應該創建索引。

這是因為,修改性能和檢索性能是互相矛盾的。當增加索引時,會提高檢索性能,但是會降低修改性能。當減少索引時,會提高修改性能,降低檢索性能。因此,當修改性能遠遠大於檢索性能時,不應該創建索引。

史上最全面的數據庫常見筆試面試題(附含答案)中

5.什麼樣的字段適合建索引

唯一、不為空、經常被查詢的字段

6.MySQL B+Tree索引和Hash索引的區別?

Hash索引和B+樹索引的特點:

Hash索引結構的特殊性,其檢索效率非常高,索引的檢索可以一次定位;

B+樹索引需要從根節點到枝節點,最後才能訪問到頁節點這樣多次的IO訪問;

為什麼不都用Hash索引而使用B+樹索引?

Hash索引僅僅能滿足"=","IN"和""查詢,不能使用範圍查詢,因為經過相應的Hash算法處理之後的Hash值的大小關係,並不能保證和Hash運算前完全一樣;

Hash索引無法被用來避免數據的排序操作,因為Hash值的大小關係並不一定和Hash運算前的鍵值完全一樣;

Hash索引不能利用部分索引鍵查詢,對於組合索引,Hash索引在計算Hash值的時候是組合索引鍵合併後再一起計算Hash值,而不是單獨計算Hash值,所以通過組合索引的前面一個或幾個索引鍵進行查詢的時候,Hash索引也無法被利用;

Hash索引在任何時候都不能避免表掃描,由於不同索引鍵存在相同Hash值,所以即使取滿足某個Hash鍵值的數據的記錄條數,也無法從Hash索引中直接完成查詢,還是要回表查詢數據;

Hash索引遇到大量Hash值相等的情況後性能並不一定就會比B+樹索引高。

補充:

1.MySQL中,只有HEAP/MEMORY引擎才顯示支持Hash索引。

2.常用的InnoDB引擎中默認使用的是B+樹索引,它會實時監控表上索引的使用情況,如果認為建立哈希索引可以提高查詢效率,則自動在內存中的“自適應哈希索引緩衝區”建立哈希索引(在InnoDB中默認開啟自適應哈希索引),通過觀察搜索模式,MySQL會利用index key的前綴建立哈希索引,如果一個表幾乎大部分都在緩衝池中,那麼建立一個哈希索引能夠加快等值查詢。

B+樹索引和哈希索引的明顯區別是:

3.如果是等值查詢,那麼哈希索引明顯有絕對優勢,因為只需要經過一次算法即可找到相應的鍵值;當然了,這個前提是,鍵值都是唯一的。如果鍵值不是唯一的,就需要先找到該鍵所在位置,然後再根據鏈表往後掃描,直到找到相應的數據;

4.如果是範圍查詢檢索,這時候哈希索引就毫無用武之地了,因為原先是有序的鍵值,經過哈希算法後,有可能變成不連續的了,就沒辦法再利用索引完成範圍查詢檢索;

同理,哈希索引沒辦法利用索引完成排序,以及like ‘xxx%’ 這樣的部分模糊查詢(這種部分模糊查詢,其實本質上也是範圍查詢);

5.哈希索引也不支持多列聯合索引的最左匹配規則;

6.B+樹索引的關鍵字檢索效率比較平均,不像B樹那樣波動幅度大,在有大量重複鍵值情況下,哈希索引的效率也是極低的,因為存在所謂的哈希碰撞問題。

7.在大多數場景下,都會有範圍查詢、排序、分組等查詢特徵,用B+樹索引就可以了。

7.B樹和B+樹的區別

B樹,每個節點都存儲key和data,所有節點組成這棵樹,並且葉子節點指針為nul,葉子結點不包含任何關鍵字信息

B+樹,所有的葉子結點中包含了全部關鍵字的信息,及指向含有這些關鍵字記錄的指針,且葉子結點本身依關鍵字的大小自小而大的順序鏈接,所有的非終端結點可以看成是索引部分,結點中僅含有其子樹根結點中最大(或最小)關鍵字。(而B 樹的非終節點也包含需要查找的有效信息)

史上最全面的數據庫常見筆試面試題(附含答案)中

8.為什麼說B+比B樹更適合實際應用中操作系統的文件索引和數據庫索引?

1.B+的磁盤讀寫代價更低

B+的內部結點並沒有指向關鍵字具體信息的指針。因此其內部結點相對B樹更小。如果把所有同一內部結點的關鍵字存放在同一盤塊中,那麼盤塊所能容納的關鍵字數量也越多。一次性讀入內存中的需要查找的關鍵字也就越多。相對來說IO讀寫次數也就降低了。

2.B+tree的查詢效率更加穩定

由於非終結點並不是最終指向文件內容的結點,而只是葉子結點中關鍵字的索引。所以任何關鍵字的查找必須走一條從根結點到葉子結點的路。所有關鍵字查詢的路徑長度相同,導致每一個數據的查詢效率相當。

9.聚集索引和非聚集索引區別?

聚合索引(clustered index):

聚集索引表記錄的排列順序和索引的排列順序一致,所以查詢效率快,只要找到第一個索引值記錄,其餘就連續性的記錄在物理也一樣連續存放。聚集索引對應的缺點就是修改慢,因為為了保證表中記錄的物理和索引順序一致,在記錄插入的時候,會對數據頁重新排序。

聚集索引類似於新華字典中用拼音去查找漢字,拼音檢索表於書記順序都是按照a~z排列的,就像相同的邏輯順序於物理順序一樣,當你需要查找a,ai兩個讀音的字,或是想一次尋找多個傻(sha)的同音字時,也許向後翻幾頁,或緊接著下一行就得到結果了。

非聚合索引(nonclustered index):

非聚集索引指定了表中記錄的邏輯順序,但是記錄的物理和索引不一定一致,兩種索引都採用B+樹結構,非聚集索引的葉子層並不和實際數據頁相重疊,而採用葉子層包含一個指向表中的記錄在數據頁中的指針方式。非聚集索引層次多,不會造成數據重排。

非聚集索引類似在新華字典上通過偏旁部首來查詢漢字,檢索表也許是按照橫、豎、撇來排列的,但是由於正文中是a~z的拼音順序,所以就類似於邏輯地址於物理地址的不對應。同時適用的情況就在於分組,大數目的不同值,頻繁更新的列中,這些情況即不適合聚集索引。

根本區別:

聚集索引和非聚集索引的根本區別是表記錄的排列順序和與索引的排列順序是否一致。

史上最全面的數據庫常見筆試面試題(附含答案)中

三、事務

1.什麼是事務?

事務是對數據庫中一系列操作進行統一的回滾或者提交的操作,主要用來保證數據的完整性和一致性。

2.事務四大特性(ACID)原子性、一致性、隔離性、持久性?

原子性(Atomicity):

原子性是指事務包含的所有操作要麼全部成功,要麼全部失敗回滾,因此事務的操作如果成功就必須要完全應用到數據庫,如果操作失敗則不能對數據庫有任何影響。

一致性(Consistency):

事務開始前和結束後,數據庫的完整性約束沒有被破壞。比如A向B轉賬,不可能A扣了錢,B卻沒收到。

隔離性(Isolation):

隔離性是當多個用戶併發訪問數據庫時,比如操作同一張表時,數據庫為每一個用戶開啟的事務,不能被其他事務的操作所幹擾,多個併發事務之間要相互隔離。同一時間,只允許一個事務請求同一數據,不同的事務之間彼此沒有任何干擾。比如A正在從一張銀行卡中取錢,在A取錢的過程結束前,B不能向這張卡轉賬。

持久性(Durability):

持久性是指一個事務一旦被提交了,那麼對數據庫中的數據的改變就是永久性的,即便是在數據庫系統遇到故障的情況下也不會丟失提交事務的操作。

3.事務的併發?事務隔離級別,每個級別會引發什麼問題,MySQL默認是哪個級別?

從理論上來說, 事務應該彼此完全隔離, 以避免併發事務所導致的問題,然而, 那樣會對性能產生極大的影響, 因為事務必須按順序運行, 在實際開發中, 為了提升性能, 事務會以較低的隔離級別運行, 事務的隔離級別可以通過隔離事務屬性指定。

事務的併發問題

1、髒讀:事務A讀取了事務B更新的數據,然後B回滾操作,那麼A讀取到的數據是髒數據

2、不可重複讀:事務 A 多次讀取同一數據,事務 B 在事務A多次讀取的過程中,對數據作了更新並提交,導致事務A多次讀取同一數據時,結果因此本事務先後兩次讀到的數據結果會不一致。

3、幻讀:幻讀解決了不重複讀,保證了同一個事務裡,查詢的結果都是事務開始時的狀態(一致性)。

例如:事務T1對一個表中所有的行的某個數據項做了從“1”修改為“2”的操作 這時事務T2又對這個表中插入了一行數據項,而這個數據項的數值還是為“1”並且提交給數據庫。而操作事務T1的用戶如果再查看剛剛修改的數據,會發現還有跟沒有修改一樣,其實這行是從事務T2中添加的,就好像產生幻覺一樣,這就是發生了幻讀。

小結:不可重複讀的和幻讀很容易混淆,不可重複讀側重於修改,幻讀側重於新增或刪除。解決不可重複讀的問題只需鎖住滿足條件的行,解決幻讀需要鎖表。

事務的隔離級別

讀未提交:另一個事務修改了數據,但尚未提交,而本事務中的SELECT會讀到這些未被提交的數據髒讀

不可重複讀:事務 A 多次讀取同一數據,事務 B 在事務A多次讀取的過程中,對數據作了更新並提交,導致事務A多次讀取同一數據時,結果因此本事務先後兩次讀到的數據結果會不一致。

可重複讀:在同一個事務裡,SELECT的結果是事務開始時時間點的狀態,因此,同樣的SELECT操作讀到的結果會是一致的。但是,會有幻讀現象

串行化:最高的隔離級別,在這個隔離級別下,不會產生任何異常。併發的事務,就像事務是在一個個按照順序執行一樣

史上最全面的數據庫常見筆試面試題(附含答案)中

4.事務傳播行為

1.PROPAGATION_REQUIRED:如果當前沒有事務,就創建一個新事務,如果當前存在事務,就加入該事務,該設置是最常用的設置。

2.PROPAGATION_SUPPORTS:支持當前事務,如果當前存在事務,就加入該事務,如果當前不存在事務,就以非事務執行。

3.PROPAGATION_MANDATORY:支持當前事務,如果當前存在事務,就加入該事務,如果當前不存在事務,就拋出異常。

4.PROPAGATION_REQUIRES_NEW:創建新事務,無論當前存不存在事務,都創建新事務。

5.PROPAGATION_NOT_SUPPORTED:以非事務方式執行操作,如果當前存在事務,就把當前事務掛起。

6.PROPAGATION_NEVER:以非事務方式執行,如果當前存在事務,則拋出異常。

7.PROPAGATION_NESTED:如果當前存在事務,則在嵌套事務內執行。如果當前沒有事務,則執行與PROPAGATION_REQUIRED類似的操作。

5.嵌套事務

嵌套是子事務套在父事務中執行,子事務是父事務的一部分,在進入子事務之前,父事務建立一個回滾點,叫save point,然後執行子事務,這個子事務的執行也算是父事務的一部分,然後子事務執行結束,父事務繼續執行。重點就在於那個save point。看幾個問題就明瞭了:

如果子事務回滾,會發生什麼?

父事務會回滾到進入子事務前建立的save point,然後嘗試其他的事務或者其他的業務邏輯,父事務之前的操作不會受到影響,更不會自動回滾。

如果父事務回滾,會發生什麼?

父事務回滾,子事務也會跟著回滾!為什麼呢,因為父事務結束之前,子事務是不會提交的,我們說子事務是父事務的一部分,正是這個道理。那麼:

事務的提交,是什麼情況?

是父事務先提交,然後子事務提交,還是子事務先提交,父事務再提交?答案是第二種情況,還是那句話,子事務是父事務的一部分,由父事務統一提交。

"

本文是銜接上文的,內容較多,建議收藏閱讀。

二、索引

1.什麼是索引?

何為索引:

數據庫索引,是數據庫管理系統中一個排序的數據結構,索引的實現通常使用B樹及其變種B+樹。

在數據之外,數據庫系統還維護著滿足特定查找算法的數據結構,這些數據結構以某種方式引用(指向)數據,這樣就可以在這些數據結構上實現高級查找算法。這種數據結構,就是索引。

史上最全面的數據庫常見筆試面試題(附含答案)中

2.索引的作用?它的優點缺點是什麼?

索引作用:

協助快速查詢、更新數據庫表中數據。

為表設置索引要付出代價的:

一是增加了數據庫的存儲空間

二是在插入和修改數據時要花費較多的時間(因為索引也要隨之變動)。

3.索引的優缺點?

創建索引可以大大提高系統的性能( 優點 ):

1.通過創建唯一性索引,可以保證數據庫表中每一行數據的唯一性。

2.可以大大加快數據的檢索速度,這也是創建索引的最主要的原因。

3.可以加速表和表之間的連接,特別是在實現數據的參考完整性方面特別有意義。

4.在使用分組和排序子句進行數據檢索時,同樣可以顯著減少查詢中分組和排序的時間。

5.通過使用索引,可以在查詢的過程中,使用優化隱藏器,提高系統的性能。

增加索引也有許多不利的方面( 缺點 ):

1.創建索引和維護索引要耗費時間,這種時間隨著數據量的增加而增加。

2.索引需要佔物理空間,除了數據表佔數據空間之外,每一個索引還要佔一定的物理空間,如果要建立聚簇索引,那麼需要的空間就會更大。

3.當對錶中的數據進行增加、刪除和修改的時候,索引也要動態的維護,這樣就降低了數據的維護速度。

4.哪些列適合建立索引、哪些不適合建索引?

索引是建立在數據庫表中的某些列的上面。在創建索引的時候,應該考慮在哪些列上可以創建索引,在哪些列上不能創建索引。

一般來說,應該在這些列上創建索引:

(1)在經常需要搜索的列上,可以加快搜索的速度;

(2)在作為主鍵的列上,強制該列的唯一性和組織表中數據的排列結構;

(3)在經常用在連接的列上,這些列主要是一些外鍵,可以加快連接的速度;

(4)在經常需要根據範圍進行搜索的列上創建索引,因為索引已經排序,其指定的範圍是連續的;

(5)在經常需要排序的列上創建索引,因為索引已經排序,這樣查詢可以利用索引的排序,加快排序查詢時間;

(6)在經常使用在WHERE子句中的列上面創建索引,加快條件的判斷速度。

對於有些列不應該創建索引:

(1)對於那些在查詢中很少使用或者參考的列不應該創建索引。

這是因為,既然這些列很少使用到,因此有索引或者無索引,並不能提高查詢速度。相反,由於增加了索引,反而降低了系統的維護速度和增大了空間需求。

(2)對於那些只有很少數據值的列也不應該增加索引。

這是因為,由於這些列的取值很少,例如人事表的性別列,在查詢的結果中,結果集的數據行佔了表中數據行的很大比例,即需要在表中搜索的數據行的比例很大。增加索引,並不能明顯加快檢索速度。

(3)對於那些定義為text, image和bit數據類型的列不應該增加索引。

這是因為,這些列的數據量要麼相當大,要麼取值很少。

(4)當修改性能遠遠大於檢索性能時,不應該創建索引。

這是因為,修改性能和檢索性能是互相矛盾的。當增加索引時,會提高檢索性能,但是會降低修改性能。當減少索引時,會提高修改性能,降低檢索性能。因此,當修改性能遠遠大於檢索性能時,不應該創建索引。

史上最全面的數據庫常見筆試面試題(附含答案)中

5.什麼樣的字段適合建索引

唯一、不為空、經常被查詢的字段

6.MySQL B+Tree索引和Hash索引的區別?

Hash索引和B+樹索引的特點:

Hash索引結構的特殊性,其檢索效率非常高,索引的檢索可以一次定位;

B+樹索引需要從根節點到枝節點,最後才能訪問到頁節點這樣多次的IO訪問;

為什麼不都用Hash索引而使用B+樹索引?

Hash索引僅僅能滿足"=","IN"和""查詢,不能使用範圍查詢,因為經過相應的Hash算法處理之後的Hash值的大小關係,並不能保證和Hash運算前完全一樣;

Hash索引無法被用來避免數據的排序操作,因為Hash值的大小關係並不一定和Hash運算前的鍵值完全一樣;

Hash索引不能利用部分索引鍵查詢,對於組合索引,Hash索引在計算Hash值的時候是組合索引鍵合併後再一起計算Hash值,而不是單獨計算Hash值,所以通過組合索引的前面一個或幾個索引鍵進行查詢的時候,Hash索引也無法被利用;

Hash索引在任何時候都不能避免表掃描,由於不同索引鍵存在相同Hash值,所以即使取滿足某個Hash鍵值的數據的記錄條數,也無法從Hash索引中直接完成查詢,還是要回表查詢數據;

Hash索引遇到大量Hash值相等的情況後性能並不一定就會比B+樹索引高。

補充:

1.MySQL中,只有HEAP/MEMORY引擎才顯示支持Hash索引。

2.常用的InnoDB引擎中默認使用的是B+樹索引,它會實時監控表上索引的使用情況,如果認為建立哈希索引可以提高查詢效率,則自動在內存中的“自適應哈希索引緩衝區”建立哈希索引(在InnoDB中默認開啟自適應哈希索引),通過觀察搜索模式,MySQL會利用index key的前綴建立哈希索引,如果一個表幾乎大部分都在緩衝池中,那麼建立一個哈希索引能夠加快等值查詢。

B+樹索引和哈希索引的明顯區別是:

3.如果是等值查詢,那麼哈希索引明顯有絕對優勢,因為只需要經過一次算法即可找到相應的鍵值;當然了,這個前提是,鍵值都是唯一的。如果鍵值不是唯一的,就需要先找到該鍵所在位置,然後再根據鏈表往後掃描,直到找到相應的數據;

4.如果是範圍查詢檢索,這時候哈希索引就毫無用武之地了,因為原先是有序的鍵值,經過哈希算法後,有可能變成不連續的了,就沒辦法再利用索引完成範圍查詢檢索;

同理,哈希索引沒辦法利用索引完成排序,以及like ‘xxx%’ 這樣的部分模糊查詢(這種部分模糊查詢,其實本質上也是範圍查詢);

5.哈希索引也不支持多列聯合索引的最左匹配規則;

6.B+樹索引的關鍵字檢索效率比較平均,不像B樹那樣波動幅度大,在有大量重複鍵值情況下,哈希索引的效率也是極低的,因為存在所謂的哈希碰撞問題。

7.在大多數場景下,都會有範圍查詢、排序、分組等查詢特徵,用B+樹索引就可以了。

7.B樹和B+樹的區別

B樹,每個節點都存儲key和data,所有節點組成這棵樹,並且葉子節點指針為nul,葉子結點不包含任何關鍵字信息

B+樹,所有的葉子結點中包含了全部關鍵字的信息,及指向含有這些關鍵字記錄的指針,且葉子結點本身依關鍵字的大小自小而大的順序鏈接,所有的非終端結點可以看成是索引部分,結點中僅含有其子樹根結點中最大(或最小)關鍵字。(而B 樹的非終節點也包含需要查找的有效信息)

史上最全面的數據庫常見筆試面試題(附含答案)中

8.為什麼說B+比B樹更適合實際應用中操作系統的文件索引和數據庫索引?

1.B+的磁盤讀寫代價更低

B+的內部結點並沒有指向關鍵字具體信息的指針。因此其內部結點相對B樹更小。如果把所有同一內部結點的關鍵字存放在同一盤塊中,那麼盤塊所能容納的關鍵字數量也越多。一次性讀入內存中的需要查找的關鍵字也就越多。相對來說IO讀寫次數也就降低了。

2.B+tree的查詢效率更加穩定

由於非終結點並不是最終指向文件內容的結點,而只是葉子結點中關鍵字的索引。所以任何關鍵字的查找必須走一條從根結點到葉子結點的路。所有關鍵字查詢的路徑長度相同,導致每一個數據的查詢效率相當。

9.聚集索引和非聚集索引區別?

聚合索引(clustered index):

聚集索引表記錄的排列順序和索引的排列順序一致,所以查詢效率快,只要找到第一個索引值記錄,其餘就連續性的記錄在物理也一樣連續存放。聚集索引對應的缺點就是修改慢,因為為了保證表中記錄的物理和索引順序一致,在記錄插入的時候,會對數據頁重新排序。

聚集索引類似於新華字典中用拼音去查找漢字,拼音檢索表於書記順序都是按照a~z排列的,就像相同的邏輯順序於物理順序一樣,當你需要查找a,ai兩個讀音的字,或是想一次尋找多個傻(sha)的同音字時,也許向後翻幾頁,或緊接著下一行就得到結果了。

非聚合索引(nonclustered index):

非聚集索引指定了表中記錄的邏輯順序,但是記錄的物理和索引不一定一致,兩種索引都採用B+樹結構,非聚集索引的葉子層並不和實際數據頁相重疊,而採用葉子層包含一個指向表中的記錄在數據頁中的指針方式。非聚集索引層次多,不會造成數據重排。

非聚集索引類似在新華字典上通過偏旁部首來查詢漢字,檢索表也許是按照橫、豎、撇來排列的,但是由於正文中是a~z的拼音順序,所以就類似於邏輯地址於物理地址的不對應。同時適用的情況就在於分組,大數目的不同值,頻繁更新的列中,這些情況即不適合聚集索引。

根本區別:

聚集索引和非聚集索引的根本區別是表記錄的排列順序和與索引的排列順序是否一致。

史上最全面的數據庫常見筆試面試題(附含答案)中

三、事務

1.什麼是事務?

事務是對數據庫中一系列操作進行統一的回滾或者提交的操作,主要用來保證數據的完整性和一致性。

2.事務四大特性(ACID)原子性、一致性、隔離性、持久性?

原子性(Atomicity):

原子性是指事務包含的所有操作要麼全部成功,要麼全部失敗回滾,因此事務的操作如果成功就必須要完全應用到數據庫,如果操作失敗則不能對數據庫有任何影響。

一致性(Consistency):

事務開始前和結束後,數據庫的完整性約束沒有被破壞。比如A向B轉賬,不可能A扣了錢,B卻沒收到。

隔離性(Isolation):

隔離性是當多個用戶併發訪問數據庫時,比如操作同一張表時,數據庫為每一個用戶開啟的事務,不能被其他事務的操作所幹擾,多個併發事務之間要相互隔離。同一時間,只允許一個事務請求同一數據,不同的事務之間彼此沒有任何干擾。比如A正在從一張銀行卡中取錢,在A取錢的過程結束前,B不能向這張卡轉賬。

持久性(Durability):

持久性是指一個事務一旦被提交了,那麼對數據庫中的數據的改變就是永久性的,即便是在數據庫系統遇到故障的情況下也不會丟失提交事務的操作。

3.事務的併發?事務隔離級別,每個級別會引發什麼問題,MySQL默認是哪個級別?

從理論上來說, 事務應該彼此完全隔離, 以避免併發事務所導致的問題,然而, 那樣會對性能產生極大的影響, 因為事務必須按順序運行, 在實際開發中, 為了提升性能, 事務會以較低的隔離級別運行, 事務的隔離級別可以通過隔離事務屬性指定。

事務的併發問題

1、髒讀:事務A讀取了事務B更新的數據,然後B回滾操作,那麼A讀取到的數據是髒數據

2、不可重複讀:事務 A 多次讀取同一數據,事務 B 在事務A多次讀取的過程中,對數據作了更新並提交,導致事務A多次讀取同一數據時,結果因此本事務先後兩次讀到的數據結果會不一致。

3、幻讀:幻讀解決了不重複讀,保證了同一個事務裡,查詢的結果都是事務開始時的狀態(一致性)。

例如:事務T1對一個表中所有的行的某個數據項做了從“1”修改為“2”的操作 這時事務T2又對這個表中插入了一行數據項,而這個數據項的數值還是為“1”並且提交給數據庫。而操作事務T1的用戶如果再查看剛剛修改的數據,會發現還有跟沒有修改一樣,其實這行是從事務T2中添加的,就好像產生幻覺一樣,這就是發生了幻讀。

小結:不可重複讀的和幻讀很容易混淆,不可重複讀側重於修改,幻讀側重於新增或刪除。解決不可重複讀的問題只需鎖住滿足條件的行,解決幻讀需要鎖表。

事務的隔離級別

讀未提交:另一個事務修改了數據,但尚未提交,而本事務中的SELECT會讀到這些未被提交的數據髒讀

不可重複讀:事務 A 多次讀取同一數據,事務 B 在事務A多次讀取的過程中,對數據作了更新並提交,導致事務A多次讀取同一數據時,結果因此本事務先後兩次讀到的數據結果會不一致。

可重複讀:在同一個事務裡,SELECT的結果是事務開始時時間點的狀態,因此,同樣的SELECT操作讀到的結果會是一致的。但是,會有幻讀現象

串行化:最高的隔離級別,在這個隔離級別下,不會產生任何異常。併發的事務,就像事務是在一個個按照順序執行一樣

史上最全面的數據庫常見筆試面試題(附含答案)中

4.事務傳播行為

1.PROPAGATION_REQUIRED:如果當前沒有事務,就創建一個新事務,如果當前存在事務,就加入該事務,該設置是最常用的設置。

2.PROPAGATION_SUPPORTS:支持當前事務,如果當前存在事務,就加入該事務,如果當前不存在事務,就以非事務執行。

3.PROPAGATION_MANDATORY:支持當前事務,如果當前存在事務,就加入該事務,如果當前不存在事務,就拋出異常。

4.PROPAGATION_REQUIRES_NEW:創建新事務,無論當前存不存在事務,都創建新事務。

5.PROPAGATION_NOT_SUPPORTED:以非事務方式執行操作,如果當前存在事務,就把當前事務掛起。

6.PROPAGATION_NEVER:以非事務方式執行,如果當前存在事務,則拋出異常。

7.PROPAGATION_NESTED:如果當前存在事務,則在嵌套事務內執行。如果當前沒有事務,則執行與PROPAGATION_REQUIRED類似的操作。

5.嵌套事務

嵌套是子事務套在父事務中執行,子事務是父事務的一部分,在進入子事務之前,父事務建立一個回滾點,叫save point,然後執行子事務,這個子事務的執行也算是父事務的一部分,然後子事務執行結束,父事務繼續執行。重點就在於那個save point。看幾個問題就明瞭了:

如果子事務回滾,會發生什麼?

父事務會回滾到進入子事務前建立的save point,然後嘗試其他的事務或者其他的業務邏輯,父事務之前的操作不會受到影響,更不會自動回滾。

如果父事務回滾,會發生什麼?

父事務回滾,子事務也會跟著回滾!為什麼呢,因為父事務結束之前,子事務是不會提交的,我們說子事務是父事務的一部分,正是這個道理。那麼:

事務的提交,是什麼情況?

是父事務先提交,然後子事務提交,還是子事務先提交,父事務再提交?答案是第二種情況,還是那句話,子事務是父事務的一部分,由父事務統一提交。

史上最全面的數據庫常見筆試面試題(附含答案)中

四、存儲引擎

1.MySQL常見的三種存儲引擎(InnoDB、MyISAM、MEMORY)的區別?

兩種存儲引擎的大致區別表現在:

1.InnoDB支持事務,MyISAM不支持, 這一點是非常之重要。事務是一種高級的處理方式,如在一些列增刪改中只要哪個出錯還可以回滾還原,而MyISAM就不可以了。

2.MyISAM適合查詢以及插入為主的應用。

3.InnoDB適合頻繁修改以及涉及到安全性較高的應用。

4.InnoDB支持外鍵,MyISAM不支持。

5.從MySQL5.5.5以後,InnoDB是默認引擎。

6.InnoDB不支持FULLTEXT類型的索引。

7.InnoDB中不保存表的行數,如select count() from table時,InnoDB需要掃描一遍整個表來計算有多少行,但是MyISAM只要簡單的讀出保存好的行數即可。注意的是,當count()語句包含where條件時MyISAM也需要掃描整個表。

8.對於自增長的字段,InnoDB中必須包含只有該字段的索引,但是在MyISAM表中可以和其他字段一起建立聯合索引。

9.DELETE FROM table時,InnoDB不會重新建立表,而是一行一行的 刪除,效率非常慢。MyISAM則會重建表。

10.InnoDB支持行鎖(某些情況下還是鎖整表,如 update table set a=1 where user like '%lee%'。

2.MySQL存儲引擎MyISAM與InnoDB如何選擇

MySQL有多種存儲引擎,每種存儲引擎有各自的優缺點,可以擇優選擇使用:MyISAM、InnoDB、MERGE、MEMORY(HEAP)、BDB(BerkeleyDB)、EXAMPLE、FEDERATED、ARCHIVE、CSV、BLACKHOLE。

雖然MySQL裡的存儲引擎不只是MyISAM與InnoDB這兩個,但常用的就是兩個。

關於MySQL數據庫提供的兩種存儲引擎,MyISAM與InnoDB選擇使用:

1.INNODB會支持一些關係數據庫的高級功能,如事務功能和行級鎖,MyISAM不支持。

2.MyISAM的性能更優,佔用的存儲空間少,所以,選擇何種存儲引擎,視具體應用而定。

如果你的應用程序一定要使用事務,毫無疑問你要選擇INNODB引擎。但要注意,INNODB的行級鎖是有條件的。在where條件沒有使用主鍵時,照樣會鎖全表。比如DELETE FROM mytable這樣的刪除語句。

如果你的應用程序對查詢性能要求較高,就要使用MyISAM了。MyISAM索引和數據是分開的,而且其索引是壓縮的,可以更好地利用內存。所以它的查詢性能明顯優於INNODB。壓縮後的索引也能節約一些磁盤空間。MyISAM擁有全文索引的功能,這可以極大地優化LIKE查詢的效率。

有人說MyISAM只能用於小型應用,其實這只是一種偏見。如果數據量比較大,這是需要通過升級架構來解決,比如分表分庫,而不是單純地依賴存儲引擎。

現在一般都是選用innodb了,主要是MyISAM的全表鎖,讀寫串行問題,併發效率鎖表,效率低,MyISAM對於讀寫密集型應用一般是不會去選用的。

MEMORY存儲引擎

MEMORY是MySQL中一類特殊的存儲引擎。它使用存儲在內存中的內容來創建表,而且數據全部放在內存中。這些特性與前面的兩個很不同。

每個基於MEMORY存儲引擎的表實際對應一個磁盤文件。該文件的文件名與表名相同,類型為frm類型。該文件中只存儲表的結構。而其數據文件,都是存儲在內存中,這樣有利於數據的快速處理,提高整個表的效率。值得注意的是,服務器需要有足夠的內存來維持MEMORY存儲引擎的表的使用。如果不需要了,可以釋放內存,甚至刪除不需要的表。

MEMORY默認使用哈希索引。速度比使用B型樹索引快。當然如果你想用B型樹索引,可以在創建索引時指定。

"

本文是銜接上文的,內容較多,建議收藏閱讀。

二、索引

1.什麼是索引?

何為索引:

數據庫索引,是數據庫管理系統中一個排序的數據結構,索引的實現通常使用B樹及其變種B+樹。

在數據之外,數據庫系統還維護著滿足特定查找算法的數據結構,這些數據結構以某種方式引用(指向)數據,這樣就可以在這些數據結構上實現高級查找算法。這種數據結構,就是索引。

史上最全面的數據庫常見筆試面試題(附含答案)中

2.索引的作用?它的優點缺點是什麼?

索引作用:

協助快速查詢、更新數據庫表中數據。

為表設置索引要付出代價的:

一是增加了數據庫的存儲空間

二是在插入和修改數據時要花費較多的時間(因為索引也要隨之變動)。

3.索引的優缺點?

創建索引可以大大提高系統的性能( 優點 ):

1.通過創建唯一性索引,可以保證數據庫表中每一行數據的唯一性。

2.可以大大加快數據的檢索速度,這也是創建索引的最主要的原因。

3.可以加速表和表之間的連接,特別是在實現數據的參考完整性方面特別有意義。

4.在使用分組和排序子句進行數據檢索時,同樣可以顯著減少查詢中分組和排序的時間。

5.通過使用索引,可以在查詢的過程中,使用優化隱藏器,提高系統的性能。

增加索引也有許多不利的方面( 缺點 ):

1.創建索引和維護索引要耗費時間,這種時間隨著數據量的增加而增加。

2.索引需要佔物理空間,除了數據表佔數據空間之外,每一個索引還要佔一定的物理空間,如果要建立聚簇索引,那麼需要的空間就會更大。

3.當對錶中的數據進行增加、刪除和修改的時候,索引也要動態的維護,這樣就降低了數據的維護速度。

4.哪些列適合建立索引、哪些不適合建索引?

索引是建立在數據庫表中的某些列的上面。在創建索引的時候,應該考慮在哪些列上可以創建索引,在哪些列上不能創建索引。

一般來說,應該在這些列上創建索引:

(1)在經常需要搜索的列上,可以加快搜索的速度;

(2)在作為主鍵的列上,強制該列的唯一性和組織表中數據的排列結構;

(3)在經常用在連接的列上,這些列主要是一些外鍵,可以加快連接的速度;

(4)在經常需要根據範圍進行搜索的列上創建索引,因為索引已經排序,其指定的範圍是連續的;

(5)在經常需要排序的列上創建索引,因為索引已經排序,這樣查詢可以利用索引的排序,加快排序查詢時間;

(6)在經常使用在WHERE子句中的列上面創建索引,加快條件的判斷速度。

對於有些列不應該創建索引:

(1)對於那些在查詢中很少使用或者參考的列不應該創建索引。

這是因為,既然這些列很少使用到,因此有索引或者無索引,並不能提高查詢速度。相反,由於增加了索引,反而降低了系統的維護速度和增大了空間需求。

(2)對於那些只有很少數據值的列也不應該增加索引。

這是因為,由於這些列的取值很少,例如人事表的性別列,在查詢的結果中,結果集的數據行佔了表中數據行的很大比例,即需要在表中搜索的數據行的比例很大。增加索引,並不能明顯加快檢索速度。

(3)對於那些定義為text, image和bit數據類型的列不應該增加索引。

這是因為,這些列的數據量要麼相當大,要麼取值很少。

(4)當修改性能遠遠大於檢索性能時,不應該創建索引。

這是因為,修改性能和檢索性能是互相矛盾的。當增加索引時,會提高檢索性能,但是會降低修改性能。當減少索引時,會提高修改性能,降低檢索性能。因此,當修改性能遠遠大於檢索性能時,不應該創建索引。

史上最全面的數據庫常見筆試面試題(附含答案)中

5.什麼樣的字段適合建索引

唯一、不為空、經常被查詢的字段

6.MySQL B+Tree索引和Hash索引的區別?

Hash索引和B+樹索引的特點:

Hash索引結構的特殊性,其檢索效率非常高,索引的檢索可以一次定位;

B+樹索引需要從根節點到枝節點,最後才能訪問到頁節點這樣多次的IO訪問;

為什麼不都用Hash索引而使用B+樹索引?

Hash索引僅僅能滿足"=","IN"和""查詢,不能使用範圍查詢,因為經過相應的Hash算法處理之後的Hash值的大小關係,並不能保證和Hash運算前完全一樣;

Hash索引無法被用來避免數據的排序操作,因為Hash值的大小關係並不一定和Hash運算前的鍵值完全一樣;

Hash索引不能利用部分索引鍵查詢,對於組合索引,Hash索引在計算Hash值的時候是組合索引鍵合併後再一起計算Hash值,而不是單獨計算Hash值,所以通過組合索引的前面一個或幾個索引鍵進行查詢的時候,Hash索引也無法被利用;

Hash索引在任何時候都不能避免表掃描,由於不同索引鍵存在相同Hash值,所以即使取滿足某個Hash鍵值的數據的記錄條數,也無法從Hash索引中直接完成查詢,還是要回表查詢數據;

Hash索引遇到大量Hash值相等的情況後性能並不一定就會比B+樹索引高。

補充:

1.MySQL中,只有HEAP/MEMORY引擎才顯示支持Hash索引。

2.常用的InnoDB引擎中默認使用的是B+樹索引,它會實時監控表上索引的使用情況,如果認為建立哈希索引可以提高查詢效率,則自動在內存中的“自適應哈希索引緩衝區”建立哈希索引(在InnoDB中默認開啟自適應哈希索引),通過觀察搜索模式,MySQL會利用index key的前綴建立哈希索引,如果一個表幾乎大部分都在緩衝池中,那麼建立一個哈希索引能夠加快等值查詢。

B+樹索引和哈希索引的明顯區別是:

3.如果是等值查詢,那麼哈希索引明顯有絕對優勢,因為只需要經過一次算法即可找到相應的鍵值;當然了,這個前提是,鍵值都是唯一的。如果鍵值不是唯一的,就需要先找到該鍵所在位置,然後再根據鏈表往後掃描,直到找到相應的數據;

4.如果是範圍查詢檢索,這時候哈希索引就毫無用武之地了,因為原先是有序的鍵值,經過哈希算法後,有可能變成不連續的了,就沒辦法再利用索引完成範圍查詢檢索;

同理,哈希索引沒辦法利用索引完成排序,以及like ‘xxx%’ 這樣的部分模糊查詢(這種部分模糊查詢,其實本質上也是範圍查詢);

5.哈希索引也不支持多列聯合索引的最左匹配規則;

6.B+樹索引的關鍵字檢索效率比較平均,不像B樹那樣波動幅度大,在有大量重複鍵值情況下,哈希索引的效率也是極低的,因為存在所謂的哈希碰撞問題。

7.在大多數場景下,都會有範圍查詢、排序、分組等查詢特徵,用B+樹索引就可以了。

7.B樹和B+樹的區別

B樹,每個節點都存儲key和data,所有節點組成這棵樹,並且葉子節點指針為nul,葉子結點不包含任何關鍵字信息

B+樹,所有的葉子結點中包含了全部關鍵字的信息,及指向含有這些關鍵字記錄的指針,且葉子結點本身依關鍵字的大小自小而大的順序鏈接,所有的非終端結點可以看成是索引部分,結點中僅含有其子樹根結點中最大(或最小)關鍵字。(而B 樹的非終節點也包含需要查找的有效信息)

史上最全面的數據庫常見筆試面試題(附含答案)中

8.為什麼說B+比B樹更適合實際應用中操作系統的文件索引和數據庫索引?

1.B+的磁盤讀寫代價更低

B+的內部結點並沒有指向關鍵字具體信息的指針。因此其內部結點相對B樹更小。如果把所有同一內部結點的關鍵字存放在同一盤塊中,那麼盤塊所能容納的關鍵字數量也越多。一次性讀入內存中的需要查找的關鍵字也就越多。相對來說IO讀寫次數也就降低了。

2.B+tree的查詢效率更加穩定

由於非終結點並不是最終指向文件內容的結點,而只是葉子結點中關鍵字的索引。所以任何關鍵字的查找必須走一條從根結點到葉子結點的路。所有關鍵字查詢的路徑長度相同,導致每一個數據的查詢效率相當。

9.聚集索引和非聚集索引區別?

聚合索引(clustered index):

聚集索引表記錄的排列順序和索引的排列順序一致,所以查詢效率快,只要找到第一個索引值記錄,其餘就連續性的記錄在物理也一樣連續存放。聚集索引對應的缺點就是修改慢,因為為了保證表中記錄的物理和索引順序一致,在記錄插入的時候,會對數據頁重新排序。

聚集索引類似於新華字典中用拼音去查找漢字,拼音檢索表於書記順序都是按照a~z排列的,就像相同的邏輯順序於物理順序一樣,當你需要查找a,ai兩個讀音的字,或是想一次尋找多個傻(sha)的同音字時,也許向後翻幾頁,或緊接著下一行就得到結果了。

非聚合索引(nonclustered index):

非聚集索引指定了表中記錄的邏輯順序,但是記錄的物理和索引不一定一致,兩種索引都採用B+樹結構,非聚集索引的葉子層並不和實際數據頁相重疊,而採用葉子層包含一個指向表中的記錄在數據頁中的指針方式。非聚集索引層次多,不會造成數據重排。

非聚集索引類似在新華字典上通過偏旁部首來查詢漢字,檢索表也許是按照橫、豎、撇來排列的,但是由於正文中是a~z的拼音順序,所以就類似於邏輯地址於物理地址的不對應。同時適用的情況就在於分組,大數目的不同值,頻繁更新的列中,這些情況即不適合聚集索引。

根本區別:

聚集索引和非聚集索引的根本區別是表記錄的排列順序和與索引的排列順序是否一致。

史上最全面的數據庫常見筆試面試題(附含答案)中

三、事務

1.什麼是事務?

事務是對數據庫中一系列操作進行統一的回滾或者提交的操作,主要用來保證數據的完整性和一致性。

2.事務四大特性(ACID)原子性、一致性、隔離性、持久性?

原子性(Atomicity):

原子性是指事務包含的所有操作要麼全部成功,要麼全部失敗回滾,因此事務的操作如果成功就必須要完全應用到數據庫,如果操作失敗則不能對數據庫有任何影響。

一致性(Consistency):

事務開始前和結束後,數據庫的完整性約束沒有被破壞。比如A向B轉賬,不可能A扣了錢,B卻沒收到。

隔離性(Isolation):

隔離性是當多個用戶併發訪問數據庫時,比如操作同一張表時,數據庫為每一個用戶開啟的事務,不能被其他事務的操作所幹擾,多個併發事務之間要相互隔離。同一時間,只允許一個事務請求同一數據,不同的事務之間彼此沒有任何干擾。比如A正在從一張銀行卡中取錢,在A取錢的過程結束前,B不能向這張卡轉賬。

持久性(Durability):

持久性是指一個事務一旦被提交了,那麼對數據庫中的數據的改變就是永久性的,即便是在數據庫系統遇到故障的情況下也不會丟失提交事務的操作。

3.事務的併發?事務隔離級別,每個級別會引發什麼問題,MySQL默認是哪個級別?

從理論上來說, 事務應該彼此完全隔離, 以避免併發事務所導致的問題,然而, 那樣會對性能產生極大的影響, 因為事務必須按順序運行, 在實際開發中, 為了提升性能, 事務會以較低的隔離級別運行, 事務的隔離級別可以通過隔離事務屬性指定。

事務的併發問題

1、髒讀:事務A讀取了事務B更新的數據,然後B回滾操作,那麼A讀取到的數據是髒數據

2、不可重複讀:事務 A 多次讀取同一數據,事務 B 在事務A多次讀取的過程中,對數據作了更新並提交,導致事務A多次讀取同一數據時,結果因此本事務先後兩次讀到的數據結果會不一致。

3、幻讀:幻讀解決了不重複讀,保證了同一個事務裡,查詢的結果都是事務開始時的狀態(一致性)。

例如:事務T1對一個表中所有的行的某個數據項做了從“1”修改為“2”的操作 這時事務T2又對這個表中插入了一行數據項,而這個數據項的數值還是為“1”並且提交給數據庫。而操作事務T1的用戶如果再查看剛剛修改的數據,會發現還有跟沒有修改一樣,其實這行是從事務T2中添加的,就好像產生幻覺一樣,這就是發生了幻讀。

小結:不可重複讀的和幻讀很容易混淆,不可重複讀側重於修改,幻讀側重於新增或刪除。解決不可重複讀的問題只需鎖住滿足條件的行,解決幻讀需要鎖表。

事務的隔離級別

讀未提交:另一個事務修改了數據,但尚未提交,而本事務中的SELECT會讀到這些未被提交的數據髒讀

不可重複讀:事務 A 多次讀取同一數據,事務 B 在事務A多次讀取的過程中,對數據作了更新並提交,導致事務A多次讀取同一數據時,結果因此本事務先後兩次讀到的數據結果會不一致。

可重複讀:在同一個事務裡,SELECT的結果是事務開始時時間點的狀態,因此,同樣的SELECT操作讀到的結果會是一致的。但是,會有幻讀現象

串行化:最高的隔離級別,在這個隔離級別下,不會產生任何異常。併發的事務,就像事務是在一個個按照順序執行一樣

史上最全面的數據庫常見筆試面試題(附含答案)中

4.事務傳播行為

1.PROPAGATION_REQUIRED:如果當前沒有事務,就創建一個新事務,如果當前存在事務,就加入該事務,該設置是最常用的設置。

2.PROPAGATION_SUPPORTS:支持當前事務,如果當前存在事務,就加入該事務,如果當前不存在事務,就以非事務執行。

3.PROPAGATION_MANDATORY:支持當前事務,如果當前存在事務,就加入該事務,如果當前不存在事務,就拋出異常。

4.PROPAGATION_REQUIRES_NEW:創建新事務,無論當前存不存在事務,都創建新事務。

5.PROPAGATION_NOT_SUPPORTED:以非事務方式執行操作,如果當前存在事務,就把當前事務掛起。

6.PROPAGATION_NEVER:以非事務方式執行,如果當前存在事務,則拋出異常。

7.PROPAGATION_NESTED:如果當前存在事務,則在嵌套事務內執行。如果當前沒有事務,則執行與PROPAGATION_REQUIRED類似的操作。

5.嵌套事務

嵌套是子事務套在父事務中執行,子事務是父事務的一部分,在進入子事務之前,父事務建立一個回滾點,叫save point,然後執行子事務,這個子事務的執行也算是父事務的一部分,然後子事務執行結束,父事務繼續執行。重點就在於那個save point。看幾個問題就明瞭了:

如果子事務回滾,會發生什麼?

父事務會回滾到進入子事務前建立的save point,然後嘗試其他的事務或者其他的業務邏輯,父事務之前的操作不會受到影響,更不會自動回滾。

如果父事務回滾,會發生什麼?

父事務回滾,子事務也會跟著回滾!為什麼呢,因為父事務結束之前,子事務是不會提交的,我們說子事務是父事務的一部分,正是這個道理。那麼:

事務的提交,是什麼情況?

是父事務先提交,然後子事務提交,還是子事務先提交,父事務再提交?答案是第二種情況,還是那句話,子事務是父事務的一部分,由父事務統一提交。

史上最全面的數據庫常見筆試面試題(附含答案)中

四、存儲引擎

1.MySQL常見的三種存儲引擎(InnoDB、MyISAM、MEMORY)的區別?

兩種存儲引擎的大致區別表現在:

1.InnoDB支持事務,MyISAM不支持, 這一點是非常之重要。事務是一種高級的處理方式,如在一些列增刪改中只要哪個出錯還可以回滾還原,而MyISAM就不可以了。

2.MyISAM適合查詢以及插入為主的應用。

3.InnoDB適合頻繁修改以及涉及到安全性較高的應用。

4.InnoDB支持外鍵,MyISAM不支持。

5.從MySQL5.5.5以後,InnoDB是默認引擎。

6.InnoDB不支持FULLTEXT類型的索引。

7.InnoDB中不保存表的行數,如select count() from table時,InnoDB需要掃描一遍整個表來計算有多少行,但是MyISAM只要簡單的讀出保存好的行數即可。注意的是,當count()語句包含where條件時MyISAM也需要掃描整個表。

8.對於自增長的字段,InnoDB中必須包含只有該字段的索引,但是在MyISAM表中可以和其他字段一起建立聯合索引。

9.DELETE FROM table時,InnoDB不會重新建立表,而是一行一行的 刪除,效率非常慢。MyISAM則會重建表。

10.InnoDB支持行鎖(某些情況下還是鎖整表,如 update table set a=1 where user like '%lee%'。

2.MySQL存儲引擎MyISAM與InnoDB如何選擇

MySQL有多種存儲引擎,每種存儲引擎有各自的優缺點,可以擇優選擇使用:MyISAM、InnoDB、MERGE、MEMORY(HEAP)、BDB(BerkeleyDB)、EXAMPLE、FEDERATED、ARCHIVE、CSV、BLACKHOLE。

雖然MySQL裡的存儲引擎不只是MyISAM與InnoDB這兩個,但常用的就是兩個。

關於MySQL數據庫提供的兩種存儲引擎,MyISAM與InnoDB選擇使用:

1.INNODB會支持一些關係數據庫的高級功能,如事務功能和行級鎖,MyISAM不支持。

2.MyISAM的性能更優,佔用的存儲空間少,所以,選擇何種存儲引擎,視具體應用而定。

如果你的應用程序一定要使用事務,毫無疑問你要選擇INNODB引擎。但要注意,INNODB的行級鎖是有條件的。在where條件沒有使用主鍵時,照樣會鎖全表。比如DELETE FROM mytable這樣的刪除語句。

如果你的應用程序對查詢性能要求較高,就要使用MyISAM了。MyISAM索引和數據是分開的,而且其索引是壓縮的,可以更好地利用內存。所以它的查詢性能明顯優於INNODB。壓縮後的索引也能節約一些磁盤空間。MyISAM擁有全文索引的功能,這可以極大地優化LIKE查詢的效率。

有人說MyISAM只能用於小型應用,其實這只是一種偏見。如果數據量比較大,這是需要通過升級架構來解決,比如分表分庫,而不是單純地依賴存儲引擎。

現在一般都是選用innodb了,主要是MyISAM的全表鎖,讀寫串行問題,併發效率鎖表,效率低,MyISAM對於讀寫密集型應用一般是不會去選用的。

MEMORY存儲引擎

MEMORY是MySQL中一類特殊的存儲引擎。它使用存儲在內存中的內容來創建表,而且數據全部放在內存中。這些特性與前面的兩個很不同。

每個基於MEMORY存儲引擎的表實際對應一個磁盤文件。該文件的文件名與表名相同,類型為frm類型。該文件中只存儲表的結構。而其數據文件,都是存儲在內存中,這樣有利於數據的快速處理,提高整個表的效率。值得注意的是,服務器需要有足夠的內存來維持MEMORY存儲引擎的表的使用。如果不需要了,可以釋放內存,甚至刪除不需要的表。

MEMORY默認使用哈希索引。速度比使用B型樹索引快。當然如果你想用B型樹索引,可以在創建索引時指定。

史上最全面的數據庫常見筆試面試題(附含答案)中

3.MySQL的MyISAM與InnoDB兩種存儲引擎在,事務、鎖級別,各自的適用場景?

事務處理上方面

MyISAM:強調的是性能,每次查詢具有原子性,其執行數度比InnoDB類型更快,但是不提供事務支持。

InnoDB:提供事務支持事務,外部鍵等高級數據庫功能。具有事務(commit)、回滾(rollback)和崩潰修復能力(crash recovery capabilities)的事務安全(transaction-safe (ACID compliant))型表。

鎖級別

MyISAM:只支持表級鎖,用戶在操作MyISAM表時,select,update,delete,insert語句都會給表自動加鎖,如果加鎖以後的表滿足insert併發的情況下,可以在表的尾部插入新的數據。

InnoDB:支持事務和行級鎖,是innodb的最大特色。行鎖大幅度提高了多用戶併發操作的新能。但是InnoDB的行鎖,只是在WHERE的主鍵是有效的,非主鍵的WHERE都會鎖全表的。

剩餘的內容在下文哦。記得關注小編。

"

相關推薦

推薦中...