成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

打工四年總結的數據庫知識點

數據庫
國慶在家無聊,我隨手翻了一下家里數據庫相關的書籍,這一翻我就看上癮了,因為大學比較熟悉的一些數據庫范式我居然都忘了,懷揣著好奇心我就看了一個小國慶。看的過程中我也做了一些小筆記,可能沒我之前系統文章那么有趣,但是絕對也是干貨十足,適合大家去回顧或者面試突擊的適合看看,也不多說先放圖。

國慶在家無聊,我隨手翻了一下家里數據庫相關的書籍,這一翻我就看上癮了,因為大學比較熟悉的一些數據庫范式我居然都忘了,懷揣著好奇心我就看了一個小國慶。

看的過程中我也做了一些小筆記,可能沒我之前系統文章那么有趣,但是絕對也是干貨十足,適合大家去回顧或者面試突擊的適合看看,也不多說先放圖。

存儲引擎

InnoDB

InnoDB 是 MySQL 默認的事務型存儲引擎,只要在需要它不支持的特性時,才考慮使用其他存儲引擎。

InnoDB 采用 MVCC 來支持高并發,并且實現了四個標準隔離級別(未提交讀、提交讀、可重復讀、可串行化)。其默認級別時可重復讀(REPEATABLE READ),在可重復讀級別下,通過 MVCC + Next-Key Locking 防止幻讀。

主索引時聚簇索引,在索引中保存了數據,從而避免直接讀取磁盤,因此對主鍵查詢有很高的性能。

InnoDB 內部做了很多優化,包括從磁盤讀取數據時采用的可預測性讀,能夠自動在內存中創建 hash 索引以加速讀操作的自適應哈希索引,以及能夠加速插入操作的插入緩沖區等。

InnoDB 支持真正的在線熱備份,MySQL 其他的存儲引擎不支持在線熱備份,要獲取一致性視圖需要停止對所有表的寫入,而在讀寫混合的場景中,停止寫入可能也意味著停止讀取。

MyISAM

設計簡單,數據以緊密格式存儲。對于只讀數據,或者表比較小、可以容忍修復操作,則依然可以使用它。

提供了大量的特性,包括壓縮表、空間數據索引等。

不支持事務。

不支持行級鎖,只能對整張表加鎖,讀取時會對需要讀到的所有表加共享鎖,寫入時則對表加排它鎖。但在表有讀取操作的同時,也可以往表中插入新的記錄,這被稱為并發插入(CONCURRENT INSERT)。

可以手工或者自動執行檢查和修復操作,但是和事務恢復以及崩潰恢復不同,可能導致一些數據丟失,而且修復操作是非常慢的。

如果指定了 DELAY_KEY_WRITE 選項,在每次修改執行完成時,不會立即將修改的索引數據寫入磁盤,而是會寫到內存中的鍵緩沖區,只有在清理鍵緩沖區或者關閉表的時候才會將對應的索引塊寫入磁盤。這種方式可以極大的提升寫入性能,但是在數據庫或者主機崩潰時會造成索引損壞,需要執行修復操作。

InnoDB 和 MyISAM 的比較

  • 事務:InnoDB 是事務型的,可以使用 Commit 和 Rollback 語句。
  • 并發:MyISAM 只支持表級鎖,而 InnoDB 還支持行級鎖。
  • 外鍵:InnoDB 支持外鍵。
  • 備份:InnoDB 支持在線熱備份。
  • 崩潰恢復:MyISAM 崩潰后發生損壞的概率比 InnoDB 高很多,而且恢復的速度也更慢。
  • 其它特性:MyISAM 支持壓縮表和空間數據索引。

索引

B+ Tree 原理

數據結構

B Tree 指的是 Balance Tree,也就是平衡樹,平衡樹是一顆查找樹,并且所有葉子節點位于同一層。

B+ Tree 是 B 樹的一種變形,它是基于 B Tree 和葉子節點順序訪問指針進行實現,通常用于數據庫和操作系統的文件系統中。

B+ 樹有兩種類型的節點:內部節點(也稱索引節點)和葉子節點,內部節點就是非葉子節點,內部節點不存儲數據,只存儲索引,數據都存在葉子節點。

內部節點中的 key 都按照從小到大的順序排列,對于內部節點中的一個 key,左子樹中的所有 key 都小于它,右子樹中的 key 都大于等于它,葉子節點的記錄也是按照從小到大排列的。

每個葉子節點都存有相鄰葉子節點的指針。

 

打工四年總結的數據庫知識點

操作

查找

查找以典型的方式進行,類似于二叉查找樹。起始于根節點,自頂向下遍歷樹,選擇其分離值在要查找值的任意一邊的子指針。在節點內部典型的使用是二分查找來確定這個位置。

插入

  • Perform a search to determine what bucket the new record should go into.
  • If the bucket is not full(a most b - 1 entries after the insertion,b 是節點中的元素個數,一般是頁的整數倍),add tht record.
  • Otherwise,before inserting the new record split the bucket. original node has 「(L+1)/2」itemsnew node has 「(L+1)/2」items Move 「(L+1)/2」-th key to the parent,and insert the new node to the parent.Repeat until a parent is found that need not split.
  • If the root splits,treat it as if it has an empty parent ans split as outline above.
  • B-trees grow as the root and not at the leaves.

刪除

和插入類似,只不過是自下而上的合并操作。

樹的常見特性

AVL 樹

平衡二叉樹,一般是用平衡因子差值決定并通過旋轉來實現,左右子樹樹高差不超過1,那么和紅黑樹比較它是嚴格的平衡二叉樹,平衡條件非常嚴格(樹高差只有1),只要插入或刪除不滿足上面的條件就要通過旋轉來保持平衡。由于旋轉是非常耗費時間的。所以 AVL 樹適用于插入/刪除次數比較少,但查找多的場景。

紅黑樹

通過對從根節點到葉子節點路徑上各個節點的顏色進行約束,確保沒有一條路徑會比其他路徑長2倍,因而是近似平衡的。所以相對于嚴格要求平衡的AVL樹來說,它的旋轉保持平衡次數較少。適合,查找少,插入/刪除次數多的場景。(現在部分場景使用跳表來替換紅黑樹,可搜索“為啥 redis 使用跳表(skiplist)而不是使用 red-black?”)

B/B+ 樹

多路查找樹,出度高,磁盤IO低,一般用于數據庫系統中。

B + 樹與紅黑樹的比較

紅黑樹等平衡樹也可以用來實現索引,但是文件系統及數據庫系統普遍采用 B+ Tree 作為索引結構,主要有以下兩個原因:

(一)磁盤 IO 次數

B+ 樹一個節點可以存儲多個元素,相對于紅黑樹的樹高更低,磁盤 IO 次數更少。

(二)磁盤預讀特性

為了減少磁盤 I/O 操作,磁盤往往不是嚴格按需讀取,而是每次都會預讀。預讀過程中,磁盤進行順序讀取,順序讀取不需要進行磁盤尋道。每次會讀取頁的整數倍。

操作系統一般將內存和磁盤分割成固定大小的塊,每一塊稱為一頁,內存與磁盤以頁為單位交換數據。數據庫系統將索引的一個節點的大小設置為頁的大小,使得一次 I/O 就能完全載入一個節點。

B + 樹與 B 樹的比較

B+ 樹的磁盤 IO 更低

B+ 樹的內部節點并沒有指向關鍵字具體信息的指針。因此其內部節點相對 B 樹更小。如果把所有同一內部結點的關鍵字存放在同一盤塊中,那么盤塊所能容納的關鍵字數量也越多。一次性讀入內存中的需要查找的關鍵字也就越多。相對來說IO讀寫次數也就降低了。

B+ 樹的查詢效率更加穩定

由于非葉子結點并不是最終指向文件內容的結點,而只是葉子結點中關鍵字的索引。所以任何關鍵字的查找必須走一條從根結點到葉子結點的路。所有關鍵字查詢的路徑長度相同,導致每一個數據的查詢效率相當。

B+ 樹元素遍歷效率高

B 樹在提高了磁盤IO性能的同時并沒有解決元素遍歷的效率低下的問題。正是為了解決這個問題,B+樹應運而生。B+樹只要遍歷葉子節點就可以實現整棵樹的遍歷。而且在數據庫中基于范圍的查詢是非常頻繁的,而 B 樹不支持這樣的操作(或者說效率太低)。

MySQL 索引

索引是在存儲引擎層實現的,而不是在服務器層實現的,所以不同存儲引擎具有不同的索引類型和實現。

B+ Tree 索引

是大多數 MySQL 存儲引擎的默認索引類型。

  • 因為不再需要進行全表掃描,只需要對樹進行搜索即可,所以查找速度快很多。
  • 因為 B+ Tree 的有序性,所以除了用于查找,還可以用于排序和分組。
  • 可以指定多個列作為索引列,多個索引列共同組成鍵。
  • 適用于全鍵值、鍵值范圍和鍵前綴查找,其中鍵前綴查找只適用于最左前綴查找。如果不是按照索引列的順序進行查找,則無法使用索引。

InnoDB 的 B+Tree 索引分為主索引和輔助索引。主索引的葉子節點 data 域記錄著完整的數據記錄,這種索引方式被稱為聚簇索引。因為無法把數據行存放在兩個不同的地方,所以一個表只能有一個聚簇索引。

 

打工四年總結的數據庫知識點

輔助索引的葉子節點的 data 域記錄著主鍵的值,因此在使用輔助索引進行查找時,需要先查找到主鍵值,然后再到主索引中進行查找,這個過程也被稱作回表。

 

打工四年總結的數據庫知識點

哈希索引

哈希索引能以 O(1) 時間進行查找,但是失去了有序性:

  • 無法用于排序與分組;
  • 只支持精確查找,無法用于部分查找和范圍查找。

InnoDB 存儲引擎有一個特殊的功能叫“自適應哈希索引”,當某個索引值被使用的非常頻繁時,會在 B+Tree 索引之上再創建一個哈希索引,這樣就讓 B+Tree 索引具有哈希索引的一些優點,比如快速的哈希查找。

全文索引

MyISAM 存儲引擎支持全文索引,用于查找文本中的關鍵詞,而不是直接比較是否相等。

查找條件使用 MATCH AGAINST,而不是普通的 WHERE。

全文索引使用倒排索引實現,它記錄著關鍵詞到其所在文檔的映射。

InnoDB 存儲引擎在 MySQL 5.6.4 版本中也開始支持全文索引。

空間數據索引

MyISAM 存儲引擎支持空間數據索引(R-Tree),可以用于地理數據存儲。空間數據索引會從所有維度來索引數據,可以有效地使用任意維度來進行組合查詢。

必須使用 GIS 相關的函數來維護數據。

索引優化

獨立的列

在進行查詢時,索引列不能是表達式的一部分,也不能是函數的參數,否則無法使用索引。

例如下面的查詢不能使用 actor_id 列的索引:

  1. SELECT actor_id FROM sakila.actor WHERE actor_id + 1 = 5; 

多列索引

在需要使用多個列作為條件進行查詢時,使用多列索引比使用多個單列索引性能更好。例如下面的語句中,最好把 actor_id 和 film_id 設置為多列索引。

 

  1. SELECT film_id, actor_ id FROM sakila.film_actor 
  2. WHERE actor_id = 1 AND film_id = 1; 

索引列的順序

讓選擇性最強的索引列放在前面。

索引的選擇性是指:不重復的索引值和記錄總數的比值。最大值為 1,此時每個記錄都有唯一的索引與其對應。選擇性越高,每個記錄的區分度越高,查詢效率也越高。

例如下面顯示的結果中 customer_id 的選擇性比 staff_id 更高,因此最好把 customer_id 列放在多列索引的前面。

 

  1. SELECT COUNT(DISTINCT staff_id)/COUNT(*) AS staff_id_selectivity, 
  2. COUNT(DISTINCT customer_id)/COUNT(*) AS customer_id_selectivity, 
  3. COUNT(*) 
  4. FROM payment; 
  5.  
  6.    staff_id_selectivity: 0.0001 
  7. customer_id_selectivity: 0.0373 
  8.                COUNT(*): 16049 

前綴索引

對于 BLOB、TEXT 和 VARCHAR 類型的列,必須使用前綴索引,只索引開始的部分字符。

前綴長度的選取需要根據索引選擇性來確定。

覆蓋索引

索引包含所有需要查詢的字段的值。

具有以下優點:

  • 索引通常遠小于數據行的大小,只讀取索引能大大減少數據訪問量。
  • 一些存儲引擎(例如 MyISAM)在內存中只緩存索引,而數據依賴于操作系統來緩存。因此,只訪問索引可以不使用系統調用(通常比較費時)。
  • 對于 InnoDB 引擎,若輔助索引能夠覆蓋查詢,則無需訪問主索引。

索引的優點

  • 大大減少了服務器需要掃描的數據行數。
  • 幫助服務器避免進行排序和分組,以及避免創建臨時表(B+Tree 索引是有序的,可以用于 ORDER BY 和 GROUP BY 操作。臨時表主要是在排序和分組過程中創建,不需要排序和分組,也就不需要創建臨時表)。
  • 將隨機 I/O 變為順序 I/O(B+Tree 索引是有序的,會將相鄰的數據都存儲在一起)。

索引的使用條件

  • 對于非常小的表、大部分情況下簡單的全表掃描比建立索引更高效;
  • 對于中到大型的表,索引就非常有效;
  • 但是對于特大型的表,建立和維護索引的代價將會隨之增長。這種情況下,需要用到一種技術可以直接區分出需要查詢的一組數據,而不是一條記錄一條記錄地匹配,例如可以使用分區技術。

為什么對于非常小的表,大部分情況下簡單的全表掃描比建立索引更高效?

如果一個表比較小,那么顯然直接遍歷表比走索引要快(因為需要回表)。

注:首先,要注意這個答案隱含的條件是查詢的數據不是索引的構成部分,否也不需要回表操作。其次,查詢條件也不是主鍵,否則可以直接從聚簇索引中拿到數據。

查詢性能優化

使用 explain 分析 select 查詢語句

explain 用來分析 SELECT 查詢語句,開發人員可以通過分析 Explain 結果來優化查詢語句。

select_type

常用的有 SIMPLE 簡單查詢,UNION 聯合查詢,SUBQUERY 子查詢等。

table

要查詢的表

possible_keys

The possible indexes to choose

可選擇的索引

key

The index actually chosen

實際使用的索引

rows

Estimate of rows to be examined

掃描的行數

type

索引查詢類型,經常用到的索引查詢類型:

const:使用主鍵或者唯一索引進行查詢的時候只有一行匹配 ref:使用非唯一索引 range:使用主鍵、單個字段的輔助索引、多個字段的輔助索引的最后一個字段進行范圍查詢 index:和all的區別是掃描的是索引樹 all:掃描全表:

system

觸發條件:表只有一行,這是一個 const type 的特殊情況

const

觸發條件:在使用主鍵或者唯一索引進行查詢的時候只有一行匹配。

 

  1. SELECT * FROM tbl_name WHERE primary_key=1; 
  2.  
  3. SELECT * FROM tbl_name 
  4.   WHERE primary_key_part1=1 AND primary_key_part2=2; 

 

打工四年總結的數據庫知識點

eq_ref

觸發條件:在進行聯接查詢的,使用主鍵或者唯一索引并且只匹配到一行記錄的時候

 

  1. SELECT * FROM ref_table,other_table 
  2.   WHERE ref_table.key_column=other_table.column
  3.  
  4. SELECT * FROM ref_table,other_table 
  5.   WHERE ref_table.key_column_part1=other_table.column 
  6.   AND ref_table.key_column_part2=1; 

ref

觸發條件:使用非唯一索引

 

  1. SELECT * FROM ref_table WHERE key_column=expr; 
  2.  
  3. SELECT * FROM ref_table,other_table 
  4.   WHERE ref_table.key_column=other_table.column
  5.  
  6. SELECT * FROM ref_table,other_table 
  7.   WHERE ref_table.key_column_part1=other_table.column 
  8.   AND ref_table.key_column_part2=1; 

 

打工四年總結的數據庫知識點

range

觸發條件:只有在使用主鍵、單個字段的輔助索引、多個字段的輔助索引的最后一個字段進行范圍查詢才是 range

 

  1. SELECT * FROM tbl_name 
  2.   WHERE key_column = 10; 
  3.  
  4. SELECT * FROM tbl_name 
  5.   WHERE key_column BETWEEN 10 and 20; 
  6.  
  7. SELECT * FROM tbl_name 
  8.   WHERE key_column IN (10,20,30); 
  9.  
  10. SELECT * FROM tbl_name 
  11.   WHERE key_part1 = 10 AND key_part2 IN (10,20,30); 

 

打工四年總結的數據庫知識點

index

The index join type is the same as ALL, except that the index tree is scanned. This occurs two ways:

觸發條件:

  • 只掃描索引樹

1)查詢的字段是索引的一部分,覆蓋索引。 2)使用主鍵進行排序

 

打工四年總結的數據庫知識點

all

觸發條件:全表掃描,不走索引

優化數據訪問

減少請求的數據量

  • 只返回必要的列:最好不要使用 SELECT * 語句。
  • 只返回必要的行:使用 LIMIT 語句來限制返回的數據。
  • 緩存重復查詢的數據:使用緩存可以避免在數據庫中進行查詢,特別在要查詢的數據經常被重復查詢時,緩存帶來的查詢性能提升將會是非常明顯的。

減少服務器端掃描的行數

最有效的方式是使用索引來覆蓋查詢。

重構查詢方式

切分大查詢

一個大查詢如果一次性執行的話,可能一次鎖住很多數據、占滿整個事務日志、耗盡系統資源、阻塞很多小的但重要的查詢。

 

  1. DELETE FROM messages WHERE create < DATE_SUB(NOW(), INTERVAL 3 MONTH); 
  2.  
  3. rows_affected = 0 
  4. do { 
  5.     rows_affected = do_query( 
  6.     "DELETE FROM messages WHERE create  < DATE_SUB(NOW(), INTERVAL 3 MONTH) LIMIT 10000"
  7. } while rows_affected > 0 

分解大連接查詢

將一個大連接查詢分解成對每一個表進行一次單表查詢,然后在應用程序中進行關聯,這樣做的好處有:

  • 讓緩存更高效。對于連接查詢,如果其中一個表發生變化,那么整個查詢緩存就無法使用。而分解后的多個查詢,即使其中一個表發生變化,對其它表的查詢緩存依然可以使用。
  • 分解成多個單表查詢,這些單表查詢的緩存結果更可能被其它查詢使用到,從而減少冗余記錄的查詢。
  • 減少鎖競爭;
  • 在應用層進行連接,可以更容易對數據庫進行拆分,從而更容易做到高性能和可伸縮。
  • 查詢本身效率也可能會有所提升。例如下面的例子中,使用 IN() 代替連接查詢,可以讓 MySQL 按照 ID 順序進行查詢,這可能比隨機的連接要更高效。

 

  1. SELECT * FROM tag 
  2. JOIN tag_post ON tag_post.tag_id=tag.id 
  3. JOIN post ON tag_post.post_id=post.id 
  4. WHERE tag.tag='mysql'
  5.  
  6. SELECT * FROM tag WHERE tag='mysql'
  7. SELECT * FROM tag_post WHERE tag_id=1234; 
  8. SELECT * FROM post WHERE post.id IN (123,456,567,9098,8904); 

事務

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

ACID

事務最基本的莫過于 ACID 四個特性了,這四個特性分別是:

  • Atomicity:原子性
  • Consistency:一致性
  • Isolation:隔離性
  • Durability:持久性

原子性

事務被視為不可分割的最小單元,事務的所有操作要么全部成功,要么全部失敗回滾。

一致性

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

隔離性

一個事務所做的修改在最終提交以前,對其他事務是不可見的。

持久性

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

ACID 之間的關系

事務的 ACID 特性概念很簡單,但不好理解,主要是因為這幾個特性不是一種平級關系:

  • 只有滿足一致性,事務的結果才是正確的。
  • 在無并發的情況下,事務串行執行,隔離性一定能夠滿足。此時只要能滿足原子性,就一定能滿足一致性。在并發的情況下,多個事務并行執行,事務不僅要滿足原子性,還需要滿足隔離性,才能滿足一致性。
  • 事務滿足持久化是為了能應對數據庫崩潰的情況。

 

打工四年總結的數據庫知識點

隔離級別

未提交讀(READ UNCOMMITTED)

事務中的修改,即使沒有提交,對其他事務也是可見的。

提交讀(READ COMMITTED)

一個事務只能讀取已經提交的事務所做的修改。換句話說,一個事務所做的修改在提交之前對其他事務是不可見的。

可重復讀(REPEATABLE READ)

保證在同一個事務中多次讀取同樣數據的結果是一樣的。

可串行化(SERIALIZABLE)

強制事務串行執行。

需要加鎖實現,而其它隔離級別通常不需要。

隔離級別 臟讀 不可重復讀 幻影讀 未提交讀 √ √ √ 提交讀 × √ √ 可重復讀 × × √ 可串行化 × × ×

鎖是數據庫系統區別于文件系統的一個關鍵特性。鎖機制用于管理對共享資源的并發訪問。

鎖類型

共享鎖(S Lock)

允許事務讀一行數據

排他鎖(X Lock)

允許事務刪除或者更新一行數據

意向共享鎖(IS Lock)

事務想要獲得一張表中某幾行的共享鎖

意向排他鎖

事務想要獲得一張表中某幾行的排他鎖

MVCC

多版本并發控制(Multi-Version Concurrency Control, MVCC)是 MySQL 的 InnoDB 存儲引擎實現隔離級別的一種具體方式,用于實現提交讀和可重復讀這兩種隔離級別。而未提交讀隔離級別總是讀取最新的數據行,無需使用 MVCC。可串行化隔離級別需要對所有讀取的行都加鎖,單純使用 MVCC 無法實現。

基礎概念

版本號

  • 系統版本號:是一個遞增的數字,每開始一個新的事務,系統版本號就會自動遞增。
  • 事務版本號:事務開始時的系統版本號。

隱藏的列

MVCC 在每行記錄后面都保存著兩個隱藏的列,用來存儲兩個版本號:

  • 創建版本號:指示創建一個數據行的快照時的系統版本號;
  • 刪除版本號:如果該快照的刪除版本號大于當前事務版本號表示該快照有效,否則表示該快照已經被刪除了。

Undo 日志

MVCC 使用到的快照存儲在 Undo 日志中,該日志通過回滾指針把一個數據行(Record)的所有快照連接起來。

 

打工四年總結的數據庫知識點

實現過程

以下實現過程針對可重復讀隔離級別。

當開始一個事務時,該事務的版本號肯定大于當前所有數據行快照的創建版本號,理解這一點很關鍵。數據行快照的創建版本號是創建數據行快照時的系統版本號,系統版本號隨著創建事務而遞增,因此新創建一個事務時,這個事務的系統版本號比之前的系統版本號都大,也就是比所有數據行快照的創建版本號都大。

SELECT

多個事務必須讀取到同一個數據行的快照,并且這個快照是距離現在最近的一個有效快照。但是也有例外,如果有一個事務正在修改該數據行,那么它可以讀取事務本身所做的修改,而不用和其它事務的讀取結果一致。

把沒有對一個數據行做修改的事務稱為 T,T 所要讀取的數據行快照的創建版本號必須小于等于 T 的版本號,因為如果大于 T 的版本號,那么表示該數據行快照是其它事務的最新修改,因此不能去讀取它。除此之外,T 所要讀取的數據行快照的刪除版本號必須是未定義或者大于 T 的版本號,因為如果小于等于 T 的版本號,那么表示該數據行快照是已經被刪除的,不應該去讀取它。

INSERT

將當前系統版本號作為數據行快照的創建版本號。

DELETE

將當前系統版本號作為數據行快照的刪除版本號。

UPDATE

將當前系統版本號作為更新前的數據行快照的刪除版本號,并將當前系統版本號作為更新后的數據行快照的創建版本號。可以理解為先執行 DELETE 后執行 INSERT。

快照讀與當前讀

在可重復讀級別中,通過MVCC機制,雖然讓數據變得可重復讀,但我們讀到的數據可能是歷史數據,是不及時的數據,不是數據庫當前的數據!這在一些對于數據的時效特別敏感的業務中,就很可能出問題。

對于這種讀取歷史數據的方式,我們叫它快照讀 (snapshot read),而讀取數據庫當前版本數據的方式,叫當前讀 (current read)。很顯然,在MVCC中:

快照讀

MVCC 的 SELECT 操作是快照中的數據,不需要進行加鎖操作。

  1. select * from table ….; 

當前讀

MVCC 其它會對數據庫進行修改的操作(INSERT、UPDATE、DELETE)需要進行加鎖操作,從而讀取最新的數據。可以看到 MVCC 并不是完全不用加鎖,而只是避免了 SELECT 的加鎖操作。

 

  1. INSERT 
  2. UPDATE 
  3. DELETE

在進行 SELECT 操作時,可以強制指定進行加鎖操作。以下第一個語句需要加 S 鎖,第二個需要加 X 鎖。

 

  1. select * from table where ? lock in share mode;  
  2. select * from table where ? for update

事務的隔離級別實際上都是定義的當前讀的級別,MySQL為了減少鎖處理(包括等待其它鎖)的時間,提升并發能力,引入了快照讀的概念,使得select不用加鎖。而update、insert這些“當前讀”的隔離性,就需要通過加鎖來實現了。

鎖算法

Record Lock

鎖定一個記錄上的索引,而不是記錄本身。

如果表沒有設置索引,InnoDB 會自動在主鍵上創建隱藏的聚簇索引,因此 Record Locks 依然可以使用。

Gap Lock

鎖定索引之間的間隙,但是不包含索引本身。例如當一個事務執行以下語句,其它事務就不能在 t.c 中插入 15。

  1. SELECT c FROM t WHERE c BETWEEN 10 and 20 FOR UPDATE

Next-Key Lock

它是 Record Locks 和 Gap Locks 的結合,不僅鎖定一個記錄上的索引,也鎖定索引之間的間隙。例如一個索引包含以下值:10, 11, 13, and 20,那么就需要鎖定以下區間:

 

  1. (-∞, 10] 
  2. (10, 11] 
  3. (11, 13] 
  4. (13, 20] 
  5. (20, +∞) 

在 InnoDB 存儲引擎中,SELECT 操作的不可重復讀問題通過 MVCC 得到了解決,而 UPDATE、DELETE 的不可重復讀問題通過 Record Lock 解決,INSERT 的不可重復讀問題是通過 Next-Key Lock(Record Lock + Gap Lock)解決的。

鎖問題

臟讀

臟讀指的是不同事務下,當前事務可以讀取到另外事務未提交的數據。

例如:

  • T1 修改一個數據,T2 隨后讀取這個數據。如果 T1 撤銷了這次修改,那么 T2 讀取的數據是臟數據。

 

打工四年總結的數據庫知識點

不可重復讀

不可重復讀指的是同一事務內多次讀取同一數據集合,讀取到的數據是不一樣的情況。

例如:

  • T2 讀取一個數據,T1 對該數據做了修改。如果 T2 再次讀取這個數據,此時讀取的結果和第一次讀取的結果不同。

 

打工四年總結的數據庫知識點

在 InnoDB 存儲引擎中,SELECT 操作的不可重復讀問題通過 MVCC 得到了解決,而 UPDATE、DELETE 的不可重復讀問題是通過 Record Lock 解決的,INSERT 的不可重復讀問題是通過 Next-Key Lock(Record Lock + Gap Lock)解決的。

Phantom Proble(幻影讀)

  • The so-called phantom problem occurs within a transaction when the same query produces different sets of rows at different times. For example, if a SELECT is executed twice, but returns a row the second time that was not returned the first time, the row is a “phantom” row.

Phantom Proble 是指在同一事務下,連續執行兩次同樣的 sql 語句可能返回不同的結果,第二次的 sql 語句可能會返回之前不存在的行。

幻影讀是一種特殊的不可重復讀問題。

總結

這都是些基礎知識,我沒想到再次回顧大半我都已忘卻了,也慶幸有這樣的假期能夠重新拾起來。

說實話做自媒體后我充電的時間少了很多,也少了很多時間研究技術棧深度,國慶假期我也思考反思了很久,后面準備繼續壓縮自己業余時間,比如看手機看B站的時間壓縮一下,還是得按時充電,目前作息還算規律早睡早起都做到了,我們一起加油喲。

 

責任編輯:未麗燕 來源: 今日頭條
相關推薦

2018-01-25 12:50:33

數據庫OracleROWNUM

2010-05-31 10:19:09

MySQL數據庫時區

2010-05-26 17:40:14

MySQL數據庫

2020-12-24 13:32:31

大數據數據分析SQL

2009-08-06 17:42:32

C#知識點

2010-06-17 16:42:04

UML

2010-08-18 10:52:46

Linux筆試

2022-07-20 00:15:48

SQL數據庫編程語言

2010-07-29 11:31:53

使用DB2

2020-07-01 17:25:28

Redis數據庫內存

2014-06-10 13:44:58

iOSUIImage知識點

2016-12-21 09:55:55

面試JavaScrip總結

2017-12-08 14:26:19

Android面試知識點總結

2011-06-14 15:11:59

ORACLE

2009-06-11 10:05:52

IT人職場程序員

2010-07-30 15:37:53

使用DB2

2010-08-03 15:15:22

使用DB2數據庫

2022-08-16 15:17:37

機器學習算法模型

2021-02-24 09:45:21

數據庫工具技術

2021-09-27 09:18:31

MySQL數據類型
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 亚洲超碰在线观看 | 中文字幕不卡在线观看 | 中文字幕av网站 | 亚洲成av片人久久久 | 一区二区免费高清视频 | 日韩电影免费观看中文字幕 | 国产在线精品一区 | 中文字幕三区 | 国产高潮好爽受不了了夜夜做 | 超碰人人人人 | 日韩中文一区二区三区 | 日本xx视频免费观看 | 精品久久久久一区二区国产 | 97国产精品 | 亚洲日本欧美日韩高观看 | 精品一区二区三区在线视频 | 国产精品美女 | 欧美日韩国产精品一区 | 中文字幕在线免费视频 | 91精品久久久久久久久 | 精精国产视频 | 成人美女免费网站视频 | www.久久久久久久久久久 | 国产精品一区二区免费 | 精品国产不卡一区二区三区 | 日日干天天干 | 夜夜草| 亚洲一区二区三区高清 | 久久久久久91香蕉国产 | 国产中文字幕网 | 视频一区二区在线观看 | 国产91在线视频 | 久热精品在线播放 | 黑人巨大精品欧美一区二区免费 | 国产精品久久久久久一级毛片 | 亚洲在线电影 | 亚洲午夜在线 | 欧美在线观看黄色 | japanhd美女动 | 国产一级一级毛片 | 久久99精品国产自在现线小黄鸭 |