数据库面试基础知识
數據庫面試基礎知識
- 一、數據庫基礎
- 1.關系型非關系型數據的區別
- 2.什么是非關型數據庫
- 3.數據庫的索引類型
- 4.數據庫的事務是怎么實現的?
- 5.數據庫中事務的ACID(四大特性都要能夠舉例說明,理解透徹,比如原子性和一致性的關聯,隔離性不好會出現的問題)
- 6.臟讀、不可重復讀、幻讀
- 7.數據庫的隔離級別,mysql和Oracle的隔離級別分別是什么(重點)
- 8.數據庫的三大范式
- 9.數據庫的鎖的種類,加鎖的方式
- 10.什么是共享鎖和排他鎖
- 11.樂觀鎖與悲觀鎖
- 二、MySQL
- 1.說一下MySQL執行一條查詢語句的內部執行過程?
- 2.MySQL的優化(高頻)
- 3.MySQL數據庫引擎介紹,innodb和myisam的特點和區別
- 三、索引
- 1.索引的優缺點,什么時候使用索引,什么時候不能使用索引(重點)
- 2.索引的低層實現(重點)
- 3.B樹和B+樹二點區別(重點)
- 4.索引最左前綴/最左匹配
- 5.各種樹形結構
一、數據庫基礎
1.關系型非關系型數據的區別
關系型數據庫的優點:
容易理解。因為它采用了關系模型來組織數據。
可以保持數據的一致性。
數據更新的開銷比較小。
支持復雜查詢(帶where子句的查詢)
非關系數據庫的優點
不需要經過sql層的解析,讀寫效率高;
基于鍵值對,數據的擴展性好;
可以支持多種類型數據的存儲,如圖片,文檔等。
2.什么是非關型數據庫
非關系型的數據庫也叫nosql,采用鍵值對的形式進行存儲。讀寫性能很高,易于擴展。如:Redis,Mongodb,hbase等等。
適合非關系型數據庫的場景:
日志系統;
地理位置存儲;
數據量大;
高可用
3.數據庫的索引類型
數據庫的索引類型可以分為邏輯分類 和 物理分類
邏輯分類:
主鍵索引:當關系表中定義主鍵時會自主創建主鍵索引。每張表的主鍵索引只能有一個,要求主鍵中的每一個值都唯一,即不可重復,也不能有空值。
唯一索引:數據列不能有重復,可以有空值。一張表可以有多個唯一索引,但每個唯一索引只能有一列。如身份證號,卡號。
普通索引:一張表可以有多個普通索引,可以重復可以為空值。
全文索引:可以加快模糊查詢,不常用。
物理分類
聚集索引(聚簇索引):數據在物理存儲中的順序跟索引中數據的邏輯順序相同,比如以ID建立聚集索引,數據庫中id從小到大排列,那么物理存儲中該數據的內存地址值也按照從小到大存儲。一般是表中的主鍵索引,如果沒有主鍵索引就會以第一個非空的唯一索引作為聚集索引。一張表只能有一個聚集索引。
非聚集索引:數據在物理存儲中的順序跟索引中數據的邏輯順序不同。非聚集索引因為無法定位數據所在的行,所以需要掃描兩遍索引樹。第一遍掃描非聚集索引的索引樹,確定該數據的主鍵ID,然后到主鍵索引(聚集索引)中尋找相應的數據。
4.數據庫的事務是怎么實現的?
事務是一組邏輯操作的集合。實現事務就是要保證可靠性和并發隔離(ACID)。這些主要靠日志恢復和并發控制完成的。
日志恢復:數據庫里有兩個日志,一個是redo log,一個是undo log。redo log記錄的是已經成功提交的事務操作信息,用來恢復數據,保證事務的持久性。undo log記錄的是事務修改之前的數據信息,用來回滾數據,保證事務的原子性。
并發控制:并發控制主要靠讀寫鎖和MVCC(多版本并發控制)來實現。讀寫鎖包括共享鎖和排他鎖,保證事務的隔離性。MVCC通過為數據添加時間戳來實現。
5.數據庫中事務的ACID(四大特性都要能夠舉例說明,理解透徹,比如原子性和一致性的關聯,隔離性不好會出現的問題)
數據庫事務是指邏輯上對數據的一種操作,這個事務要么全部成功,要么全部失敗
A:atom 原子性
事務是一個不可分割的工作單位,這組操作要么全部發生,要么全部不發生。
C:consistency 一致性
數據庫事務的一致性是指:在事務開始以前,數據庫的數據有一個一致的狀態。在事務完成以后,數據庫中的事務也應該保持這種一致性。事務應該將數據從一個一致性狀態轉移到另一個一致性狀態。如:在銀行轉賬操作前后兩個賬戶的總額應當不變。
I:isolation 隔離性
數據庫事務的隔離性要求數據庫中的事務不會受另一個開發執行的事務的影響,對于數據庫中同時執行的每個事務來說,其他事務要么還沒開始執行,要么已經執行結束。
D:durability 持久性
數據庫事務的持久性要求書屋對數據庫的改變時永久的,哪怕數據庫發生損壞都不會影響到已發生的事務。
如果事務沒有完成,數據庫因故斷電了,那么重啟后也應該是沒有執行事務的狀態,如果事務已經完成后數據庫斷電了,那么重啟后就應該是事務執行完成后的狀態。
6.臟讀、不可重復讀、幻讀
臟讀: 一個事務在處理過程中讀取了另外一個還沒提交的事務的數據。
不可重復讀:對于數據庫的某一個字段,一個事務多次拆線呢卻返回了不同的值,只是由于早查詢的間隔中,該字段被其他事務修改并提交了。
幻讀:事務多次讀取同一個范圍的時候,查詢結果的記錄數不一樣,這是由于在查詢的間隔中,另一個事務新增或刪除了數據。
避免不可重復讀需要鎖行,避免幻讀則需要鎖表。
7.數據庫的隔離級別,mysql和Oracle的隔離級別分別是什么(重點)
為了保證數據庫事務一致性,解決臟讀,不可重復讀和幻讀的問題,數據庫的隔離級別一共有四種隔離級別:
讀未提交 Read Uncommitted: 最低級別的隔離,不能解決以上問題
讀已提交 Read committed: 可以避免臟讀的發生
可重復讀 Reapeatable read: 確保事務可以多次從一個字段中讀取相同的值,在該事務執行期間,禁止其他事務對此字段的更新,可以避免臟讀和不可重復讀。 通過鎖行來實現
串行化 Serializaion 最嚴格的事務隔離機制,要求所有事務被串行執行,可以避免以上所有問題。 通過鎖表來實現
Oracle的默認隔離級別是讀已提交,實現了四種隔離級別中的讀已提交和串行化隔離級別
MySQL的默認隔離級別是可重復讀,并且實現了所有四種隔離級別
8.數據庫的三大范式
第一范式(確保每列保持原子性)
第一范式是最基本的范式。如果數據庫表中的所有字段值都是不可分解的原子值,就說明該數據庫表滿足了第一范式。
第二范式(確保表中的每列都和主鍵相關)
在滿足第一范式的前提下,(主要針對聯合主鍵而言)第二范式需要確保數據庫表中的每一列都和主鍵的所有成員直接相關,由整個主鍵才能唯一確定,而不能只與主鍵的某一部分相關或者不相關。
第三范式(確保非主鍵的列沒有傳遞依賴)
在滿足第二范式的前提下,第三范式需要確保數據表中的每一列數據都和主鍵直接相關,而不能間接相關。非主鍵的列不能確定其他列,列與列之間不能出現傳遞依賴。
BCNF范式(確保主鍵之間沒有傳遞依賴)
主鍵有可能是由多個屬性組合成的復合主鍵,那么多個主鍵之間不能有傳遞依賴。也就是復合主鍵之間誰也不能決定誰,相互之間沒有關系。
9.數據庫的鎖的種類,加鎖的方式
以MySQL為例
按照類型來分有樂觀鎖和悲觀鎖
根據粒度來分有行級鎖,頁級鎖,表級鎖(粒度一個比一個大) (僅BDB,Berkeley Database支持頁級鎖)
根據作用來分有共享鎖(讀鎖)和排他鎖(寫鎖)
10.什么是共享鎖和排他鎖
共享鎖是讀操作的時候創建的鎖,一個事務對數據加上共享鎖之后,其他事務只能對數據再加共享鎖,不能進行寫操作直到釋放所有共享鎖。
排他鎖是寫操作時創建的鎖,事務對數據加上排他鎖之后其他任何事務都不能對數據加任何的鎖(即其他事務不能再訪問該數據)
11.樂觀鎖與悲觀鎖
一般的數據庫都會支持并發操作,在并發操作中為了避免數據沖突,所以需要對數據上鎖,樂觀鎖和悲觀鎖就是兩種不同的上鎖方式。
悲觀鎖假設數據在并發操作中一定會發生沖突,所以在數據開始讀取的時候就把數據鎖住。而樂觀鎖則假設數據一般情況下不會發生沖突,所以在數據提交更新的時候,才會檢測數據是否有沖突。
悲觀鎖的實現:悲觀鎖有行級鎖和頁級鎖兩種形式。行級鎖對正在使用的單條數據進行鎖定,事務完成后釋放該行數據,而頁級鎖則對整張表進行鎖定,事務正在對該表進行訪問的時候不允許其他事務并行訪問。
悲觀鎖要求在整個過程中一直與數據庫有一條連接,因為上一個事務完成后才能讓下一個事務執行,這個過程是串行的。
樂觀鎖有三種常用的實現形式:
一種是在執行事務時把整個數據都拷貝到應用中,在數據更新提交的時候比較數據庫中的數據與新數據,如果兩個數據一摸一樣則表示沒有沖突可以直接提交,如果有沖突就要交給業務邏輯去解決。
一種是使用版本戳來對數據進行標記,數據每發生一次修改,版本號就增加1。某條數據在提交的時候,如果數據庫中的版本號與自己的一致,就說明數據沒有發生修改,否則就認為是過期數據需要處理。
最后一種采用時間戳對數據最后修改的時間進行標記。
二、MySQL
1.說一下MySQL執行一條查詢語句的內部執行過程?
連接器:客戶端首先通過連接器連接到MySQL服務器。
緩存:連接器經過權限驗證后,先查詢之前是否有執行過此語句(有緩存),若有則,直接返回緩存數據,若無,進入分析器。
分析器:分析器會對查詢語句進行語法分析和詞法分析,判斷 SQL 語法是否正確,如果查詢語法錯誤會直接返回給客戶端錯誤信息,如果語法正確則進入優化器。
優化器:優化器是對查詢語句進行優化處理,例如一個表里面有多個索引,優化器會判別哪個索引性能更好。
執行器:優化器執行完就進入執行器,執行器就開始執行語句進行查詢比對了,直到查詢到滿足條件的所有數據,然后進行返回。
2.MySQL的優化(高頻)
高頻訪問:
分表分庫:將數據庫表進行水平拆分,減少表的長度
增加緩存: 在web和DB之間加上一層緩存層
增加數據庫的索引:在合適的字段加上索引,解決高頻訪問的問題
并發優化:
主從讀寫分離:只在主服務器上寫,從服務器上讀
負載均衡集群:通過集群或者分布式的方式解決并發壓力
3.MySQL數據庫引擎介紹,innodb和myisam的特點和區別
InnoDB : InnoDB是mysql的默認引擎,支持事務和外鍵,支持容災恢復。適合更新頻繁和多并發的表 行級鎖
MyISAM : 插入和查詢速度比較高,支持大文件,但是不支持事務,適合在web和數據倉庫場景下使用 表級鎖
MEMORY : memory將表中的數據保存在內存里,適合數據比較小而且頻繁訪問的場景
CSV
blackhole
三、索引
1.索引的優缺點,什么時候使用索引,什么時候不能使用索引(重點)
什么時候適合使用索引:
經常搜索的列上建索引;
作為主鍵的列上需要建索引
經常需要連接(where)的列上
經常需要排序的列
進場需要范圍插著列
那些列不適合建索引:
很少查詢的列
更新很頻繁的列
數據的可取值比較少的列
2.索引的低層實現(重點)
數據庫的索引是用B+樹實現的;
B+樹是一種特殊的平衡多路樹,是B樹的優化改進版本,它把所有的數據都存放在葉節點上,中間節點保存的是索引。這樣一來相對于B樹來說,減少了數據對中間節點的空間占用,使得中間節點可以存放更多的指針,使得樹變得更矮,深度更小,從而減少查詢的磁盤IO次數,提高查詢效率。另一個是由于葉節點之間有指針連接,所以可以進行范圍查詢,方便區間訪問。
而紅黑樹是二叉的,他的深度相對于B+樹來說更大,更大的深度意味著查找的次數更多,更頻繁的磁盤IO,所以紅黑樹更適合在內存中進行查找。
3.B樹和B+樹二點區別(重點)
B+樹優點:由于B+樹的數據都存儲在葉子結點中,分支結點均為索引,方便掃庫,只需要掃一遍葉子結點即可,但是B樹因為其分支結點同樣存儲著數據,我們要找到具體的數據,需要進行一次中序遍歷按序來掃,所以B+樹更加適合在區間查詢的情況,所以通常B+樹用于數據庫索引,而B樹則常用于文件索引。
4.索引最左前綴/最左匹配
假如我們對a b c三個字段建立了聯合索引,在聯合索引中,從最左邊的字段開始,任何連續的索引都能匹配上,當遇到范圍查詢的時候停止。比如對于聯合索引index(a,b,c),能匹配a,ab,abc三組索引。并且對查詢時字段的順序沒有限制,也就是a,b,c; b,a,c; c,a,b; c,b,a都可以匹配。
5.各種樹形結構
AVL樹(平衡二叉樹)
紅黑樹是在AVL樹的基礎上提出來的。
平衡二叉樹又稱為AVL樹,是一種特殊的二叉排序樹。其左右子樹都是平衡二叉樹,且左右子樹高度之差的絕對值不超過1。
AVL樹中所有結點為根的樹的左右子樹高度之差的絕對值不超過1。
將二叉樹上結點的左子樹深度減去右子樹深度的值稱為平衡因子BF,那么平衡二叉樹上的所有結點的平衡因子只可能是-1、0和1。只要二叉樹上有一個結點的平衡因子的絕對值大于1,則該二叉樹就是不平衡的。
紅黑樹
對紅黑樹的理解:通過特殊的要求實現了比較奇怪的結構(數據存放方式),這種結構(存放方式)可以讓查找數據變得特別有效,查找方式和常規的二叉查找樹查找同。
紅黑樹是在AVL樹的基礎上發展而來的。紅黑樹是一種二叉查找樹,但在每個節點增加一個存儲位表示節點的顏色,可以是紅或黑(非紅即黑)。通過對任何一條從根到葉子的路徑上各個節點著色的方式的限制,紅黑樹確保沒有一條路徑會比其它路徑長出兩倍,因此,紅黑樹是一種弱平衡二叉樹,相對于要求嚴格的AVL樹來說,它的旋轉次數少,所以對于搜索,插入,刪除操作較多的情況下,通常使用紅黑樹。
紅黑樹較AVL樹的優點:
AVL 樹是高度平衡的,頻繁的插入和刪除,會引起頻繁的rebalance,導致效率下降;紅黑樹不是高度平衡的,算是一種折中,插入最多兩次旋轉,刪除最多三次旋轉。
所以紅黑樹在查找,插入刪除的性能都是O(logn),且性能穩定,所以STL里面很多結構包括map底層實現都是使用的紅黑樹。
紅黑樹旋轉:
旋轉:紅黑樹的旋轉是一種能保持二叉搜索樹性質的搜索樹局部操作。有左旋和右旋兩種旋轉,通過改變樹中某些結點的顏色以及指針結構來保持對紅黑樹進行插入和刪除操作后的紅黑性質。
左旋:對某個結點x做左旋操作時,假設其右孩子為y而不是T.nil:以x到y的鏈為“支軸”進行。使y成為該子樹新的根結點,x成為y的左孩子,y的左孩子成為x的右孩子。
右旋:對某個結點x做右旋操作時,假設其左孩子為y而不是T.nil:以x到y的鏈為“支軸”進行。使y成為該子樹新的根結點,x成為y的右孩子,y的右孩子成為x的左孩子。
B+樹
B+是一種多路搜索樹,主要為磁盤或其他直接存取輔助設備而設計的一種平衡查找樹,在B+樹中,每個節點的可以有多個孩子,并且按照關鍵字大小有序排列。所有記錄節點都是按照鍵值的大小順序存放在同一層的葉節點中。相比B樹,其具有以下幾個特點:
每個節點上的指針上限為2d而不是2d+1(d為節點的出度)
內節點不存儲data,只存儲key
葉子節點不存儲指針
總結
- 上一篇: 写大数据简历的黄金法则及项目经验
- 下一篇: 数据库知识点汇总(最全!!)