Java面試中常問的數據庫方面問題②
B樹和B+樹的區別
- B樹,每個節點都存儲key和data,所有節點組成這棵樹,並且葉子節點指針爲nul,葉子結點不包含任何關鍵字信息。
- B+樹,所有的葉子結點中包含了全部關鍵字的信息,及指向含有這些關鍵字記錄的指針,且葉子結點本身依關鍵字的大小自小而大的順序鏈接,所有的非終端結點可以看成是索引部分,結點中僅含有其子樹根結點中最大(或最小)關鍵字。 (而B 樹的非終節點也包含需要查找的有效信息)
爲什麼說B+比B樹更適合實際應用中操作系統的文件索引和數據庫索引?
什麼情況下應不建或少建索引
- 表記錄太少
- 經常插入、刪除、修改的表
- 數據重複且分佈平均的表字段,假如一個表有10萬行記錄,有一個字段A只有T和F兩種值,且每個值的分佈概率大約爲50%,那麼對這種表A字段建索引一般不會提高數據庫的查詢速度。
- 經常和主字段一塊查詢但主字段索引值比較多的表字段
MySQL分區
一. 什麼是表分區?
表分區,是指根據一定規則,將數據庫中的一張表分解成多個更小的,容易管理的部分。從邏輯上看,只有一張表,但是底層卻是由多個物理分區組成。
二. 表分區與分表的區別
分表:指的是通過一定規則,將一張表分解成多張不同的表。比如將用戶訂單記錄根據時間成多個表。
分表與分區的區別在於:分區從邏輯上來講只有一張表,而分表則是將一張表分解成多張表。
三. 表分區有什麼好處?
- 分區表的數據可以分佈在不同的物理設備上,從而高效地利用多個硬件設備。 2. 和單個磁盤或者文件系統相比,可以存儲更多數據
- 優化查詢。在where語句中包含分區條件時,可以只掃描一個或多個分區表來提高查詢效率;涉及sum和count語句時,也可以在多個分區上並行處理,最後彙總結果。
- 分區表更容易維護。例如:想批量刪除大量數據可以清除整個分區。
- 可以使用分區表來避免某些特殊的瓶頸,例如InnoDB的單個索引的互斥訪問,ext3問價你係統的inode鎖競爭等。
四. 分區表的限制因素
- 一個表最多隻能有1024個分區
- MySQL5.1中,分區表達式必須是整數,或者返回整數的表達式。在MySQL5.5中提供了非整數表達式分區的支持。
- 如果分區字段中有主鍵或者唯一索引的列,那麼多有主鍵列和唯一索引列都必須包含進來。即:分區字段要麼不包含主鍵或者索引列,要麼包含全部主鍵和索引列。
- 分區表中無法使用外鍵約束
- MySQL的分區適用於一個表的所有數據和索引,不能只對表數據分區而不對索引分區,也不能只對索引分區而不對錶分區,也不能只對表的一部分數據分區。
五. 如何判斷當前MySQL是否支持分區?
命令:show variables like '%partition%' 運行結果:
mysql> show variables like '%partition%';+-------------------+-------+| Variable_name | Value |+-------------------+-------+| have_partitioning | YES |+-------------------+-------+1 row in set (0.00 sec)have_partintioning 的值爲YES,表示支持分區。
六. MySQL支持的分區類型有哪些?
- RANGE分區: 這種模式允許將數據劃分不同範圍。例如可以將一個表通過年份劃分成若干個分區
- LIST分區: 這種模式允許系統通過預定義的列表的值來對數據進行分割。按照List中的值分區,與RANGE的區別是,range分區的區間範圍值是連續的。
- HASH分區 :這中模式允許通過對錶的一個或多個列的Hash Key進行計算,最後通過這個Hash碼不同數值對應的數據區域進行分區。例如可以建立一個對錶主鍵進行分區的表。
- KEY分區 :上面Hash模式的一種延伸,這裏的Hash Key是MySQL系統產生的。
四種隔離級別
- Serializable (串行化):可避免髒讀、不可重複讀、幻讀的發生。
- Repeatable read (可重複讀):可避免髒讀、不可重複讀的發生。
- Read committed (讀已提交):可避免髒讀的發生。
- Read uncommitted (讀未提交):最低級別,任何情況都無法保證。
關於MVVC
MySQL InnoDB存儲引擎,實現的是基於多版本的併發控制協議——MVCC (Multi-Version Concurrency Control) (注:與MVCC相對的,是基於鎖的併發控制,Lock-Based Concurrency Control)。MVCC最大的好處:讀不加鎖,讀寫不衝突。在讀多寫少的OLTP應用中,讀寫不衝突是非常重要的,極大的增加了系統的併發性能,現階段幾乎所有的RDBMS,都支持了MVCC。
- LBCC:Lock-Based Concurrency Control,基於鎖的併發控制。
- MVCC:Multi-Version Concurrency Control,基於多版本的併發控制協議。純粹基於鎖的併發機制併發量低,MVCC是在基於鎖的併發控制上的改進,主要是在讀操作上提高了併發量。
在MVCC併發控制中,讀操作可以分成兩類:
- 快照讀 (snapshot read):讀取的是記錄的可見版本 (有可能是歷史版本),不用加鎖(共享讀鎖s鎖也不加,所以不會阻塞其他事務的寫)。
- 當前讀 (current read):讀取的是記錄的最新版本,並且,當前讀返回的記錄,都會加上鎖,保證其他事務不會再併發修改這條記錄。
行級鎖定的優點:
- 當在許多線程中訪問不同的行時只存在少量鎖定衝突。
- 回滾時只有少量的更改
- 可以長時間鎖定單一的行。
行級鎖定的缺點:
- 比頁級或表級鎖定佔用更多的內存。
- 當在表的大部分中使用時,比頁級或表級鎖定速度慢,因爲你必須獲取更多的鎖。
- 如果你在大部分數據上經常進行GROUP BY操作或者必須經常掃描整個表,比其它鎖定明顯慢很多。
- 用高級別鎖定,通過支持不同的類型鎖定,你也可以很容易地調節應用程序,因爲其鎖成本小於行級鎖定。
MySQL觸發器簡單實例
- CREATE TRIGGER --觸發器必須有名字,最多64個字符,可能後面會附有分隔符.它和MySQL中其他對象的命名方式基本相象.
- { BEFORE | AFTER } --觸發器有執行的時間設置:可以設置爲事件發生前或後。
- { INSERT | UPDATE | DELETE } --同樣也能設定觸發的事件:它們可以在執行insert、update或delete的過程中觸發。
- ON --觸發器是屬於某一個表的:當在這個表上執行插入、 更新或刪除操作的時候就導致觸發器的激活. 我們不能給同一張表的同一個事件安排兩個觸發器。
- FOR EACH ROW --觸發器的執行間隔:FOR EACH ROW子句通知觸發器 每隔一行執行一次動作,而不是對整個表執行一次。
- --觸發器包含所要觸發的SQL語句:這裏的語句可以是任何合法的語句, 包括複合語句,但是這裏的語句受的限制和函數的一樣。