數據庫必知必會

傳播行爲分爲兩種:分爲支持事物的傳播和不支持事物的傳播

一、PROPAGATION_REQUIRED:(支持事物)若是當前沒有事務,就建立一個新事務,若是當前存在事務,就加入該事務,該設置是最經常使用的設置。mysql

二、PROPAGATION_SUPPORTS:(支持事物)支持當前事務,若是當前存在事務,就加入該事務,若是當前不存在事務,就以非事務執行。‘spring

三、PROPAGATION_MANDATORY:(支持事物)支持當前事務,若是當前存在事務,就加入該事務,若是當前不存在事務,就拋出異常。sql

四、PROPAGATION_REQUIRES_NEW:(支持事物)建立新事務,不管當前存不存在事務,都建立新事務。數據庫

五、PROPAGATION_NOT_SUPPORTED:(不支持事物)以非事務方式執行操做,若是當前存在事務,就把當前事務掛起。緩存

六、PROPAGATION_NEVER:(不支持事物)以非事務方式執行,若是當前存在事務,則拋出異常。數據結構

七、PROPAGATION_NESTED:(不支持事物)若是當前存在事務,則在嵌套事務內執行。若是當前沒有事務,則執行與PROPAGATION_REQUIRED相似的操做。併發

PROPAGATION_NESTED和PROPAGATION_REQUIRED區別

PROPAGATION_NESTED的子事務異常,父事務能夠選擇性回滾,也能夠選擇捕獲異常不回滾。

spring的事務是什麼?與數據庫的事務是否同樣?

本質上實際上是同一個概念,spring的事務是對數據庫的事務的封裝,最後本質的實現仍是在數據庫,假如數據庫不支持事務的話,spring的事務是沒有做用的.數據庫的事務說簡單就只有開啓,回滾和關閉,spring對數據庫事務的包裝,原理就是拿一個數據鏈接,根據spring的事務配置,操做這個數據鏈接對數據庫進行事務開啓,回滾或關閉操做。函數

如何設計一個關係型數據庫?

儲存:數據庫最主要就是用來存儲持久化數據的
 
儲存管理:須要對數據的格式,文件的風格進行管理,即把物理數據經過邏輯和組織的形式表示出來
緩存機制:優化執行效率
SQL解析:方便外界指令來操做數據庫,編譯成機器識別的語言
日誌管理:記錄操做
權限劃分:多用戶管理
容災機制:方便處理異常的狀況
索引管理:提升數據庫查詢
鎖管理:支持併發操做

爲何要使用索引?

數據量大的狀況下,儘可能避免全表掃描,使用索引,能夠大幅提升掃描速度。高併發

什麼樣的信息能成爲索引?

主鍵,惟一鍵等,可讓數據具有惟一性的字段均可以。

索引的數據結構?

二叉樹,B樹,B+樹,Hash,BitMap性能

Mysql數據庫不支持BitMap索引
同時基於MyISAM和InnoDB的引擎不顯示支持Hash索引
對於InnoDB的哈希索引,確切的應該這麼說:
(1)InnoDB用戶沒法手動建立哈希索引,這一層上說,InnoDB確實不支持哈希索引
(2)InnoDB會自調優(self-tuning),若是斷定創建自適應哈希索引(Adaptive Hash Index, AHI),可以提高查詢效率,InnoDB本身會創建相關哈希索引,這一層上說,InnoDB又是支持哈希索引的

B樹

0
 
定義
  • 根節點至少包括兩個孩子;
  • 樹中每一個節點最多含有m個孩子(m>=2);
  • 除根節點和葉節點外,其餘每一個節點至少有ceil(m/2)個孩子
  • 全部葉子節點都位於同一層;
  • 假設每一個非終端節點中包含有n個關鍵字信息,其中

    a) ki(i=1...n)爲關鍵字,且關鍵字按順序升序排序k(i-1)<=ki
    b) 關鍵字的個數n必須知足:[ceil(m/2)-1]<=n<=m-1
    c) 非葉子節點的指針:P[1],P[2],...P[m];其中P[1]指向關鍵字小於k[1]的子樹;P[m]指向關鍵字大於k[m]的子樹;其餘P[i]指向關鍵字屬於(k(i-1),ki)的子樹。

相對於二叉樹,B樹讓每一個索引庫存儲更多東西,減小io次數。

B+樹

0

定義

B+樹是B樹的變體,其定義基本與B樹相同,除了:
  • 非葉子結點的子樹指針與關鍵字個數相同;
  • 非葉子結點的子樹指針P[i],指向關鍵字值屬於[K[i], K[i+1])的子樹;
  • 非葉子節點僅用來索引,數據都保存在葉子節點中;
  • 全部葉子節點均有一個鏈指針指向下一個葉子節點,有利於作範圍統計

B+樹更適合來作索引 

  • 磁盤讀寫代價更低:B+樹非葉子節點只放索引信息,不存放數據,所以內部節點相對B樹更小,能夠一次性讀取更多數據,減小IO讀寫
  • 查詢效率更加穩定:任何信息查找,都必須走一條從根節點到葉子結點的路,全部關鍵字查找長度相同
  • 更有利於對數據庫的掃描:只需遍歷葉子節點鏈表便可

Hash索引

根據哈希函數的運算,只須要一次定位就能查到數據所在的頭
優勢:查詢效率高
缺點:
  • 只能等值查詢,不能範圍查詢,沒法排序(存放的hash值大小順序,並不能保證和運算前的同樣)
  • 不能避免表掃描(哈希函數計算後的哈希值和行指針信息放到bukket中,不一樣索引值存在相同哈希值,還須要訪問bukket的實際數據做比較)
  • 不能利用部分索引鍵查詢,由於計算函數值是根據整個組合鍵
  • 若是存在大量相同hash值,性能可能很低,不穩定

BitMap索引(位圖)

  • 存放的值是固定幾個的話,能夠用來作高效統計
  • 鎖的力度很大,修改的時候,在同一位圖的東西都會被鎖住
  • 不適合高併發

密集索引

葉子結點不只保存了鍵值,還保存了同一行其餘列的信息 ,因爲密集索引決定了表的物理排列順序,一個表只有一個物理排列順序,因此一個表只能建立一個密集索引

稀疏索引

葉子節點僅保存了鍵位信息以及該行數據的地址

密集索引和稀疏索引的區別

密集索引文件中的每一個搜索碼值都對應一個索引值
稀疏索引文件只爲索引碼的某些值創建索引項
0
MyISAM:無論是主鍵索引、惟一鍵索引或者普通索引,其索引都屬於稀疏索引
InnoDB:只有一個密集索引,選取規則以下
  • 如有定義主鍵,則主鍵做爲密集索引
  • 若沒有定義主鍵,該表的第一個惟一非空索引做爲密集索引
  • 上面兩種狀況都沒有,內部會生成一個隱藏主鍵
 
0
 
InnoDB數據和索引放在一塊兒,而MyISAM分開存放

如何定位並優化慢查詢SQL?

  • 根據慢日誌定位慢查詢SQL

show variables like '%quer%' 獲取全部變量
set global slow_query_log=on; 打開慢查詢
slow_query_log_file 存放慢查詢日誌路徑
long_query_time 超過該時間就會被記錄
show status like '%slow_queries%' 慢查詢的條數  
  • 重點關注type和extra

system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > all
type 重要的項,顯示鏈接使用的類型,按最 優到最差的類型排序 說明
system 表僅有一行(=系統表)。這是 const 鏈接類型的一個特例。
const const 用於用常數值比較 PRIMARY KEY 時。當 查詢的表僅有一行時,使用 System。
eq_ref const 用於用常數值比較 PRIMARY KEY 時。當 查詢的表僅有一行時,使用 System。
ref 鏈接不能基於關鍵字選擇單個行,可能查找 到多個符合條件的行。 叫作 ref 是由於索引要 跟某個參考值相比較。這個參考值或者是一 個常數,或者是來自一個表裏的多表查詢的 結果值。
ref_or_null 如同 ref, 可是 MySQL 必須在初次查找的結果 裏找出 null 條目,而後進行二次查找。
index_merge 說明索引合併優化被使用了。
unique_subquery 在某些 IN 查詢中使用此種類型,而不是常規的 ref:value IN (SELECT primary_key FROM single_table WHERE some_expr)
index_subquery 在 某 些 IN 查 詢 中 使 用 此 種 類 型 , 與 unique_subquery 相似,可是查詢的是非惟一 性索引: value IN (SELECT key_column FROM single_table WHERE some_expr)
range 只檢索給定範圍的行,使用一個索引來選擇 行。key 列顯示使用了哪一個索引。當使用=、 <>、>、>=、<、<=、IS NULL、<=>、BETWEEN 或者 IN 操做符,用常量比較關鍵字列時,可 以使用 range。
index 全表掃描,只是掃描表的時候按照索引次序 進行而不是行。主要優勢就是避免了排序, 可是開銷仍然很是大。
all 最壞的狀況,從頭至尾全表掃描。

extra 中出現如下 2 項意味着 MYSQL 根本不能使用索引,效率會受到重大影響。應儘量對此進行優化
extra 項 說明
Using filesort 表示 MySQL 會對結果使用一個外部索引排序,而不是從表裏按索引次序讀到相關內容。可能在內存或者磁盤上進行排序。MySQL 中沒法利用索引完成的排序操做稱爲「文件排序」
Using temporary 表示 MySQL 在對查詢結果排序時使用臨時表。常見於排序 order by 和分組查詢 group by。
  • 修改SQL並讓其儘可能走索引

聯合索引的最左匹配原則

  • 最左前綴匹配原則,很是重要的原則,MySQL 會一直向右匹配直到遇到範圍查詢(> , < ,between,like)就中止匹配。好比 a = 1 and b = 2 and c > 3 and d = 4,若是創建的是(a,b,c,d)這種順序的索引,那麼 d 是用不到索引的,可是若是創建的是 (a,b,d,c)這種順序的索引的話,那麼就沒問題,並且 a,b,d 的順序能夠隨意調換。
  • = 和 in 能夠亂序,好比 a = 1 and b = 2 and c = 3 創建 (a,b,c)索引能夠任意順序,MYSQL的查詢優化器會幫忙優化
   成因?
    mysql建立複合索引的規則是首先會對複合索引的最左邊,也就是索引中的第一個字段進行排序,在第一個字段排序的基礎上,在對索引上第二個字段進行排序,其實就像是實現相似order by 字段1,字段2這樣的排序規則,那麼第一個字段是絕對有序的,而第二個字段就是無序的了,所以通常狀況下直接只用第二個字段判斷是用不到索引的,這就是爲何mysql要強調聯合索引最左匹配原則的緣由。
索引是鍵的越多越好嗎?
  • 數據量小的表不須要創建索引,創建會增長額外的索引開銷
  • 數據變動須要維護索引,意味着更多的索引意味着更多的維護成本
  • 更多的索引也須要跟多的存儲空間
MyISAM與InnoDB關於鎖方面的區別
  • MyISAM默認用的是表級鎖,不支持行級鎖

  • InnoDB默認用的是行級鎖,也支持表級鎖(innobdb沒有使用索引使用的是表鎖,使用索引用的是行鎖)

  • InnoDB對查詢優化,默認不加鎖

MyISAM適合場景

  • 頻繁執行count語句
  • 增刪改不頻繁,查詢很是頻繁
  • 沒有事務。

InnoDB適合場景

  • 可靠性要求比較高,要求支持事務
  • 數據增刪改查都至關頻繁

鎖的劃分 

0

樂觀鎖實現

  • 使用數據版本(Version)記錄機制實現
  • 使用時間戳字段 

事務的四大特性(ACID)

  • 原子性(Atomic)
  • 一致性(Consistency)
  • 隔離性(Isolation)
  • 持久性(Durability)

當前讀與快照讀

  1.當前讀

  • select … lock in share mode,select … for update
  • update,delete,insert

  update語句,先select數據最新版本,再update,因此是當前讀,delete和insert同理。

  2.快照讀:不加鎖的非阻塞讀,select

事務隔離級別以及各級下的併發訪問問題

  • 更新丟失(即一個事務的更新覆蓋了另外一個事務的更新)
  • 髒讀(讀取了另外一個更新事務,更新以前的數據)
  • 不可重複讀(其餘事務的修改,當前事務對同一條數據,每次讀取結果不同)
  • 幻讀(指新插入的行,讀到本來存在行的更新結果不算,只在當前讀下,一個事務(同一個read view)在先後兩次查詢同一範圍的時候,後一次查詢看到了前一次查詢沒有看到
事務的隔離級別 更新丟失 髒讀 不可重複讀 幻讀
未提交讀 避免 發生 發生 發生
已提交讀 避免 避免 發生 發生
可重複讀 避免 避免 避免 發生
串行化 避免 避免 避免 避免

RC,RR級別下的INNODB的非阻塞讀如何實現

  • 數據行裏的DB_TRX_ID、DB_ROLL_PTR、DB_ROW_ID字段

  • undo日誌(每操做一次數據,順序增長一個日誌)

  • read view(快照本照了)

 1.數據行DB_TRX_ID、DB_ROLL_PTR、DB_ROW_ID字段

  DB_TRX_ID(最後一次操做事務ID)

  DB_ROLL_PTR(回滾指針)

  DB_ROW_ID(InnoDB表中在沒有默認主鍵的狀況下會生成一個6字節空間的自動增加主鍵)

 2.undo日誌

    第1次修改數據12爲32

    

 第2次修改數據13爲45

    0

 3.read view

    RC下,快照讀和當前讀結果同樣,緣由是每次快照讀會建立一個新的read view

    RR下,快照讀若是在修改後讀,結果會和當前讀同樣,不然不同,緣由是第一條快照讀會建立一個read view,後面再調用快照也是使用這個read view

InnoDB可重複讀隔離級別下如何避免幻讀

  • 表象:快照讀(非阻塞讀)—僞MVCC

  • 內在:next-key鎖,(行鎖+gap鎖)

  • Gap鎖:間隙鎖,鎖定一個範圍,不包括記錄自己,目的是爲了防止同一事務的兩次當前讀出現幻讀的狀況,RR級別及以上纔有。

對主鍵索引或者惟一索引會用Gap鎖

  • 若是where條件所有命中,則不會用Gap鎖,只會加記錄鎖
  • 若是where條件部分命中或者全不命中,則會加Gap鎖
Gap鎖會用在非惟一索引或者不走索引的當前讀中

關鍵語法

  GROUP BY:select裏面的列,只能是group by裏出現的列,帶有函數的列,其餘表的列。(僅限於group by中的列是主鍵或者惟一非空列)
  HAVING:過濾組
  同一sql的順序:WHERE>GROUP BY>HAVING
相關文章
相關標籤/搜索