傳播行爲分爲兩種:分爲支持事物的傳播和不支持事物的傳播
一、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的事務配置,操做這個數據鏈接對數據庫進行事務開啓,回滾或關閉操做。函數
如何設計一個關係型數據庫?
![](http://static.javashuo.com/static/loading.gif)
儲存:數據庫最主要就是用來存儲持久化數據的
儲存管理:須要對數據的格式,文件的風格進行管理,即把物理數據經過邏輯和組織的形式表示出來
緩存機制:優化執行效率
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樹
定義
- 根節點至少包括兩個孩子;
- 樹中每一個節點最多含有m個孩子(m>=2);
- 除根節點和葉節點外,其餘每一個節點至少有ceil(m/2)個孩子
- 全部葉子節點都位於同一層;
-
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+樹
定義
B+樹是B樹的變體,其定義基本與B樹相同,除了:
- 非葉子結點的子樹指針與關鍵字個數相同;
- 非葉子結點的子樹指針P[i],指向關鍵字值屬於[K[i], K[i+1])的子樹;
- 非葉子節點僅用來索引,數據都保存在葉子節點中;
- 全部葉子節點均有一個鏈指針指向下一個葉子節點,有利於作範圍統計
B+樹更適合來作索引
- 磁盤讀寫代價更低:B+樹非葉子節點只放索引信息,不存放數據,所以內部節點相對B樹更小,能夠一次性讀取更多數據,減小IO讀寫
- 查詢效率更加穩定:任何信息查找,都必須走一條從根節點到葉子結點的路,全部關鍵字查找長度相同
- 更有利於對數據庫的掃描:只需遍歷葉子節點鏈表便可
Hash索引
根據哈希函數的運算,只須要一次定位就能查到數據所在的頭
優勢:查詢效率高
缺點:
- 只能等值查詢,不能範圍查詢,沒法排序(存放的hash值大小順序,並不能保證和運算前的同樣)
- 不能避免表掃描(哈希函數計算後的哈希值和行指針信息放到bukket中,不一樣索引值存在相同哈希值,還須要訪問bukket的實際數據做比較)
- 不能利用部分索引鍵查詢,由於計算函數值是根據整個組合鍵
- 若是存在大量相同hash值,性能可能很低,不穩定
BitMap索引(位圖)
- 存放的值是固定幾個的話,能夠用來作高效統計
- 鎖的力度很大,修改的時候,在同一位圖的東西都會被鎖住
- 不適合高併發
密集索引
葉子結點不只保存了鍵值,還保存了同一行其餘列的信息 ,因爲密集索引決定了表的物理排列順序,一個表只有一個物理排列順序,因此一個表只能建立一個密集索引
稀疏索引
葉子節點僅保存了鍵位信息以及該行數據的地址
密集索引和稀疏索引的區別
密集索引文件中的每一個搜索碼值都對應一個索引值
稀疏索引文件只爲索引碼的某些值創建索引項
MyISAM:無論是主鍵索引、惟一鍵索引或者普通索引,其索引都屬於稀疏索引
InnoDB:只有一個密集索引,選取規則以下
- 如有定義主鍵,則主鍵做爲密集索引
- 若沒有定義主鍵,該表的第一個惟一非空索引做爲密集索引
- 上面兩種狀況都沒有,內部會生成一個隱藏主鍵
InnoDB數據和索引放在一塊兒,而MyISAM分開存放
如何定位並優化慢查詢SQL?
show variables like '%quer%' 獲取全部變量
set global slow_query_log=on; 打開慢查詢
slow_query_log_file 存放慢查詢日誌路徑
long_query_time 超過該時間就會被記錄
show status like '%slow_queries%' 慢查詢的條數
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。 |
聯合索引的最左匹配原則
- 最左前綴匹配原則,很是重要的原則,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適合場景
- 頻繁執行count語句
- 增刪改不頻繁,查詢很是頻繁
- 沒有事務。
InnoDB適合場景
- 可靠性要求比較高,要求支持事務
- 數據增刪改查都至關頻繁
鎖的劃分
樂觀鎖實現
- 使用數據版本(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的非阻塞讀如何實現
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
![](http://static.javashuo.com/static/loading.gif)
第2次修改數據13爲45
![0](http://static.javashuo.com/static/loading.gif)
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