計算機考研複試面試常問問題 數據庫篇

計算機考研複試面試常問問題 數據庫篇

在這裏插入圖片描述

在複習過程中,我用心查閱並整理了在考研複試面試中可能問到的大部分問題,並分點整理了答案,可以直接理解背誦並加上自己的語言潤色!極力推薦打印下來看,效率更高!絕對良心之作!

此係列一共有8篇:編程語言篇|數據結構篇|操作系統篇|組成原理篇|計算機網絡篇|數據庫篇|軟件工程篇|計算機專業英語篇(還未全部完成,敬請期待,你們的支持和關注是我最大的動力!)

個人整理,不可用於商業用途,轉載請註明出處。

作者各個平臺請搜索:程序員寶藏。快來探索屬於你的寶藏吧!

需要pdf直接打印版,可在公衆號"程序員寶藏"回覆複試上岸獲取(會持續更新)

需要408電子書最新版,可在公衆號"程序員寶藏"回覆408電子書獲取

需要408初試視頻最新版,可在公衆號"程序員寶藏"回覆408視頻獲取

需要複試機試視頻,可在公衆號"程序員寶藏"回覆機試必過獲取

相對於408初試,複試需要的少多了,加油,大家都可以上岸!!!讓我們一起努力!!!

章節導讀:

1.事務

概念:事務指的是滿足 ACID 特性的一組操作,可以通過 Commit 提交一個事務,也可以使用 Rollback 進行回滾。

ACID特性
(1)原子性 (Atomicity):事務被視爲不可分割的最小單元,事務的所有操作要麼全部提交成功,要麼全部失敗回滾。回滾可以用回滾日誌來實現,回滾日誌記錄着事務所執行的修改操作,在回滾時反向執行這些修改操作即可。

(2)一致性 (Consistency):數據庫在事務執行前後都保持一致性狀態。在一致性狀態下,所有事務對一個數據的讀取結果都是相同的。

(3)隔離性 (Isolation):一個事務所做的修改在最終提交以前,對其它事務是不可見的。

(4)持久性 (Durability):一旦事務提交,則其所做的修改將會永遠保存到數據庫中。即使系統發生崩潰,事務執行的結果也不能丟失。

使用重做日誌來保證持久性。

事務的 ACID 特性概念簡單,但不是很好理解,主要是因爲這幾個特性不是一種平級關係:
只有滿足一致性,事務的執行結果纔是正確的。
在無併發的情況下,事務串行執行,隔離性一定能夠滿足。此時只要能滿足原子性,就一定能滿足一致性。
在併發的情況下,多個事務並行執行,事務不僅要滿足原子性,還需要滿足隔離性,才能滿足一致性。事務滿足持久性是爲了能應對數據庫崩潰的情況。

2.併發一致性問題

丟失數據

丟失數據:T1T_1T2T_2 兩個事務都對一個數據進行修改,T1T_1 先修改,T2T_2 隨後修改,T2T_2 的修改覆蓋了 T1T_1 的修改。簡記爲 同時修改

讀髒數據

讀髒數據:T1T_1 對一個數據做了修改,T2T_2 讀取這一個數據。若 T1T_1 執行 ROLLBACK 操作,則 T2T_2 讀取的結果和第一次的結果不一樣。簡記爲 讀取失敗的修改。最簡單的場景是修改完成後,緊接着查詢檢驗結果。

不可重複讀

不可重複讀:T2T_2 讀取一個數據,T1T_1 對該數據做了修改。如果 T2T_2 再次讀取這個數據,此時讀取的結果和第一次讀取的結果不同。簡記爲 讀時修改,重複讀取的結果不一樣。

幻影讀

幻影讀:T1T_1 讀取某個範圍的數據,T2T_2 在這個範圍內插入新的數據,T1T_1 再次讀取這個範圍的數據,此時讀取的結果和和第一次讀取的結果不同。簡記爲 讀時插入,重複讀取的結果不一樣。

解決方案

在併發環境下,事務的隔離性很難保證,因此會出現很多併發一致性問題。產生併發不一致性問題的主要原因是破壞了事務的隔離性。解決方法是通過 併發控制 來保證隔離性。併發控制可以通過 封鎖 來實現,但是封鎖操作需要用戶自己控制,相當複雜。數據庫管理系統提供了事務的 隔離級別,讓用戶以一種更輕鬆的方式處理併發一致性問題。

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.關係數據庫設計理論

函數依賴

  • ABA \to B 表示 A 函數決定 B,也可以說 B 函數依賴於 A。
  • {A1A2...An}\{A_1,A_2,... ,A_n\} 是關係的一個或多個屬性的集合,該集合函數決定了關係的其它所>有屬性並且是 最小的,那麼該集合就稱爲 鍵碼
  • 對於 ABA \to B,如果能找到 A 的真子集 AA',使得 ABA' \to B,那麼 ABA \to B 就是 部分函數>依賴,否則就是 完全函數依賴
  • 對於 ABA \to BBCB \to C,則 ACA \to C 是一個 傳遞函數依賴

異常

  • 如表所示,展示了學生課程關係的函數依賴爲 {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 \to Grade

第三範式 (3NF)

  • 非主屬性不傳遞函數依賴於鍵碼。簡而言之,第三範式就是屬性不依賴於其它非主屬性。
  • 上面的 關係-1 中存在以下傳遞函數依賴:Sno \to Sdept \to 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 從左到右非遞減排列,若某個指針的 keyikey_i 左右相鄰分別是 keyi1key_{i-1}keyi+1key_{i+1},且不爲 null,則該指針指向節點的所有 key 滿足 keyi1keyikeyi+1key_{i-1} \leq key_i \leq key_{i+1}

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)在內存中只緩存索引,而數據依賴於操作系統來緩存。因此,只訪問索引可以不使用系統調用(通常比較費時)。

索引的使用場景

  • 對於 非常小的表:大部分情況下簡單的 全表掃描 比建立索引更高效;
  • 對於 中大型的表建立索引 非常有效;
  • 對於 特大型的表:建立和維護索引的代價將會隨之增長。這種情況下,需要用到一種技術可以直接區分出需要查詢的一組數據,而不是一條記錄一條記錄地匹配。例如可以使用 分區技術
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章