天天看點

「資料庫」MySQL 那麼多資料引擎 , 真的都有在用嗎?

作者:架構思考

一 . 前言

總是看到有說MySQL某個資料引擎哪裡哪裡有問題的 , 讓我一度懷疑我是不是Mysql 用的不對 , 隻會用InnoDB 建表 . 看 MyISAM 的表也沒超過10次.

是以我非常好奇 , 資料庫的存儲引擎 , 大家真的在用嗎?

MySQL 官方文檔:: MySQL 5.7 Reference Manual :: 15 Alternative Storage Engines

二. 涉及的引擎

2.1 不同存儲引擎的特性

「資料庫」MySQL 那麼多資料引擎 , 真的都有在用嗎?
「資料庫」MySQL 那麼多資料引擎 , 真的都有在用嗎?
修改引擎的相關指令
// 檢視 MySQL 版本 (不同版本對于存儲引擎的支援不一樣)
SELECT VERSION();

// 檢視支援的引擎
show engines;

// 修改引擎類型
alter table table_name engine=innodb;           

三. 引擎的選擇

了解存儲引擎的差別隻是一方面 , 更重要的是在何種場景下應該選擇哪些存儲引擎. 存儲引擎使用最多的應該是四種 : InnoDB , MyISAM , Archive , Memory .

但是實際上真正可能用的多的 , 隻會是 InnoDB 和 MyISAM

3.1 引擎的選擇

MySQL 各個存儲引擎的使用空間可以說越來越小了, 比如 Memory , 鎖是表鎖 , 又不能持久化資料. 也許業務場景中唯一的作用就是節約成本 , 不用搭一套Redis .

但是都上雲了 , MySQL 伺服器記憶體的開銷 , 相對價格也不會便宜到哪去.

而針對于 csv 引擎 , 其實就是存儲CSV檔案, 那麼搞一套OSS系統存這些可能更便宜.

而更有價值的可能就是各種圖引擎或者特殊功能的引擎 , 但是往往都會有更好的替代品.

對于這些引擎總結起來就一句話 : 除非需要用到某些InnoDB 不具備的特性,并且沒有其他辦 怯可以替代,否則都應該優先選擇Inno DB 引擎 <高性能MySQL>

那麼剩下的 , 就是 InnoDB 和 MylSAM 了~~~

3.2 InnoDB 和 MylSAM 的選擇

MySQL 的引擎太多了, 用的最多的應該就是 InnoDB 和 MylSAM, 這也是涉及篇幅最大的兩個資料引擎.

兩個存儲引擎的差別很多 , 但是正在的核心集中在以下幾個方面 :

是否支援事務

MyISAM 本身是不支援事務的 ,

事務就很重要了 , 如果業務線比較長 ,而且強制要求資料完整一緻. InnoDB.

如果本身就是單次操作或者可以通過 TCC 的方式進行復原 , 那麼選擇 MyISAM 也不會對業務産生什麼影響.

MVCC

MyISAM 是不支援 MVCC 的 , MVCC 是 多版本并發控制 , 如果對事務接觸比較深 , 就會了解到四種隔離級别. 而 MySQL 的事務隔離級别就是基于 MVCC 進行實作.

外鍵

外鍵通常用來保證資料的完整性 ,A表的字段是B表的主鍵,就可以為該字段設定外鍵限制。 InnoDB 支援外鍵而 MyISAM 不支援.

外鍵其實很讨厭 , 删除資料時如果有外鍵關聯 , 會導緻資料删除不掉,處理起來也會非常複雜. 同時由于強調多表關聯 , 也會導緻性能較差

但是外鍵好處也很強大 , 保證了資料的一緻和完整. 再也不怕使用者未删除 ,而屬性被删除的問題.

不過個人接觸的幾個系統裡面就一個使用了外鍵 ,是以這個特性不能影響到引擎的選擇~~

鎖粒度

鎖粒度通常是指行鎖和表鎖. InnoDB 鎖粒度為行鎖 ,而 MyISAM 為表鎖.

行鎖和表鎖不能一概而論 :

  • 表鎖面積更大 , 但是申請鎖隻需要進行一次 ,單次鎖的處理時間更短
  • 行鎖面積小 , 但是需要申請多次鎖 , 單次處理的時間更長

四 . 引擎的對比

了解理論還是不夠 , 是以期望能從資料上看一看 , 兩個存儲引擎到底差了多少 . 實際業務中有沒有必要使用特殊的引擎建表

4.1 InnoDB 與 MylSAM 的性能差距

MyISAM 更快的原因
// 索引不同 :  
- MyISAM 隻有三個檔案:索引檔案,表結構檔案,資料檔案
- InnerDB 基于 BTree 的索引方法
> 宏觀 : MyISAM 直接加載索引檔案到記憶體中,由于索引檔案的資料量更少,相同時間加載的索引資料就更多
> 微觀 :InnerDB 尋址需要查詢到塊,再在塊中找到對應的行,但是MyISAM查詢資料很快,直接辨別的OFFSET位址


// 事務 :
- InnerDB 處理時需要維護事務,越複雜的場景這種損耗就會越高

// 緩存機制的不同 :
- MyISAM 使用 KeyCache ,将頻繁通路的索引塊直接放到記憶體中 
- InnerDB 使用 BufferPool ,會緩存資料和索引
> 相對而言MyISAM能夠緩存的資料更多,實際操作也能發現,第二次查詢InnerDB需要 10 秒,而MyISAM隻用 1 秒           

4.2 了解事務

上面列舉了一堆事務和性能什麼什麼的,但是不論用什麼引擎,都需要深入了解性能和事務的直接聯系。

首先事務的原理是什麼 , 從單機事務的角度來說 ,事務主要是基于MySQL來實作 ,簡單來說就是從 START TRANSACTION 來開啟事務 ,到 COMMIT 結束事務 。

而看似簡單的兩個步驟 ,整個在InnerDB中的執行過程是很長的。

以 InnerDB 為例 , 該引擎為事務提供了四種隔離級别 : 讀未送出 , 讀已送出 , 可重複讀 , 可串行化。 為了實作這四種隔離級别 ,InnerDB 對資料進行了加鎖 , MVCC , lock in share mode 等操作 。

就光加鎖這一項,就限制了并發的能力。而MVCC機制帶來的快照,同樣會對性能有所影響。其他的引擎同理

// PS : 性能名額是絕對的嗎? (100萬資料)
- READ_UNCOMMITTED : 讀未送出 >> 58 秒
- READ_COMMITTED : 讀已送出 >> 55 秒
- REPEATABLE_READ : 可重複讀 >> 35 秒           

很奇怪不是 , 為什麼我們看到的越嚴格的隔離級别反而少了時間 :

  • 因為性能和鎖挂鈎 ,而鎖往往隻會在複雜的業務場景中才會有沖突,才會存在并發的問題,我這裡就是單純的寫,本身并不會出現什麼鎖的競争,也就沒什麼事務的問題。

4.3 了解外鍵

InnerDB 的外鍵這東西,用好了妥妥的可靠性小助手,再也不怕某個資料不存在而作一堆查詢和判斷。資料的完備性大大的提升。

但是這功能沒用好,簡直能把人惡心死。外鍵的設計,是需要對系統有很深的了解的,哪些資料應該綁定,哪些資料不應該建立耦合關系很重要。

但是現在的系統設計思路,會考慮邏輯删除資料,這個時候外鍵的作用就很小了。

而外鍵同樣是會對性能帶來損耗的 :

外鍵的目的在于綁定多張表之間的關系,外鍵在進行子表的寫入操作時,是會對主表加共享鎖,而一旦加了鎖,在并發的場景下,就會有性能的問題。

綜合考慮下 : 外鍵的功能僅适用于特殊場景下的完整性限制,而在并發的需求下,能不用就不用吧

總結

本着學習的目的了解了這些 , 雖然MySQL 本身還支援很多種其他的引擎 , 但是最好還是不要嘗鮮. 用的時候一時爽 , 回頭上雲或者切庫的時候 , 那怕是後悔的不得了.

一般業務裡面其實基本上都會選用 InnoDB , 極個别場景會選用 MyISAM, 其實其他的引擎都可以用外部元件來解決. Redis ,MongoDB , ES 就是用來解決這些問題的 , 是以已經沒有什麼理由非要用 MyISAM 了,而其他的引擎,基本上不需要在生産上實踐

而伴随着分庫分表的流行 , 加上很多公司會選擇把大資料的計算交給大資料部門來處理, 對 MySQL 的壓力是在逐漸變小的.

另外需要注意,性能這東西并不是絕對的,這篇文章不好實踐,也不好追代碼,都是看看别人的部落格,然後了解吸收後用自己的話表述出來,也不知道是不是真的~~~

附錄 : 各種存儲引擎

InnoDB :
  • InnoDB 的資料存儲在表空間( tablespace )中
  • InnoDB 采用MVCC 來支援高井發,并且實作了四個标準的隔離級别
  • InnoDB 表是基于聚簇索引建立的
MylSAM
  • MyISAM 提供了全文索引、壓縮、空間函數( GIS ) 等,但My ISAM 不支援事務和行級
  • MyISAM 會将表存儲在兩個檔案中: 資料檔案和索引檔案,分别以.MYD 和. MYI 為擴充名
  • MyISAM 表可以包含動态或者靜态(長度固定)行。
  • 可以使用myisa 1叩a c k 對My ISAM 表進行壓縮(也叫打包pack ), 壓縮表是不能進行修 改的
Archive 引擎
  • Archive 存儲引擎隻支援INSERT 和SELECT 操作 , Archive 引擎會緩存所有的寫并利用zlib 對插入的行進行壓縮 , 磁盤 IO 更少
  • 表适合日志和資料采集類應用
  • 支援行級鎖和專用的緩沖區,是以可以實作高并發的插入
Blackhole 引擎 (問題太多 , 不推薦)
  • 會丢棄所有插入的資料,不做任何儲存。但是伺服器會記錄Blackhole 表的日志,是以可以用于複制資料到備庫,或者隻是簡單地記錄到日志
  • 在一些特殊的複制架構和日志稽核時發揮作用。
csv 引擎
  • 将普通的csv 檔案(逗号分割值的檔案)作為MySQL 的表來處理
  • 不支援索引。csv 引擎可以在資料庫運作時拷入或者拷出檔案
  • 将 Excel 等電子表格軟體中的資料存儲為csv 檔案,然後複制到MySQL 資料目錄下
Federated 引擎
  • 代理引擎 : 會建立一個到遠端MySQL 伺服器的用戶端連接配接,井将查詢傳輸到遠端伺服器執行,然後提取或者發送需要的資料。
Memory 引擎
  • 如果需要快速地通路資料,并且這些資料不會被修改,重新開機以後丢失也沒有關系,那麼使用Memory 表
  • Memory 表至少比MyISAM 表要快一個數量級
  • Memroy 表是表級鎖,是以并發寫入的性能較差
  • 每行長度固定 , 部分記憶體的搜費
Merge 引擎
  • Merge 表是由多個My ISAM 表合并而來的虛拟表
  • 可以用于将MySQL 用于日志或者資料倉庫類應用

文章來源:https://juejin.cn/post/7173296499726483470

繼續閱讀