1、常見的MySql引擎
1.1、什麼是MySql引擎?
數據庫引擎是用於存儲、處理和保護數據的核心服務。利用數據庫引擎可控制訪問權限並快速處理事務,從而滿足企業內大多數需要處理大量數據的應用程序的要求。使用存儲引擎創建用於聯機事務或聯機分析處理數據的關係數據庫。這包括創建用於存儲數據的表和用於查看、管理和保護數據安全的數據庫對象(如索引、視圖和存儲過程)。
1.2、存儲引擎的作用是什麼?
- 設計並創建數據庫以保存系統所需的關係或XML文檔。
- 實現系統以訪問和更改數據庫中存儲的數據。包括實現網站或使用數據的應用程序,還包括生成使用SQL-Server工具和實用工具以使用數據的過程。
- 爲單位或客戶部署實現的系統。
- 提供日常管理支持以優化數據庫的性能。
1.3、爲什麼要合理選擇數據庫存儲引擎?
MySql中的數據用各種不同的技術存儲在文件(或者內存)中,這些技術中的每一種技術都使用不同的存儲機制、索引技巧、鎖定水平並且最終提供廣泛的不同的功能和能力。通過選擇不同的技術(存儲引擎),你能夠獲得額外的速度或者功能,從而改善你的應用的整體功能。
這些不同的技術以及配套的相關功能在MySQL中被稱作存儲引擎(也稱作表類型)。MySQL默認配置了許多不同的存儲引擎,可以預先設置或者在MySQL服務器中啓用。你可以選擇適用於服務器、數據庫和表格的存儲引擎,以便在選擇如何存儲你的信息、如何檢索這些信息以及你需要你的數據結合什麼性能和功能的時候爲你提供最大的靈活性。
下圖是我的mysql引擎配置情況:
1.4、InnoDB(默認的存儲引擎)
InnoDB是一個事務型的存儲引擎,它給MySql提供了具有提交、回滾、崩潰恢復能力的事務安全(ACID兼容)存儲引擎,有行級鎖定和外鍵約束。
InnoDB是爲處理巨大數據量時的最大性能設計,它的CPU效率可能是其他基於磁盤關係數據庫引擎所不能匹敵的。
InnoDB引擎提供了對數據庫ACID事務的支持,並且實現了SQL標準的四種隔離級別。該引擎還提供行級鎖和外鍵約束,它的設計目的是處理大容量數據庫系統,它本身其實就是基於MySql後臺的完整數據庫系統。MySql運行時Innodb會在內存中建立緩衝池,用於緩衝數據和索引。當需要使用數據庫事務時,該引擎是首選。
適用場景:
- 經常更新的表,適合處理多重併發的更新請求。
- 需要支持數據庫事務時。
- 需要外鍵約束時。
- 支持自動增加列屬性auto_increment。
- 可以從災難中恢復時(通過bin-log日誌等)。
什麼是事務?簡稱ACID
- 事務的原子性(Atomicity):指一個事務要麼全部執行,要麼全部不執行。
- 事務的一致性(Consistency):指事務的運行並不能改變數據庫中數據的一致性。例如,完整性約束了a+b=10,如果一個事務改變了a,那麼b也要隨之改變。
- 事務的獨立性(Isolation):事務的獨立性也成爲隔離性,是指兩個以上的事務不會出現交錯執行的狀態。因爲交錯執行可能會導致數據的一致性不能得到保障。
- 事務的持久性(Durability):事務的持久性是指事務執行成功之後,該事物鎖數據庫所做的更改是持久保存在數據庫中的,不會無緣無故的回滾到之前的狀態。
1.5、MyIsam
MyIsam是MySql V5.1之前的默認存儲引擎,在此版本之後默認引擎改爲了InnoDB。
MyIsam沒有提供對數據庫事務的支持,也不支持行級鎖和外鍵約束,因此當INSERT(插入)或UPDATE(更新)數據時即寫操作需要鎖定整個表,效率會更低一些。
MyIsam引擎獨立於操作系統,也就是可以在Windows上使用,也可以比較簡單的將數據轉移到Linux操作系統上去。(MyIsam引擎在創建表的時候,會創建三個文件,一個是.frm文件用於存儲表的定義,一個是.MYD文件用於存儲表的數據,另一個是.MYI文件用於存儲索引。操作系統操作大文件的速度是比較慢的,這樣將表分爲3個文件,那麼.MYD這個文件單獨來存放數據自然可以優化數據庫的查詢等操作。有索引管理和字段管理。MyIsam還是用一種表格鎖定的機制,用來優化併發的讀寫操作,其代價是你需要經常運行OPTIMIZE TABLE命令來恢復被更新機制鎖浪費的空間。)
適用場景:
- 不支持事務的設計,但是不代表有着事務操作的項目就不能用Mylsam引擎,可以在service層根據自己業務需求進行相應的控制。
- 不支持外鍵的表設計。
- 查詢速度快,如果數據庫insert和update的操作較多的話比較適用。
- 如果讀操作的需求遠遠超過寫操作,並且不需要數據庫事務的支持,那麼MyIsam引擎是比較好的選擇。
1.6、InnoDB引擎和MyIsam引擎的對比
存儲引擎 | MyIsam | Innodb |
事務 | 不支持事務處理等高級處理 | 支持 |
外鍵 | 不支持外鍵 | 支持 |
鎖的粒度 | 鎖的粒度是表級 | 鎖的粒度是行級 |
全文類型索引 | 支持 | mysql5.6以後支持 |
MyIsam相對簡單,所以在效率上要優於InnoDB,小型應用可以考慮使用MyIsam。
當你的數據庫有大量的寫入、更新操作,而查詢比較少或者數據完整性要求比較高的時候就選擇InnoDB。
當你的數據庫以查詢爲主,而更新和寫入操作較少,並且業務方面完整性要求不是那麼嚴格,就選擇使用MyIsam。
鎖的粒度主要有以下幾種:
- 行鎖:粒度最小,併發性最高。
- 頁鎖:一次鎖定一頁。25個行鎖可以升級爲一個頁鎖。
- 表鎖:粒度大,併發性低。
- 數據庫鎖:控制整個數據庫操作。
樂觀鎖、悲觀鎖:
樂觀鎖:相對悲觀鎖而言,樂觀鎖假設認爲數據一般情況下不會造成衝突,所在在數據進行提交更新時,纔會正式對數據的衝突與否進行檢測,如果發生了衝突,則返回用戶錯誤信息,讓用戶決定如何去改,一般樂觀鎖的實現方式就是記錄數據版本。
舉個例子:客戶端A和客戶端B同時借閱一本書(只有一本),這種情況下勢必只有一個客戶端能夠借閱到這本書。這個時候爲了防止衝突,可以在數據表中加入version字段,爲了輔助判斷數據修改的條件,我們對數據的每一次更新,都讓version加1(version初始值默認爲1)。當A借閱更新時,要判斷當前更新數據後的lastversion(上一版本號)值跟A第一次從數據庫中查詢到的version值是否一致,如果一致就更新;如果不一致,那麼就說明B搶在A前頭更新了數據,把最後一本書借閱走了。那麼A的更新數據將會被視爲過期,會駁回其借閱請求。
藉助下表來演示,A和B正在搶老人與海這本書,書的數量num爲1,當前數據版本號version爲1
ID | bookname | num | version(隱藏) |
0001 | 老人與海 | 1 | 1 |
如果A借閱了這本書,那麼num將更新爲0,version更新爲2
ID | bookname | num | version(隱藏) | lastversion(隱藏) |
0001 | 老人與海 | 0 | 2 | 1 |
A更新數據後發現lastversion與第一次從數據庫中查出的version相同,那麼A更新數據成功,這個時候B如果再來更新數據,那麼情況如下表所示
ID | bookname | num | version(隱藏) | lastversion(隱藏) |
0001 | 老人與海 | 0 | 3 | 2 |
這時lastversion(值爲2)與B第一次查出來的version(值爲1)不相等,那麼系統則告知B更新數據過期,駁回更新請求。
悲觀鎖:顧名思義,就是很悲觀,每次取拿數據的時候都認爲別人會修改,所以每次拿數據時都要上鎖,這樣別人來拿數據時就會block(受阻)知道它拿掉鎖。傳統的關係型數據庫中就有很多這種鎖機制,比如行鎖、表鎖、讀鎖、寫鎖等,都是在操作之前先上鎖。