MySQL事務處理的特性原子性(Atomicity):事務開始後所有操作,要麼全部做完,要麼全部不做,不可能停滯在中間環節。事務執行過程中出錯,會回滾到事務開始前的狀態,所有的操作就像沒有發生一樣。也就是說事務是一個不可分割的整體,就像化學中學過的原子,是物質構成的基本單位。一致性(Consistency):事務開始前和結束後,資料庫的完整性約束沒有被破壞 。比如A向B轉賬,不可能A扣了錢,B卻沒收到。隔離性(Isolation):同一時間,只允許一個事務請求同一資料,不同的事務之間彼此沒有任何干擾。比如A正在從一張銀行卡中取錢,在A取錢的過程結束前,B不能向這張卡轉賬。永續性(Durability):事務完成後,事務對資料庫的所有更新將被儲存到資料庫,不能回滾。事務的併發問題髒讀:事務A讀取了事務B更新的資料,然後B回滾操作,那麼A讀取到的資料是髒資料不可重複讀:事務 A 多次讀取同一資料,事務 B 在事務A多次讀取的過程中,對資料作了更新並提交,導致事務A多次讀取同一資料時,結果 不一致。幻讀:系統管理員A將資料庫中所有學生的成績從具體分數改為ABCDE等級,但是系統管理員B就在這個時候插入了一條具體分數的記錄,當系統管理員A改結束後發現還有一條記錄沒有改過來,就好像發生了幻覺一樣,這就叫幻讀。
小結:不可重複讀的和幻讀很容易混淆,不可重複讀側重於修改,幻讀側重於新增或刪除。解決不可重複讀的問題只需鎖住滿足條件的行,解決幻讀需要鎖表
索引索引是什麼:索引是為了加快查詢速度的一種資料結構。
索引的作用:高效查詢資料。
索引的結構:MyISAM和InnoDB都是採用B+樹作為資料結構。
下面是B+tree的建樹過程
依次插入6 10 4 14 5 11 15 3 2 12 1 7 8 8 6 3 6 21 5 15 15 6 32 23 45 65 7 8 6 5
雖說MyISAM與InnoDB的資料結構都是B+樹,但是其實現方式卻截然不同,具體的索引實現詳見部落格:https://blog.csdn.net/b_x_p/article/details/86434387
MYSQL為什麼最終要去選擇B+TREE?1、B+TREE是B TREE的變種,B TREE能解決的問題,B+TREE也能夠解決(降低樹的高度,增大節點儲存資料量)2、 B+TREE掃庫和掃表能力更強,如果我們要根據索引去進行資料表的掃描,對B TREE進行掃描,需要把整棵樹遍歷一遍,而B+TREE只需要遍歷他的所有葉子節點即可(葉子節點之間有引用)。3、B+TREE磁碟讀寫能力更強,他的根節點和支節點不儲存資料區,所有根節點和支節點同樣大小的情況下,儲存的關鍵字要比B TREE要多。而葉子節點不儲存子節點引用。所以,B+TREE讀寫一次磁碟載入的關鍵字比B TREE更多。4、B+TREE排序能力更強,如上面的圖中可以看出,B+TREE天然具有排序功能。5、B+TREE查詢效率更加穩定,每次查詢資料,查詢IO次數一定是穩定的。當然這個每個人的理解都不同,因為在B TREE如果根節點命中直接返回,確實效率更高。什麼情況適合建立索引:表的主鍵和外來鍵需要建立索引;資料量超過300的需要建立索引;經常出現在where字句中的欄位;經常用於連線兩張表的列;經常需要範圍查詢的列,因為索引已經排序,所以指定的範圍是連續的;經常需要排列的列,理由同上;索引的缺點:更新資料時需要對索引進行更新;索引需要佔用一定的空間。資料庫最佳化的思路這個我借鑑了慕課上關於資料庫最佳化的課程。
1.SQL語句最佳化
1)應儘量避免在 where 子句中使用!=或<>運算子,否則將引擎放棄使用索引而進行全表掃描。
2)應儘量避免在 where 子句中對欄位進行 null 值判斷,否則將導致引擎放棄使用索引而進行全表掃描,如:
select id from t where num is null
可以在num上設定預設值0,確保表中num列沒有null值,然後這樣查詢:
select id from t where num=0
3)很多時候用 exists 代替 in 是一個好的選擇
4)用Where子句替換HAVING 子句 因為HAVING 只會在檢索出所有記錄之後才對結果集進行過濾
2.索引最佳化
看上文索引
3.資料庫結構最佳化
1)正規化最佳化: 比如消除冗餘(節省空間。。)
2)反正規化最佳化:比如適當加冗餘等(減少join)
3)拆分表: 分割槽將資料在物理上分隔開,不同分割槽的資料可以制定儲存在處於不同磁碟上的資料檔案裡。這樣,當對這個表進行查詢時,只需要在表分割槽中進行掃描,而不必進行全表掃描,明顯縮短了查詢時間,另外處於不同磁碟的分割槽也將對這個表的資料傳輸分散在不同的磁碟I/O,一個精心設定的分割槽可以將資料傳輸對磁碟I/O競爭均勻地分散開。對資料量大的時時表可採取此方法。可按月自動建表分割槽。
4)拆分其實又分垂直拆分和水平拆分: 案例: 簡單購物系統暫設涉及如下表: 1.產品表(資料量10w,穩定) 2.訂單表(資料量200w,且有增長趨勢) 3.使用者表 (資料量100w,且有增長趨勢) 以mysql為例講述下水平拆分和垂直拆分,mysql能容忍的數量級在百萬靜態資料可以到千萬 垂直拆分:解決問題:表與表之間的io競爭 不解決問題:單表中資料量增長出現的壓力 方案: 把產品表和使用者表放到一個server上 訂單表單獨放到一個server上 水平拆分: 解決問題:單表中資料量增長出現的壓力 不解決問題:表與表之間的io爭奪
方案: 使用者表透過性別拆分為男使用者表和女使用者表 訂單表透過已完成和完成中拆分為已完成訂單和未完成訂單 產品表 未完成訂單放一個server上 已完成訂單表盒男使用者表放一個server上 女使用者表放一個server上(女的愛購物 哈哈)
4.伺服器硬體最佳化
InnoDB儲存引擎InnoDB是預設的事務型儲存引擎,也是最重要,使用最廣泛的儲存引擎。在沒有特殊情況下,一般優先使用InnoDB儲存引擎。
1、資料儲存形式使用InnoDB時,會將資料表分為.frm 和 idb兩個檔案進行儲存。
2、鎖的粒度InnoDB採用MVCC(多版本併發控制)來支援高併發,InnoDB實現了四個隔離級別,預設級別是REPETABLE READ,並透過間隙鎖策略防止幻讀的出現。它的鎖粒度是行鎖。【透過MVCC實現,MVCC在稍後會進行介紹】
3、事務InnoDB是典型的事務型儲存引擎,並且透過一些機制和工具,支援真正的熱備份。
4、資料的儲存特點InnoDB表是基於聚簇索引(另一篇部落格有介紹)建立的,聚簇索引對主鍵的查詢有很高的效能,不過他的二級索引(非主鍵索引)必須包含主鍵列,索引其他的索引會很大。
MyISAM儲存引擎1、資料儲存形式
MyISAM採用的是索引與資料分離的形式,將資料儲存在三個檔案中.frm.MYD,.MYIs。
2、鎖的粒度
MyISAM不支援行鎖,所以讀取時對錶加上共享鎖,在寫入時對錶加上排他鎖。由於是對整張表加鎖,相比InnoDB,在併發寫入時效率很低。
3、事務
MyISAM不支援事務。
4、資料的儲存特點
MyISAM是基於非聚簇索引進行儲存的。
5、其他
MyISAM提供了大量的特性,包括全文索引,壓縮,空間函式,延遲更新索引鍵等。
進行壓縮後的表是不能進行修改的,但是壓縮表可以極大減少磁碟佔用空間,因此也可以減少磁碟IO,從而提供查詢效能。
全文索引,是一種基於分詞建立的索引,可以支援複雜的查詢。
延遲更新索引鍵,不會將更新的索引資料立即寫入到磁碟,而是會寫到記憶體中的緩衝區中,只有在清除緩衝區時候才會將對應的索引寫入磁碟,這種方式大大提升了寫入效能。