計算機考研復試面試常問問題 數據庫篇
在復習過程中,我用心查閱並整理了在考研復試面試中可能問到的大部分問題,並分點整理了答案,可以直接理解背誦並加上自己的語言潤色!極力推薦打印下來看,效率更高!絕對良心之作!
此系列一共有8篇:編程語言篇|數據結構篇|操作系統篇|組成原理篇|計算機網絡篇|數據庫篇|軟件工程篇|計算機專業英語篇(還未全部完成,敬請期待,你們的支持和關注是我最大的動力!)
需要pdf直接打印版,可在公眾號"程序員寶藏"回復復試上岸獲取(會持續更新)
相對於408初試,復試需要的少多了,加油,大家都可以上岸!!!讓我們一起努力!!!
章節導讀:
1.事務
概念:事務指的是滿足 ACID 特性的一組操作,可以通過 Commit 提交一個事務,也可以使用 Rollback 進行回滾。
ACID特性: (1)原子性 (Atomicity):事務被視為不可分割的最小單元,事務的所有操作要么全部提交成功,要么全部失敗回滾。回滾可以用回滾日志來實現,回滾日志記錄着事務所執行的修改操作,在回滾時反向執行這些修改操作即可。
(2)一致性 (Consistency):數據庫在事務執行前后都保持一致性狀態。在一致性狀態下,所有事務對一個數據的讀取結果都是相同的。
(3)隔離性 (Isolation):一個事務所做的修改在最終提交以前,對其它事務是不可見的。
(4)持久性 (Durability):一旦事務提交,則其所做的修改將會永遠保存到數據庫中。即使系統發生崩潰,事務執行的結果也不能丟失。
使用重做日志來保證持久性。
事務的 ACID 特性概念簡單,但不是很好理解,主要是因為這幾個特性不是一種平級關系: 只有滿足一致性,事務的執行結果才是正確的。 在無並發的情況下,事務串行執行,隔離性一定能夠滿足。此時只要能滿足原子性,就一定能滿足一致性。 在並發的情況下,多個事務並行執行,事務不僅要滿足原子性,還需要滿足隔離性,才能滿足一致性。事務滿足持久性是為了能應對數據庫崩潰的情況。
2.並發一致性問題
丟失數據
丟失數據:
和
兩個事務都對一個數據進行修改,
先修改,
隨后修改,
的修改覆蓋了
的修改。簡記為
同時修改。
讀臟數據
讀臟數據:
對一個數據做了修改,
讀取這一個數據。若
執行 ROLLBACK 操作,則
讀取的結果和第一次的結果不一樣。簡記為
讀取失敗的修改。最簡單的場景是修改完成后,緊接着查詢檢驗結果。
不可重復讀
不可重復讀:
讀取一個數據,
對該數據做了修改。如果
再次讀取這個數據,此時讀取的結果和第一次讀取的結果不同。簡記為
讀時修改,重復讀取的結果不一樣。
幻影讀
幻影讀:
讀取某個范圍的數據,
在這個范圍內插入新的數據,
再次讀取這個范圍的數據,此時讀取的結果和和第一次讀取的結果不同。簡記為
讀時插入,重復讀取的結果不一樣。
解決方案
在並發環境下,事務的隔離性很難保證,因此會出現很多並發一致性問題。產生並發不一致性問題的主要原因是破壞了事務的隔離性。解決方法是通過
並發控制來保證隔離性。並發控制可以通過封鎖來實現,但是封鎖操作需要用戶自己控制,相當復雜。數據庫管理系統提供了事務的隔離級別,讓用戶以一種更輕松的方式處理並發一致性問題。
3.封鎖
封鎖粒度 MySQL 中提供了兩種封鎖粒度:
行級鎖以及表級鎖。應盡量只鎖定需要修改的那部分數據,而不是所有的資源。鎖定的數據量越少,發生鎖爭用的可能就越小,系統的並發程度就越高。但是加鎖需要消耗資源,鎖的各種操作 (包括獲取鎖、釋放鎖、以及檢查鎖狀態) 都會增加系統開銷。因此封鎖粒度越小,系統開銷就越大。為此,我們在選擇封鎖粒度時,需在
鎖開銷和並發程度之間做一個權衡。
封鎖類型
(1)讀寫鎖 排它鎖 (Exclusive),簡寫為
X 鎖,又稱寫鎖。共享鎖 (Shared),簡寫為
S 鎖,又稱讀鎖。有以下兩個規定: 一個事務對數據對象 A 加了 X 鎖,就可以對 A 進行讀取和更新。加鎖期間其它事務不能對 A 加任何鎖。
一個事務對數據對象 A 加了 S 鎖,可以對 A 進行讀取操作,但是不能進行更新操作。加鎖期間其它事務能對 A 加 S 鎖,但是不能加 X 鎖。
(2)意向鎖 使用意向鎖 (Intention Locks),可以更容易地支持多粒度封鎖,使得行鎖和表鎖能夠共存。 在存在行級鎖和表級鎖的情況下,事務 T 想要對表 A 加 X 鎖,就需要先檢測是否有其它事務對表 A 或者表 A 中的任意一行加了鎖,那么就需要對表 A 的每一行都檢測一次,這是非常耗時的。
意向鎖在原來的 X/S 鎖之上引入了 IX / IS,IX / IS 都是
表級別的鎖,用來表示一個事務稍后會對表中的某個數據行上加 X 鎖或 S 鎖。整理可得以下兩個規定:一個事務在獲得某個數據行對象的 S 鎖之前,必須先獲得表的 IS 鎖或者更強的鎖; 一個事務在獲得某個數據行對象的 X 鎖之前,必須先獲得表的 IX 鎖。
封鎖協議
三級封鎖協議
一級封鎖協議:事務 T 要修改數據 A 時必須加 X 鎖,直到 T 結束才釋放鎖。防止同時修改,可解決丟失修改問題,因不能同時有兩個事務對同一個數據進行修改,那么事務的修改就不會被覆蓋。
二級封鎖協議:在一級的基礎上,要求讀取數據 A 時必須加 S 鎖,讀取完馬上釋放 S 鎖。防止修改時讀取,可解決丟失修改和讀臟數據問題,因為一個事務在對數據 A 進行修改,根據 1 級封鎖協議,會加 X 鎖,那么就不能再加 S 鎖了,也就是不會讀入數據。
三級封鎖協議:在二級的基礎上,要求讀取數據 A 時必須加 S 鎖,直到事務結束了才能釋放 S 鎖。防止讀取時修改,可解決丟失修改和讀臟數據問題,還進一步防止了不可重復讀的問題,因為讀 A 時,其它事務不能對 A 加 X 鎖,從而避免了在讀的期間數據發生改變。
兩段鎖協議 兩段鎖協議是指每個事務的執行可以分為兩個階段:生長階段 (加鎖階段) 和衰退階段 (解鎖階段)。 兩段封鎖法可以這樣來實現:
事務開始后就處於加鎖階段,一直到執行 ROLLBACK 和 COMMIT 之前都是加鎖階段。 ROLLBACK 和 COMMIT 使事務進入解鎖階段,即在 ROLLBACK 和 COMMIT 模塊中 DBMS 釋放所有封鎖。
4.關系數據庫設計理論
函數依賴
- 記
表示 A 函數決定 B,也可以說 B 函數依賴於 A。
- 若
是關系的一個或多個屬性的集合,該集合函數決定了關系的其它所>有屬性並且是
最小的,那么該集合就稱為鍵碼。- 對於
,如果能找到 A 的真子集
,使得
,那么
就是
部分函數>依賴,否則就是完全函數依賴。- 對於
,
,則
是一個
傳遞函數依賴。
異常
- 如表所示,展示了學生課程關系的函數依賴為 {Sno, Cname} -> {Sname, Sdept, Mname, Grade},鍵碼為 {Sno, Cname}。也就是說,確定學生和課程后就能確定其它信息。
| Sno | Sname | Sdept | Mname | Cname | Grade |
|---|---|---|---|---|---|
| 1 | 學生-1 | 學院-1 | 院長-1 | 課程-1 | 90 |
| 2 | 學生-2 | 學院-2 | 院長-2 | 課程-2 | 80 |
| 2 | 學生-2 | 學院-2 | 院長-2 | 課程-1 | 100 |
| 3 | 學生-3 | 學院-2 | 院長-2 | 課程-2 | 95 |
不符合范式的關系,會產生很多異常,主要有以下四種異常:
冗余數據:例如學生-2出現了兩次。
修改異常:修改了一個記錄中的信息,但是另一個記錄中相同的信息卻沒有被修改。
刪除異常:刪除一個信息,那么也會丟失其它信息。例如刪除了課程-1需要刪除第一>行和第三行,那么 學生-1 的信息就會丟失。
插入異常:例如想要插入一個學生的信息,如果這個學生還沒選課,那么就無法插入。
范式
范式理論是為了解決以上提到四種異常。高級別范式的依賴於低級別的范式,1NF 是最低級別的范式。
第一范式 (1NF)
屬性不可分。即數據庫表的每一列都是不可分割的基本數據項,同一列中不能有多個值,即實體中的某個屬性不能有多個值或者不能有重復的屬性。
第二范式 (2NF)
每個非主屬性完全函數依賴於鍵碼。可以通過分解來滿足 2NF。
分解前:
| Sno | Sname | Sdept | Mname | Cname | Grade |
|---|---|---|---|---|---|
| 1 | 學生-1 | 學院-1 | 院長-1 | 課程-1 | 90 |
| 2 | 學生-2 | 學院-2 | 院長-2 | 課程-2 | 80 |
| 2 | 學生-2 | 學院-2 | 院長-2 | 課程-1 | 100 |
| 3 | 學生-3 | 學院-2 | 院長-2 | 課程-2 | 95 |
以下學生課程關系中,{Sno, Cname} 為鍵碼,有如下函數依賴:
- Sno -> Sname, Sdept
- Sdept -> Mname
- Sno, Cname-> Grade
函數依賴狀況分析: Grade 完全函數依賴於鍵碼,它沒有任何冗余數據,每個學生的每門課都有特定的成績。
Sname, Sdept 和 Mname 都部分依賴於鍵碼,當一個學生選修了多門課時,這些數據就會出現多次,造成大量冗余數據。
分解后:
關系-1:
| Sno | Sname | Sdept | Mname |
|---|---|---|---|
| 1 | 學生-1 | 學院-1 | 院長-1 |
| 2 | 學生-2 | 學院-2 | 院長-2 |
| 3 | 學生-3 | 學院-2 | 院長-2 |
- 有以下函數依賴: - Sno -> Sname, Sdept - Sdept -> Mname
- 關系-2:
| Sno | Cname | Grade |
|---|---|---|
| 1 | 課程-1 | 90 |
| 2 | 課程-2 | 80 |
| 2 | 課程-1 | 100 |
| 3 | 課程-2 | 95 |
- 有以下函數依賴: Sno, Cname
Grade
第三范式 (3NF)
- 非主屬性不傳遞函數依賴於鍵碼。簡而言之,第三范式就是屬性不依賴於其它非主屬性。
- 上面的 關系-1 中存在以下傳遞函數依賴:Sno
Sdept
Mname。
分解后
- 關系-1.1:
| Sno | Sname | Sdept |
|---|---|---|
| 1 | 學生-1 | 學院-1 |
| 2 | 學生-2 | 學院-2 |
| 3 | 學生-3 | 學院-2 |
- 關系-1.2:
| Sdept | Mname |
|---|---|
| 學院-1 | 院長-1 |
| 學院-2 | 院長-2 |
巴斯-科德范式(BCNF)
Boyce-Codd Normal Form(巴斯-科德范式) 在3NF基礎上,任何非主屬性不能對主鍵子集依賴(在3NF基礎上消除對主碼子集的依賴) 巴斯-科德范式(BCNF)是第三范式(3NF)的一個子集,即滿足巴斯-科德范式(BCNF)必須滿>足第三范式(3NF)。通常情況下,巴斯-科德范式被認為沒有新的設計規范加入,只是對第二范式與第三范式中設計規范要求更強,因而被認為是修正第三范式,也就是說,它事實上是對第三范式的修正,使數據庫冗余度更小。這也是BCNF不被稱為第四范式的原因。某些書上,根據范式要求的遞增性將其稱之為第四范式是不規范,也是更讓人不容易理解的地方。而真正的第四范式,則是在設計規范中添加了對多值及依賴的要求。
5.ER 圖
實體關系圖 (Entity-Relationship,E-R),有三個組成部分:實體、屬性、聯系。用來進行關系型數據庫系統的概念設計。
實體:用矩形表示,矩形框內寫明實體名.屬性:用橢圓形表示,並用無向邊將其與相應的實體連接起來。聯系:用菱形表示,菱形框內寫明聯系名,並用無向邊分別與有關實體連接起來,同時在無向>邊旁標上聯系的類型(1...1,1...* 或 *...*)就是指存在的三種關系 (一對一、一對多或多對多)。
- ER 模型轉換為關系模式的原則:
一對一:遇到一對一關系的話,在兩個實體任選一個添加另一個實體的主鍵即可。一對多:遇到一對多關系的話,在多端添加另一端的主鍵。多對多:遇到多對多關系的話,我們需要將聯系轉換為實體,然后在該實體上加上另外兩個實體的主鍵,作為聯系實體的主鍵,然后再加上該聯系自身帶的屬性即可。
6.索引
索引的數據結構
B-Tree (平衡樹, Balance Tree):也稱為
多路平衡查找樹,並且所有葉子節點位於同一層。
B+Tree:它不僅具有 B-Tree 的平衡性,並且可通過
順序訪問指針來提高區間查詢的性能。在 B+Tree 中,一個節點中的 key 從左到右非遞減排列,若某個指針的
左右相鄰分別是
和
,且不為 null,則該指針指向節點的所有 key 滿足
。
B+Tree 與 B-Tree 最大區別是,B+Tree 的非葉子結點不保存數據,只用於索引,所有數據都保存在葉子結點中。而且葉子結點間按照從小到大順序鏈接起來。
B-Tree/B+Tree 的增刪改查:
查找操作:首先在根節點進行二分查找,找到一個 key 所在的指針,然后遞歸地在指針所指向的節點進行查找。直到查找到葉子節點,然后在葉子節點上進行二分查找,找出 key 所對應的 data。二分查找要求表有序,正好 B-Tree 和 B+Tree 結點中的 key 從左到右非遞減有序排列。
增刪操作:會破壞平衡樹的平衡性,因此在插入刪除操作之后,需要對樹進行一個分裂、合並、旋轉等操作來維護平衡性。
MySQL 索引
索引,在 MySQL 也稱為鍵 (Key),是
存儲引擎快速找到記錄的一種數據結構。相當於圖書的目錄,可根據目錄中的頁碼快速找到所需的內容。
索引結構類型
(1)B+Tree 索引
- B+Tree 索引是大多數 MySQL 存儲引擎的默認索引類型。
- 因為 B+ Tree 的
有序性,因此可用於部分查找、范圍查找、排序和分組。 - 適用於全鍵值、鍵值范圍和鍵前綴查找,其中鍵前綴查找只適用於最左前綴查找。若不是按照索引列的順序進行查找,則無法使用索引。
(2)Hash 索引
-
Hash 索引能以 O(1) 時間進行查找,但是失去了有序性。因此無法用於排序與分組,無法用於部分查找和范圍查找,只支持
精確查找。Hash 索引僅滿足
=,IN和<=>查詢,不能使用范圍查詢。因為 Hash 索引比較的是 Hash 運算后的 Hash 值,所以它只能用於等值的過濾。
(3)全文索引
- 全文索引使用倒排索引實現,它記錄着關鍵詞到其所在文檔的映射。
(4)空間數據索引
- 空間數據索引會從所有維度來索引數據,可以有效地使用任意維度來進行組合查詢。
- 必須使用 GIS 相關的函數來維護數據。
索引的優點缺點
優點
-
大大減少了服務器需要掃描的數據行數。
-
避免服務器進行排序和分組操作,以避免創建
臨時表。B+Tree 索引是有序的,可以用於 ORDER BY 和 GROUP BY 操作。臨時表主要是在排序和分組過程中創建,不需要排序和分組,也就不需要創建臨時表。
-
將
隨機 I/O變為順序 I/O。B+Tree 索引是有序的,會將相鄰的數據都存儲在一起。
缺點
- 索引並不是越多越好,索引固然可以提高相應的 SELECT 的效率,但同時也降低了 INSERT 及 UPDATE 的效率,因為 INSERT 或 UPDATE 時有可能會
重建索引。
索引的設計原則
從索引的優、缺點考慮索引的設計原則。
忌過度索引:索引需要額外的磁盤空間,而且會降低寫操作的性能。- 在修改表內容時,索引會進行更新甚至重構,索引列越多花銷時間越長。為此優化檢索性能,只保持需要的索引即可。
- 經常用在
排列、分組和范圍搜索的列適合創建索引,因為索引是有序的。 - 經常出現在
WHERE子句的列,或是JOIN連接子句中指定的列適合創建索引。
使用短索引:若對長字符串列進行索引,應該指定一個前綴長度,這樣能夠節省大量索引空間。
索引的優化策略
-
獨立的列:在進行查詢時,索引列不能是表達式的一部分,也不能是函數參數,否則無法使用索引。 -
多列索引:在需要使用多個列作為條件進行查詢時,使用多列索引比使用多個單列索引性能更好。 -
索引列的順序:讓選擇性最強的索引列放在前面。 -
前綴索引:對於 BLOB、TEXT 和 VARCHAR 類型的列,必須使用前綴索引,只索引開始的部分字符。前綴長度的選取需要根據索引選擇性來確定。 -
覆蓋索引:索引包含所有需要查詢的字段的值。具有以下優點:- 索引通常遠小於數據行的大小,只讀取索引能大大減少數據訪問量。
- 一些存儲引擎(例如 MyISAM)在內存中只緩存索引,而數據依賴於操作系統來緩存。因此,只訪問索引可以不使用系統調用(通常比較費時)。
索引的使用場景
- 對於
非常小的表:大部分情況下簡單的全表掃描比建立索引更高效; - 對於
中大型的表:建立索引非常有效; - 對於
特大型的表:建立和維護索引的代價將會隨之增長。這種情況下,需要用到一種技術可以直接區分出需要查詢的一組數據,而不是一條記錄一條記錄地匹配。例如可以使用分區技術。

和