面:如何設計一個關係型數據庫?html
這主要考察咱們對關係型數據庫總體架構的把握,至關於讓咱們本身編寫一個RDBMS(關係型數據庫管理系統)。設計架構圖以下,能夠從下圖中的各個模塊進行回答。mysql
面:爲何要使用索引?面試
答:爲了在數據庫中記錄較多的時候避免每次查詢都用全表掃描的方式,咱們須要一種更高效的機制,那就是索引相似與字典中的目錄,用來快速查詢數據。sql
面:什麼樣的信息能成爲索引?數據庫
答:能將某個記錄限定在必定查找範圍內的字段,就是一些關鍵信息,如主鍵、惟一鍵以及普通鍵等。segmentfault
爲了提升索引的性能,就要採起一些數據結構來加快索引的查詢。索引能夠採用的數據結構主要有如下幾種:數據結構
二叉查找樹的弊端:當對索引的數據結構進行修改後,可能會退化成鏈表,即時間複雜度從O(logn)下降到O(n)。即便經過旋轉等方式使此樹可以保證二叉查找樹的結構,那麼還有一個影響性能的關鍵因素:I/O讀寫。深度過深的話,I/O讀寫次數也會變多,效率仍是很低。因此二叉查找樹不適用於創建索引。架構
B-Tree:經過分析二叉查找樹的弊端,咱們能夠下降樹的高度來減小I/O的次數。那麼B-Tree就能夠派上用場了。先看下什麼是B-Tree,這裏的B表示balance(平衡),B-Tree是一種多路自平衡的搜索樹。它相似於普通的平衡二叉樹,不一樣的一點是B-Tree容許每一個節點有更多的子節點。下圖是B-Tree的簡化圖:併發
B-Tree有如下特色:工具
B+-Tree:B+-Tree是B-Tree的變體,也是一種多路搜索樹,它與B-Tree的不一樣之處在於:
簡化B+-Tree以下圖:
面:爲何B+-Tree相比B-Tree更適合用來作存儲索引?
因爲B+-Tree的查詢必須進過根節點到葉子節點,通過屢次I/O,那麼是否可考慮Hash索引呢?
雖然Hash索引的查詢效率比B+-Tree索引的查詢效率要高,但同時它也有許多的弊端:
因此綜上,MySQL採用B+樹來做爲索引的數據結構。
面:密集索引和稀疏索引的區別
答:
在MySQL中的InnoDB中,關於密集索引的知識點以下:
面:如何定位並優化慢查詢SQL?(開放性)
答:
實例:首先查看慢日誌(DML SQL執行時間大於必定長度)的相關配置。
show VARIABLES like '%query%'
在返回的結果中,關注三個變量:
Variable_name | value |
---|---|
long_query_time | 1.000000 #慢查詢時間的閾值 |
slow_query_log | ON #是否開啓記錄慢查詢日誌 |
slow_query_log_file | /home/mysql/data3001/mysql/slow_query.log #慢日誌路徑 |
show status like '%slow_queries%' #查看當前慢查詢的條數
運行語句SELECT name FROM chapter
,chpater表中有50多萬條記錄,耗時23s。運行上面的查詢慢查詢條數的SQL語句,會發現增長了1,接下來經過explain工具分析。運行語句explain SELECT name FROM chapter
,關注返回結果的type
列發現結果是ALL,意味着是走的全表掃描,那麼確實是不快的。咱們來看下查詢走索引的,explain SELECT id FROM chapter
,type列的結果是index,走的是索引(但不是主鍵索引,看key列結果是fk_chapter_novel,走的是外鍵索引,說明主鍵索引不必定比其餘索引快)。此時運行SELECT id FROM chapte
只耗時2.9秒。來強制走下主鍵索引,運行語句SELECT id FROM chapter FORCE INDEX(PRIMARY)
,耗時23s,運行EXPLAIN SELECT id FROM chapter FORCE INDEX(PRIMARY)
發現是走了主鍵索引的,可是耗時卻和全表掃描差很少了。
面:索引是創建的越多越好嗎?
答:答案固然是否認的。
關於數據庫鎖部分主要回答以下問題:
面:MyISAM與InnoDB關於鎖方面的區別是什麼?
答:
共享鎖和排它鎖的兼容性
- | X | S |
---|---|---|
X | 衝突 | 衝突 |
S | 衝突 | 兼容 |
MyISAM適合的場景
InnoDB適合的場景
數據庫鎖的分類
面:數據庫事務的四大特性
答:ACID
面:能說說事務隔離級別以及各級別下的併發訪問問題嗎?
答:MySQL事務的隔離級別由低到高分別是read uncommitted(未提交讀)、read committed(提交讀)、repeatable read(可重複讀)、serializable(串行化)。併發訪問問題及對應解決的事務隔離級別以下:
更新丟失(一個事務的更新覆蓋掉了另外一個事務的更新):MySQL中全部事務隔離級別在數據庫層面上都可避免
實例以下圖:
髒讀(一個事務讀到另一個未提交事務的數據):READ-COMMITTED事務隔離級別及以上可避免
不可重複讀(事務A屢次讀取同一數據,事務B在事務A讀取的同時對該數據作了更新並提交,致使事務A屢次讀取到的結果不一致):REPEATABLE-READ事務隔離級別及以上可避免
幻讀(事務A屢次讀取與搜索條件相匹配的若干行,事務B用插入或刪除行的方式來修改事務A的結果集,致使事務A出現了「幻覺」):SERIALIZABLE事務隔離級別可避免
當前讀與快照讀
當前讀的數據是最新的,而快照讀讀取的是快照。當前讀主要是如下SQL:
select...lock in share mode select...for update update,delete,insert
面:能說說InnoDB可重複讀隔離級別下如何避免幻讀嗎?
答:表面上來看是經過僞MVCC的快照讀(非阻塞讀)實現的,但本質確實經過next-key鎖即行鎖+gap鎖實現的。
SELECT column_1, column_2, ... FROM table_1 [INNER | LEFT |RIGHT] JOIN table_2 ON conditions WHERE conditions GROUP BY column_1 HAVING group_conditions ORDER BY column_1 LIMIT offset, length;