数据库引擎讲解_1
1. 各個存儲引擎,來看看MYSQL的各個存儲引擎,當然這么多的存儲引擎,我們重點講兩個吧,其實這些我下面都有介紹,但是重點我要講哪個呢,重點講MYISAM,和InnoDB,因為這兩個存儲引擎它是比較有代表性意義的,我們來看MYSQL的存儲引擎其實我們在講MYSQL的歷史的時候,我們提到了一個,MYSQL最早這個東西是為了是為了做存儲倉庫,所以其實它更多的是對查詢上面做了優化,而沒有對事物做控制,所以最早的版本MYSQL里面的存儲引擎只有一個叫ISAM,那么這個ISAM呢,有的同學會認為是IS’AM,不是這個意思,它是四個單詞的簡寫,哪四個單詞呢,其實這個四個單詞恰恰就定義到了數據庫的一個特點,I指的是誰能不能猜出來,I是indexed索引,S是誰呢,S是Sequential序列,然后A是誰呢,A是Access,M是誰呢,M是Method,注意直譯過來就是索引序列訪問法,通過這個名字我么就可以定義到,其實這個引擎更多的是為了解決什么問題,優化查詢,ISAM是一個定義明確且歷經時間考驗的數據表格管理方法,他在設計的時候就考慮到數據庫被查詢的次數就要遠大于更新的次數,因此,ISAM執行讀操作的速度很快,而且不占用大量的內存和存儲資源,ISAM有兩個主要的不足之處,在于他不支持事務處理,這有一個歷史遺留問題,也就是說在8幾年那個年代,其實數據庫還沒有提出事務ACID的特點,什么原子性,一致性,隔離性,持久性,所以他更多的是考慮做數據存儲,更多的是為查詢做準備,還沒有考慮到事務,那這里我們一定要記住,是不是索引序列訪問法,是不是不支持事務,記住它是不支持事務的,第二個是什么呢,第二個缺點是不能夠容錯,如果你的硬盤崩潰掉了,那么數據文件就無法恢復了,這是一個非常致命的問題,如果你把ISAM用在關鍵任務應用程序里,那就需要經常備份你經常使用的數據,通過其復制特點,MYSQL能夠支持這樣的備份應用數據,MYSQL是可以實時備份的,你不備份,一旦蹦了,數據就丟了,那其實即便是實時備份,你想想他是不是也有可能會丟,那么在這里我們需要注意的一點是,使用ISAM注意,必須經常備份所有的實時數據,那我是不是得經常備份啊,因為這個動作真要去做,而且像這個ISAM這個,現在已經沒有人去用了如果非得用它,也是用它的升級版MyISAM,這是最早的MSYQL版本提供的,除了有這兩個缺點以外,他有一個優點,對索引支持的特別好,而且MYSQL的索引是做的非常不錯的,比如說用這個B-TREE,Balanced-Tree,還有叫什么全文注解,這些都是可以提升它的查詢效率的,而恰恰這種索引技術,能很好的被ISAM所處理,所以他的查詢性能是比較高的
2. 我們再來看第二個存儲引擎,叫MyISAM,其實MyISAM是什么意思呢,這個我已經有介紹了,MyISAM是對MYSQL的ISAM的一個擴展和缺省數據庫引擎,注意看這個關鍵詞,缺省,那么說也就是默認的了,不是的,但是它是在MYSQL5.5之前作為一個默認的引擎,但是從MYSQL5.5以后,他的存儲引擎默認的就已經不再是MyISAM,是InnoDB,回顧一下,我們在Linux下,第一次啟動MYSQL的時候,那說明我們當前所用的MYSQL的版本至少是5.5以上的,那我們接著往下看,除了提供ISAM里鎖沒有的索引和字段管理的大量功能,MyISAM還使用一種表格鎖定的機制,因為在多線程下數據是共享的,我們既要對他做到安全,我們查詢效率會用到事務這個概念,什么共享鎖,獨占鎖,排他鎖,等等,其實這里我有必要和大家多說依據,MYSQL也好,ORALCE也好,提升查詢的效率對于鎖,他們已經細化到極細極細的單位,舉個例子,現在有這么多客戶端,都來我這個DB,而且是并發的,那么我這個DB給你提供數據的時候,他并沒有在這個位置做鎖控制,不是來了做成串型化,如果是那樣的話,你想一想,他最終和串型化還是一個樣,一個一個去處理,所以他并沒有在這個概念去做鎖的處理,而是在哪兒呢,還要往后推,他這個軸越是往后推,并發的延展性就越強,效率損耗就越低,如果上來就串行化了那后面延伸的就直接串行化了,所以他會把并發的時間軸往后延,延到哪兒呢,延到不能夠再延了,操作數據了,如果這塊我再不去做處理,那數據就會有風險了,就已經去讀數據了,他會在哪做鎖呢,在你操作數據時,那它是把所有的都變成串行化嗎,不管你是查詢還是更新還是刪除,還是添加,不是,他還得看你對數據做了什么樣的操作,在這個操作上再去做鎖的處理,如果再往后推,他必須在最后的節點上做鎖的控制,所以說當你去做一個查詢的時候,它會給你上一個共享鎖,共享鎖什么意思,誰都可以查,這個數據不鎖定,共享鎖就是不鎖定,但是一旦這個數據要去做DML操作了,它會給他上一個排他鎖,排他鎖不是一上來就鎖定了,比如咱們的更新鎖吧,更新是建立在一次查詢之后才去更新的,所以說像這個更新鎖,是兩個鎖的復合鎖,是共享鎖和排他鎖,在更新的時候,我有個數據A,我要去更新他,在更的時候我去查的時候,還需要上排他鎖呢,還是共享鎖呢,恰巧這個時候有人查數據,但是一旦我把數據查出來了,這個時候我就不能讓別人再查了,因為下一步我馬上要更新了,我再不鎖定他,就可以出現張冠李戴的現象了,所以在這個節點上,馬上把共享鎖變成排他鎖,還有獨占鎖,這個時候所有的查詢,什么時候釋放這個鎖呢,等他的數據更新完畢以后,他在釋放掉這個排他鎖,是在不得不做的這個環節了,才去做鎖的處理,所以說這些策略都是為了提高他的數據庫的一個性能,有沒有說明白,來優化多個讀寫操作,其代價就是你需要經常運行OPTIMIZE TABLE命令,OPTIMIZE是什么東西呢,它是一個命令,這個命令其實為了解決什么問題呢,比如我們對表做DML操作的時候,更新也好,刪除也好,比如我們拿刪除來說,它支持表的刪除的,更新的,你頻繁的對一個表的數據做刪除,那么這個時候,對于數據庫來講,他把這個數據從數據文件移除以后,這個時候其實會在數據文件里面產生大量的碎片,這個碎片其實歸根結底不是來自于文件,而是來源于磁盤,文件其實也是磁盤的一種邏輯表現形式,我們存所有的文件不就是存磁盤嗎,磁盤那么大怎么存,文件可以規劃這個存儲結構和內容,所以這個東西最終還是要砸到磁盤,那么我們對磁盤做操作就涉及到一個碎片的問題,這個碎片如果在這里不好做理解,我們換一個角度來理解,比如我們現在裝操作系統,因為你們可能沒就接觸到,磁盤在存二進制的時候,這一個字節到底怎么存,這是有規則的,那么這個規則就是我們所說的磁盤存儲規則,如果你沒聽過就是現在太智能化了把一些底層的東西給掩蓋了,比如我們現在安裝操作系統,分區恢復就可以了,比如在我那個年代,我們要想裝系統,就得經歷過這幾個步驟,第一個分區,分區是什么呢,把一個物理磁盤,劃分為邏輯的幾個區域,我們現在的D盤,F盤....,這個并不是把真正的物理硬盤給切割了,而是邏輯的劃分了,你的文件不能存在除了這幾個盤以外的地方了,只能存到這里了,然后在這個區域里又分為目錄,又分為文件,所以我們分完區以后,這個時候磁盤是沒法存文件的,所以我們得給他一個存儲格式,怎么辦呢要對它做格式化處理,最早在裝windows98,windows2000之前的,比如你電腦用著突然死機了,這時候你再開機,在啟動的時候他不會馬上進入操作系統,它會做一個碎片清理,我突然掉電了,有一些程序在內存里面運行的時候,有一些文件運行的不完整,那么久可能導致在磁盤里又丟失的情況,磁盤之前是連續的來存儲,現在不是連續的了,不連續鎖帶來的問題是什么,加入原來有8個空
window98都支持碎片整理的一個能力,把這些浪費掉的回收回來,然后把它們做一個排序,這就叫碎片整理,其實我說這個東西是想通的,如果能用MyISAM存數據的時候,產生碎片,產生碎片就會帶來磁盤浪費,要使用OPTIMIZE TABLE命令對你的這個表去做碎片整理,把數據文件倒騰出來,然后更合理的存儲數據,所以這命令主要是干這事的,所以這也是MyISAM的一個缺點,如果你的引擎是他,數據有刪除了或者有其他的更新操作它會產生碎片,需要我們用這樣的命令做一個釋放,而且這個命令要注意,這個命令很簡單,OPTIMIZE TABLE 表名,就可以了,但是一旦你對這個表做碎片整理了,這個表是鎖定狀態的,什么意思,這個表什么都干不了,什么時候等他碎片整理完了,所以會有這樣的一個問題,用這個命令來恢復被更新機制所浪費的空間,MyISAM還有一些有用的擴展,例如來修復數據庫文件的MyISAMCHK工具,MYISAM強調了快速讀寫操作,這是為什么MYSQL受到WEB開發如此青睞的原因,這我再多說一句,其實大家開始懷疑,MYSQL一個開源的東西,而且還這么小,注意小和大是相對的,相對于ORACLE,ORACLE一個安裝文件就一個多G,而MYSQL100M,這玩意能靠譜嗎,其實很多人都對這個有疑問,互聯網公司最大的一個特點是什么,數據量大,那這小玩意能行嗎,我記得一個本書里面寫著,MYSQL麻雀雖小五臟俱全,他的性能或者他的可靠性,已經不再是業內所懷疑的一個對象了,為什么對他不懷疑了呢,好多現在比較主流的互聯網公司存儲都在用MYSQL,比如國內的淘寶京東,包括騰訊,他們大量的應用用MYSQL,原來淘寶用ORACLE,不用了,全部用MYSQL,除了國內往國外說,FACEBOOK,FACEBOOK那么大的信息量,說明MYSQL的可靠性還是比較強的,你想想這種產品,你說他小,他能力強,你說這樣的產品能不被用戶所接受嗎,所以說現在好多人也在用MYSQL,但是MYSQL能不能徹底的替代ORACLE呢,還是不能的,單從服務這一塊,因為MYSQL是開源的,他沒有服務,出了問題你自己搗鼓,不像ORACLE,我花錢買的產品,我這邊數據有問題了,售后馬上給你來處理,明白我的意思吧,ORACLE有專門的人給你解決,這是一個選擇的問題,所以他最終沒有誰替代誰的問題,各有各的優缺點,ORACLE一般用于企業級開發,他們兩個互相補,使用MYISAM引擎的時候要注意,必須經常使用OPTIMIZE TABLE命令清理表空間,必須經常備份所有的數據,這個肯定需要經常備份的,這是MYISAM遺留的問題,但是這里需要注意一個,字段類型,約束,記住三個文件,如果使用該引擎,會生成三個文件,.frm的,這里存的是表結構信息,.MYD這個存的是數據文件,.MYI這個存的是表的索引信息,如果你在你的數據庫里發現這三個文件,其實更關鍵的是.MYD和.MYI這兩個,那說明你當前這個表的引擎存的是MYISAM引擎的,因為InnoDB所生成的數據文件名字是不一樣的,那這個引擎有沒有講清楚,所以歸根結底總結一下,這個引擎最大的特點是什么,就是優化查詢,就是查詢效率比較高,那么久上升到了一個優化的問題,咱們在數據庫優化的時候該怎么去優化,我們會有一個策略,除了SQL優化,建索引,但是一旦建立索引了,他所影響的面,它會對你這個列在執行DML操作的時候性能比沒有建索引的性能要低的多,再往后優化,是不是可以把查詢多,事務沒有那么嚴的是不是可以換成MYISAM,怎么換一會教你,但是你別忘了,建索引影響的是一個列,而引擎影響的是一個表,再往后對數據庫的內存分布做優化,那影響的是整個數據庫,優化的過程是逐步的向后擴,那么你影響的面就越廣,所以我們在優化的過程當中,對于換引擎這個東西,慎重慎重,為什么這么說,因為換引擎簡單,但是不是每個表都適合去換引擎,首先設計表的時候就要考慮哪些作為存儲表,哪些作為查詢表,那么大家對這個引擎有沒有了解了,他的最大特點就是查詢效率高
3. 先看看什么叫InnoDB,InnoDB數據庫引擎都是造就MYSQL靈活性的技術的直接產品,這項技術就是MYSQL++的API,在使用MYSQL的時候,你所面對的每一個挑戰幾乎都源自于ISAM和MyISAM數據庫引擎不支持事務處理,其實數據庫不支持事務及其可怕,比如我們在做電商的時候,所以現在對于事務的要求性,就是數據庫必須要支持事務,就是MYSQL5.5之前就默認不支持事務,這是他的一個缺陷,那么其實InnoDB其實就是為了解決這個問題的,ISAM和MYISAM不支持事務以外,還不支持外鍵,盡管要比ISAM和MYISAM要慢很多,說明這個引擎在查詢性能上是不是比前兩個引擎要慢,是的,肯定是要比前兩個引擎要慢的,但是InnoDB包括了對事務處理和外鍵的支持,其實正是因為它對事務的支持,才會導致他的查詢效率會有影響,這兩點都是這兩個引擎所沒有的,如前所述,如果你的設計需要這些特性中的一者或者兩者,那你就需要被迫使用兩個引擎中的一個了,那你想一想,我們對于數據庫的操作,所以InnoDB是我們用的最多的一個引擎,MYSQL官方對InnoDB是這樣解釋的,InnoDB給MYSQL提供了具有提交,回滾和崩潰恢復能力的事務安全(ACID)存儲引擎,什么意思呢,MYSQL說了,我的事務是按照嚴格標準來執行的,作為事務的四個特性ACID,隔離性,原子性,一致性,持久性,我全都支持,然后InnoDB鎖定在行級,并且在SELECT語句中提供一個ORACLE風格一致的非鎖定讀,剛才我說過,非鎖定就是共享鎖,就是讀的不是每個人一個一個讀,而是一起讀,這些特色增加了多用戶部署和性能,沒有在InnoDB中擴大鎖需要,因為在InnoDB中行級鎖定適合非常小的空間,他有行級鎖定,還有表級鎖定,InnoDB也支持FOREIGN KEY的強制,也就是這東西還支持外鍵查詢,那外鍵的參照完整性也就支持了,沒錯啊,在SQL查詢中,你可以自由的講InnoDB類型的表與其它MYSQL的表的類型混合起來,甚至可以在同一個查詢中也可以混合,InnoDB是為處理巨大數據量時的最大性能設計,他的CPU效率可能是任何其它基于磁盤的關系數據庫引擎所不能匹敵的,就是他的性能更強大一些,InnoDB存儲引擎完全與MYSQL整合,InnoDB存儲它的表,索引在一個表空間中,表空間可以包含數個文件,InnoDB存儲引擎在主內存中緩存數據和索引而維持它的自己的緩存池,這與MYISAM不同,比如MYISAM表中每個表被存在分離的文件中,InnoDB可以是任何尺寸,即使在文件尺寸被限制為2GB的操作系統上也沒問題,InnDB跟MYISAM的區別
InnoDB的特點:1. 支持事務安裝2. 數據多版本讀取3. 鎖定機制的改進4. 實現外鍵好記吧,就把這四點說一下,下面會有更詳細的東西了
InnoDB與MYISAM的區別?1. InnoDB支持事務,他不支持,對于InnoDB每一條SQL語句都默認封裝成事務,之所以他的查詢效率會慢一些,是和事務有關,因為它會把每一條SQL都封裝成事務,即便查詢也是,明白我的意思吧,自動提交,這樣會影響速度,所以最好把多條SQL語言放在begin和commit之間,組成一個事務,我們有沒有這么做,有的,我們在座的時候,比如JDBC寫的時候,先不自動提交嗎,然后把所有的SQL語句全都發給MYSQL之后,然后我們再commit2. InnoDB支持外鍵,而它不支持,對一個包含外鍵的InnoDB表轉為MYISAM會失敗,這個非常重要3. InnoDB是聚集索引,數據文件和索引綁定在一起,必須要有主鍵,其實就是我們在建的時候,在建表的時候,你不建主鍵也能用,那有人說是不是和這句話就產生悖論了,這里不是說了嗎,不是必須要有主鍵嗎,其實是這樣的,當你用InnoDB的時候,即便你不建主鍵,InnoDB也會去看你表里面有沒有唯一性的字段,如果有就會把它默認設為主鍵,如果連這個也沒有,即便你不建主鍵,也會有一個默認主鍵,但實際上我們在建表的時候,一般我們會自己來建一個索引,為什么要給表默認建一個主鍵,為什么要保證表默認有一個主鍵呢,這個就跟聚集索引有關了,就把所有表里關于InnoDB引擎的所有的主鍵,都做一個排列組合,以便你在檢索表的時候,某個表里數據的時候,能夠更快速的檢索數據,聚集索引不是我們能見的,聚集索引是MYSQL的InnoDB自己來維護的,比如這是一個表,我們說一個表肯定會有一個主鍵嗎,既然這個表會有默認的,聚合不就是聚到一起嗎,檢索的時候就會更快的檢索到,InnoDB在做數據檢索的時候,但是你說你沒有建主鍵,都是為了提高他的效率,但是輔助索引需要查詢兩次,輔助索引是什么啊,就是我們自己能夠創建的索引,比如說我們create index,比如我們查詢的列給他建了index,他首先會走聚集索引,然后才會走你自己建的索引,那有人說效率反而低了,不會的,因為索引本身就能夠定義到唯一性了,查兩次的效率也是非常高的,他不會在大量的數據中去檢索索引的,所以他不會影響到效率,這樣我先畫一個表結構,這里有一個id,有一個name,id是pk,pk就是主鍵,name是unique,明白我的意思了吧,然后當你去查詢條件給的是name,那么這個時候我們在查詢的時候,他先去他的聚集索引查,他的聚集索引有沒有和name索引有關的,聚集索引下有沒有,沒有,因為只有你根據id查的時候才會去從聚集索引里查找,但是聚集索引是不是要查一次,沒查到,接著才會去走輔助索引也就是unique索引,我這么說能不能懂,所以他要查兩次嗎,首先查到主鍵,然后查詢主鍵所查詢到的數據,因此主鍵不應過大,因為主鍵太大,其他索引也都會很大,而MYISAM是非聚集索引,注意MYISAM不支持聚集索引,聚集索引只有InnoDB,明白這個意思吧,記住聚集索引是InnoDB的特點,數據文件是分離的,索引保存的是數據文件的指針,主鍵索引和輔助索引是獨立的4. InnoDB不保存表的具體行數,也就是說不管你的表里又多少條數據,都不保留他具體的行數,所以我們想去計算有多少條數據,是不是需要select count(*) 啊,其實這個count(*)是非常耗時的,因為操作需要全表掃描,而MYISAM用了一個變量保存了整個表的行,也就是你可以通過這個引擎的一個偽列,就可以返回類似count(*)所返回的值,這是他的另一個缺點,執行上述語句時只需要讀出改變量即可,速度很快5. InnoDB不支持全文檢索,而MYISAM支持全文檢索,查詢效率上比MYISAM要高
對于這兩大引擎我們該如何選擇呢?1. 還是我說過,其實對于我們開發人員來講,你用什么引擎跟我們的關系不大,我只要把數據持久化進去就行了,更多的是DBA在優化數據庫的時候需要考慮的,那怎么去選擇呢,第一我們要看是否要支持事務,如果要支持那InnoDB是首選了,如果不需要刻意考慮MYISAM2.如果表中絕大部分數據是查詢,可以考慮MYISAM,如果既有讀和寫,而且也比較頻繁,請考慮InnoDB3. 系統奔潰后,MYISAM恢復起來會更加困難,能否接受,就是這個數據庫一旦崩了,數據丟了,恢復起來老困難了,甚至恢復不了了,這事你能不能接受4. MYSQL5.5版本以后InnoDB已經稱為MYSQL的默認引擎,之前是MYISAM,說明其優勢是有目共睹的,如果你不知道用什么那就用InnoDB,不會錯的,其實還是那句話,這個引擎不會做修改,要想改,我先要考慮了,就是這個表未來就是做數據查詢的,如果你現在在設計數據庫的時候,沒有在考慮這么些問題,每個表只能DML操作,這也映射出一句話,我們在開發的過程當中,項目需求的階段,DBA是要介入的,包括你數據庫的設計,DBA是要參與的,需要給出合理的數據庫設計,合理的設計是針對于日后的優化所提供的一個方式,前提是你們公司得有一個DBA,就是后來你是基于前端,服務端,然后運維我花大量的時間去講存儲引擎的區別,大家有沒有理解了,我覺得講完你總結總結,再遇到問這個問題,你們回答起來應該是沒有壓力的,當然你并不需要把它完全的背下來,其實一點都不那么復雜,那么剩下的就是數據庫提供的其他的引擎了,其他的引擎我們一帶而過,比如有一個NDBCluster,你看這個名就知道是什么意思了,說明這個引擎是支持MYSQL集群的,是從MYSQL5.0開始提供的,還有一個叫MERGE存儲引擎,MERGE存儲引擎也沒有什么了不起的,他就是把MYISAM的一些分離化的東西整合了,提供了一個統一的操作接口,操作入口吧,MERGE不就是合并的意思嗎,還有一個MEMORGY存儲引擎,看這個名字也就知道,他就是內存引擎,存在內存當中的,你想一下存在內存當中是不是有一定的風險啊,介紹一個BLACKHOLE,什么意思,黑洞,你看這個引擎可有意思了,功能恰如其名,黑洞,就像我們unix系統下面的/dev/null一樣,不管我們寫什么信息,都是有去無回,就是往里塞,什么都不管,雖然他提供了這么多引擎,但是并不是每個引擎都適合我們,明白我的意思吧,跟我們用的最多的也是最廣的,那就是InnoDB了,包括我們的MYISAM,還有CSV存儲引擎,這個還是有用的,它是操作一個CSV文件,他不支持索引,就是大家有時候需要從數據庫導出一些報表文件,如果你的數據庫經常導出報表,其他的沒什么了,你要是覺得這么引擎還不夠用,MYSQL更牛,MYSQL給你提供了一個接口,讓你可以自定義存儲引擎,MYSQL++是MYSQL的一門語言,架構圖是不是有這么多引擎,你看后面有一個User Designed
?
總結
- 上一篇: 操作数据库存储引擎
- 下一篇: Oracle之SQL分析函数