本文介紹關于MySQL的相關面試知識
一、關系型數據庫
1、定義
關系型數據庫(Relational Database)是一種基于關系模型的數據庫管理系統(DBMS),它將數據存儲在表格(表)中,并通過表格之間的關系來組織和管理數據。
2、常見的關系型數據庫
-
MySQL:開源的、高性能的關系型數據庫,適用于Web應用和中小型企業。
-
PostgreSQL:開源的、功能強大的關系型數據庫,支持復雜的數據類型和高級功能。
-
Oracle Database:商業級的高性能數據庫,適用于大型企業和高并發場景。
-
Microsoft SQL Server:商業級的數據庫系統,與Windows環境和.NET框架集成良好。
-
SQLite:輕量級的嵌入式數據庫,適用于小型應用和移動設備。
二、MySQL
1、為什么還要用到MySQL,MySQL有什么優點?
- 成熟穩定,功能完善。
- 開源免費。
- 文檔豐富,既有詳細的官方文檔,又有非常多優質文章可供參考學習。
- 開箱即用,操作簡單,維護成本低。
- 兼容性好,支持常見的操作系統,支持多種開發語言。
- 社區活躍,生態完善。
- 事務支持優秀, InnoDB 存儲引擎默認使用 REPEATABLE-READ 并不會有任何性能損失,并且,InnoDB 實現的 REPEATABLE-READ 隔離級別其實是可以解決幻讀問題發生的。
- 支持分庫分表、讀寫分離、高可用
2、MySQL有哪些數據類型?
- 數值類型
數據類型 | 存儲大小(字節) | 描述/范圍(有符號) |
---|---|---|
TINYINT | 1 | -128 到 127 |
SMALLINT | 2 | -32768 到 32767 |
MEDIUMINT | 3 | -8388608 到 8388607 |
INT? | 4 | -2147483648 到 2147483647 |
BIGINT | 8 | -9223372036854775808 到 9223372036854775807 |
FLOAT | 4? | 單精度浮點數 |
DOUBLE? | 8? | 雙精度浮點數 |
DECIMAL | 用于存儲精確的小數 | 定點數類型 |
- 字符串類型
數據類型 | 描述 |
---|---|
VARCHAR | 可變長度字符串,最大長度為 65535 字節(取決于字符集)。 |
CHAR | 固定長度字符串,最大長度為 255 字節。 |
TEXT | 用于存儲較大的文本數據,最大長度為 65535 字節。 |
MEDIUMTEXT | 最大長度為 16777215 字節。 |
LONGTEXT | 最大長度為 4294967295 字節。 |
BLOB | 用于存儲二進制數據,最大長度為 65535 字節。 |
MEDIUMBLOB | 最大長度為 16777215 字節。 |
LONGBLOB | 最大長度為 4294967295 字節。 |
- ?日期和時間類型
數據類型 | 描述 |
---|---|
DATE | 日期值,格式為?YYYY-MM-DD 。 |
TIME | 時間值,格式為?HH:MM:SS 。 |
DATETIME | 日期和時間值,格式為?YYYY-MM-DD HH:MM:SS 。 |
TIMESTAMP | 時間戳,表示從 1970-01-01 00:00:00 UTC 開始的秒數。 |
YEAR | 年份值,可以是 2 位或 4 位格式。 |
3、MySQL索引
(1)索引的介紹
索引是一種用于快速查詢和檢索數據的數據結構,其本質可以看成是一種排序好的數據結構。
索引底層數據結構存在很多種類型,常見的索引結構有: B 樹, B+樹 和 Hash、紅黑樹。在 MySQL 中,無論是 Innodb 還是 MyIsam,都使用了 B+樹作為索引結構。
(2)索引的底層結構
-
二叉查找樹(BST)
二叉查找樹(Binary Search Tree,簡稱BST)是一種特殊的二叉樹,它具有以下性質:
-
每個節點包含一個鍵值(key)和兩個子樹的引用(左子樹和右子樹)。
-
左子樹上所有節點的鍵值都小于其根節點的鍵值。
-
右子樹上所有節點的鍵值都大于其根節點的鍵值。
-
左子樹和右子樹也都是二叉查找樹。
索引為什么不選擇二叉樹?當二叉查找樹是平衡的時候,也就是樹的每個節點的左右子樹深度相差不超過 1 的時候,查詢的時間復雜度為 O(log2(N)),具有比較高的效率。然而,當二叉查找樹不平衡時,例如在最壞情況下(有序插入節點),樹會退化成線性鏈表(也被稱為斜樹),導致查詢效率急劇下降,時間復雜退化為 O(N)。
- 紅黑樹
紅黑樹是一種自平衡二叉查找樹,通過在插入和刪除節點時進行顏色變換和旋轉操作,使得樹始終保持平衡狀態,它具有以下特點:
- 每個節點非紅即黑;
- 根節點總是黑色的;
- 每個葉子節點都是黑色的空節點(NIL 節點);
- 如果節點是紅色的,則它的子節點必須是黑色的(反之不一定);
- 從任意節點到它的葉子節點或空子節點的每條路徑,必須包含相同數目的黑色節點(即相同的黑色高度)。
HashMap 底層用的就是紅黑樹,它的增刪改查性能都很好,但數據庫的索引依舊不用它,這是由于紅黑樹的平衡性相對較弱,可能會導致樹的高度較高,這可能會導致一些數據需要進行多次磁盤 IO 操作才能查詢到。
- B樹&B+樹(多叉平衡搜索樹)
在 B 樹中,一個節點可以有許多個數據,并且它們按序排列起來。不僅如此,原來二叉樹中每個節點最多有兩個分支,而 B 樹中,每個節點可以有很多很多分支。它具有以下特點:
- 葉節點具有相同的深度,葉節點的指針為空
- 所有索引元素不重復
- 節點中的數據索引從左到右遞增排列
?
?為什么不用B樹呢?B 樹雖然好,但它也存在一些問題:查詢效率不太穩定,有些在根節點或者根節點附近就能找到,搜索起來就很快。有些在葉子節點上,那查詢起來就很慢。
B+樹的特點:
- 非葉子節點不存儲 data,只存儲索引(冗余),可以放更多的索引
- 葉子節點包含所有索引字段
- 葉子節點用指針連接,提高區間訪問的性能
?
B+ 樹在 B 樹基礎上做了進一步優化,將數據全部放在葉子節點上。這樣不管查詢哪個數據,最終都要走到葉子節點,從而解決了查詢性能不穩定的問題。?
Q:B樹和B+樹有什么不同呢?
-
節點存儲數據的方式:B樹:每個節點既可以存儲鍵值,也可以存儲數據記錄(或指向數據記錄的指針)。數據可以分布在樹的任意節點中。而B+樹:只有葉節點存儲數據記錄(或指向數據記錄的指針),非葉節點僅存儲鍵值用于索引。這種設計使得B+樹的非葉節點只用于引導查找,而數據訪問集中在葉節點。
-
葉節點結構:B樹:葉節點之間沒有直接的連接。B+樹:葉節點之間通過指針連接成一個雙向鏈表。這種結構使得范圍查詢更加高效,因為可以直接在葉節點鏈表中順序掃描。
-
空間利用率:B樹:由于數據分散在各個節點,可能導致空間利用率較低,尤其是在頻繁更新數據時。B+樹:由于所有數據都集中在葉節點,非葉節點只存儲鍵值,因此空間利用率更高,更適合存儲大量數據。
-
查找效率:B樹:對于單點查詢效率較高,因為數據可能在任意節點。B+樹:對于范圍查詢效率更高,因為所有數據都在葉節點,且葉節點通過鏈表連接,便于順序掃描。
-
插入和刪除操作:B樹:插入和刪除操作可能涉及多個節點的調整,因為數據分布在樹的各個節點。B+樹:插入和刪除操作主要集中在葉節點,非葉節點的調整相對較少,因此更適合頻繁更新的場景
4、MySQL事務
(1)事務的概念和特性?
什么是事務?MySQL的事務是邏輯上的一組操作,要么都執行,要么都不執行。
它具有以下四個核心特性,通常被稱為ACID特性:
-
原子性(Atomicity):事務中的所有操作要么全部完成,要么全部不做,不會出現部分完成的情況。
-
一致性(Consistency):事務執行前后,數據庫必須從一個一致的狀態轉換到另一個一致的狀態。例如,轉賬操作中,金額的總和在事務前后必須保持不變。
-
隔離性(Isolation):多個事務并發執行時,一個事務的執行不應受到其他事務的干擾。MySQL提供了不同的隔離級別來控制事務之間的可見性。
-
持久性(Durability):事務一旦提交,其對數據庫的更改就是永久性的,即使系統故障也不會丟失。
(2)多事務并發產生的問題
- 臟讀:一個事務1讀取數據并且對數據進行了修改,這個修改對其他事務來說是可見的,即使當前事務沒有提交。這時另外一個事務2讀取了這個還未提交的數據,但事務1突然回滾,導致數據并沒有被提交到數據庫,那事務2讀取到的就是臟數據,這也就是臟讀的由來。
- 不可重復讀:?事務1執行過程中,若對同一條數據進行兩次讀取,在這兩次讀取之間,事務2修改了這條數據,并且進行了完整提交。A事務的兩次讀取,卻讀到了兩次不同的數據。
- ?幻讀:幻讀與不可重復讀類似。它發生在一個事務讀取了幾行數據,接著另一個并發事務插入了一些數據時。在隨后的查詢中,第一個事務就會發現多了一些原本不存在的記錄,就好像發生了幻覺一樣,所以稱為幻讀。
(3)并發事務的控制方式
?MySQL 中并發事務的控制方式無非就兩種:鎖 和 MVCC。鎖可以看作是悲觀控制的模式,多版本并發控制(MVCC,Multiversion concurrency control)可以看作是樂觀控制的模式。
鎖 控制方式下會通過鎖來顯式控制共享資源而不是通過調度手段,MySQL 中主要是通過 讀寫鎖 來實現并發控制。
- 共享鎖(S 鎖):又稱讀鎖,事務在讀取記錄的時候獲取共享鎖,允許多個事務同時獲取(鎖兼容)。
- 排他鎖(X 鎖):又稱寫鎖/獨占鎖,事務在修改記錄的時候獲取排他鎖,不允許多個事務同時獲取。如果一個記錄已經被加了排他鎖,那其他事務不能再對這條記錄加任何類型的鎖(鎖不兼容)。
讀寫鎖可以做到讀讀并行,但是無法做到寫讀、寫寫并行。另外,根據根據鎖粒度的不同,又被分為 表級鎖(table-level locking) 和 行級鎖(row-level locking) 。InnoDB 不光支持表級鎖,還支持行級鎖,默認為行級鎖。行級鎖的粒度更小,僅對相關的記錄上鎖即可(對一行或者多行記錄加鎖),所以對于并發寫入操作來說, InnoDB 的性能更高。不論是表級鎖還是行級鎖,都存在共享鎖(Share Lock,S 鎖)和排他鎖(Exclusive Lock,X 鎖)這兩類。
MVCC 是多版本并發控制方法,即對一份數據會存儲多個版本,通過事務的可見性來保證事務能看到自己應該看到的版本。通常會有一個全局的版本分配器來為每一行數據設置版本號,版本號是唯一的。
(4)事務的隔離級別
隔離級別 | 臟讀 | 不可重復讀 | 幻讀 | 臟寫(更新丟失) |
---|---|---|---|---|
Read?Uncommit(讀未提交) | 會出現 | 會出現 | 會出現 | 第二類 |
Read?Commit(讀已提交) | 解決 | 會出現 | 會出現 | 第二類 |
Repeatable?Read(可重復讀,默認) | 解決 | 解決 | 會出現 | 解決 |
Serializable(串行) | 解決 | 解決 | 解決 | 解決 |
?可串行化原理:對于 select 查詢語句,會自動給這條記錄加上共享鎖(S 鎖),此時其他線程就只能讀,因為共享鎖之間相互兼容(S鎖還可以加S鎖),但修改操作會被阻塞,以此實現可串行化的效果。對于 update、delete、insert 語句,會自動加一把排他鎖(X 鎖加了之后不允許加其他鎖),此時其他線程什么都做不了,只能被阻塞,因為排他鎖和其他鎖都互斥,以此實現可串行化的效果
都看到這里了,給個小心心?唄~