1. 程式人生 > >談談我對MySQL儲存引擎的理解

談談我對MySQL儲存引擎的理解

  這篇文章並不是在說某個技術,更多的是一種感悟,一種學習技術的方法,相信讀者如果認真閱讀這篇文章,一定會比學習一個單純的技術收穫更大(就是這麼自信^o^)。 

  到底什麼是儲存引擎,儲存引擎這個概念在Oracle中是沒有的。或者說Oracle中只有一種儲存引擎。

  在說具體的儲存引擎之前,先說說我對MySQL儲存引擎的理解。我對於MySQL引擎的理解是這樣,MySQL是一個大的框架,負責整體的管理工作,比如sql解析,查詢快取等等。而對於一個數據庫來講,最重要的是對資料的操作。如何操作資料呢,比如資料的儲存,是要儲存到磁碟,還是要放到記憶體。再比如是否需要事務等等,那麼可能在實現資料的增刪改查的方法上就不同。既然有不同,我就要抽象介面,我抽象出來一個所有的關於資料操作的介面,然後形成一套規範

,有了介面不行,需要有實現類,而且只要實現了我定義的介面的實現類都可以為我所用。當然,我也先預設實現一個或者多個,那麼這個麼個東西就是引擎。這樣看MySQL的系統結構可以從總體上分為兩層,上層是提供使用者介面,以及一些管理功能,下層就是我們的儲存引擎。

  很快,剛有了這些想法,就佐證了。那麼在猜想之前用了這麼多的時間為什麼沒有找到類似的說法呢,我想大概沒有往那個方面去搜索的原因吧。上面提到了資料庫的結構,那麼我馬上就可以搜一下資料庫的結構來佐證,還真是不負有心人,找到一個系統結構的圖片。


 總的來說,MySQL可以看成是二層架構,第一層我們通常叫做SQLLayer,在MySQL資料庫系統處理底層資料之前的所有工作都是在這一層完成的,包括許可權判斷,sql解析,執行計劃優化,querycache的處理等等;第二層就是儲存引擎層,我們通常叫做StorageEngineLayer,也就是底層資料存取操作實現部分,由多種儲存引擎共同組成。

還有一張圖來佐證我說的介面的問題,這張圖似乎更加說明了我的猜測是正確的



下面再說說猜想,猜想不是憑空猜想,是根據一些專業知識給出的猜測。為什麼要介面,這是對系統架構的理解。一般要設計一個可擴充套件的專案,首先就是要抽象介面。好了,就不多說了。下面是關於MySQL引擎的具體內容。

MySQL給我們提供了多種儲存引擎,通過命令來檢視資料庫所支援引擎
SHOW ENGINES

下面來看一下各種引擎的具體介紹

InnoDB儲存引擎

InnoDB是事務型資料庫的首選引擎,支援事務安全表(ACID),支援行鎖定和外來鍵,上圖也看到了,InnoDB是預設的MySQL引擎。InnoDB主要特性有:1、InnoDB給MySQL提供了具有提交、回滾和崩潰恢復能力的事物安全(ACID相容)儲存引擎。InnoDB鎖定在行級並且也在SELECT語句中提供一個類似Oracle的非鎖定讀。這些功能增加了多使用者部署和效能。在SQL查詢中,可以自由地將InnoDB型別的表和其他MySQL的表型別混合起來,甚至在同一個查詢中也可以混合2、InnoDB是為處理巨大資料量的最大效能設計。它的CPU效率可能是任何其他基於磁碟的關係型資料庫引擎所不能匹敵的3、InnoDB儲存引擎完全與MySQL伺服器整合,InnoDB儲存引擎為在主記憶體中快取資料和索引而維持它自己的緩衝池。InnoDB將它的表和索引在一個邏輯表空間中,表空間可以包含數個檔案(或原始磁碟檔案)。這與MyISAM表不同,比如在MyISAM表中每個表被存放在分離的檔案中。InnoDB表可以是任何尺寸,即使在檔案尺寸被限制為2GB的作業系統上4、InnoDB支援外來鍵完整性約束,儲存表中的資料時,每張表的儲存都按主鍵順序存放,如果沒有顯示在表定義時指定主鍵,InnoDB會為每一行生成一個6位元組的ROWID,並以此作為主鍵5、InnoDB被用在眾多需要高效能的大型資料庫站點上InnoDB不建立目錄,使用InnoDB時,MySQL將在MySQL資料目錄下建立一個名為ibdata1的10MB大小的自動擴充套件資料檔案,以及兩個名為ib_logfile0和ib_logfile1的5MB大小的日誌檔案InnerDB的儲存方式有兩種,一種是共享表空間的儲存方式另外一種是獨享表空間的儲存方式。共享表空間的儲存方式就是上面說到的,在MySQL的資料目錄下建立一個名為ibdata1的自動擴充套件資料檔案。當然可以通過配置來配置多個ibdata檔案。獨佔表空間的儲存方式和myISAM的儲存類似,沒張表單獨儲存成為一個檔案,副檔名為.ibd。
我們該如何來檢視我們使用的是共享表空間的儲存方式還是獨佔表空間的儲存方式呢?修改獨佔空表空間配置,以下幾個引數必須在一起加入innodb_data_home_dir = "/usr/local/mysql/var/" 資料庫檔案所存放的目錄innodb_log_group_home_dir = "/usr/local/mysql/var" 日誌存放目錄innodb_data_file_path=ibdata1:10M:autoextend 設定配置一個可擴充套件大小的尺寸為10MB的單獨檔案(共享資料檔案),名為ibdata1。沒有給出檔案的位置,所以預設的是在MySQL的資料目錄內(如 /db/mysql/ibdata1)。innodb_file_per_table=1 是否使用共享以及獨佔表空間(1 為使用獨佔表空間,0 為使用共享表空間)innodb_file_per_table 通過這個引數來實現的轉化,如果為OFF說明所使用的是共享表空間【預設情況下,所使用的表空間為共享表空間】innodb_file_per_table值來進行修改即可,但是對於之前使用過的共享表空間則不會影響,除非手動的去進行修改或者是注意:InnoDB不建立目錄,所以在啟動伺服器之前請確認”所配置的路徑目錄”的確存在。做資料的移植以及備份時,要注意資料檔案的完整性.

MyISAM儲存引擎

MyISAM基於ISAM儲存引擎,並對其進行擴充套件。它是在Web、資料倉儲和其他應用環境下最常使用的儲存引擎之一。MyISAM擁有較高的插入、查詢速度,但不支援事物。MyISAM主要特性有:1、大檔案(達到63位檔案長度)在支援大檔案的檔案系統和作業系統上被支援2、當把刪除和更新及插入操作混合使用的時候,動態尺寸的行產生更少碎片。這要通過合併相鄰被刪除的塊,以及若下一個塊被刪除,就擴充套件到下一塊自動完成3、每個MyISAM表最大索引數是64,這可以通過重新編譯來改變。每個索引最大的列數是164、最大的鍵長度是1000位元組,這也可以通過編譯來改變,對於鍵長度超過250位元組的情況,一個超過1024位元組的鍵將被用上5、BLOB和TEXT列可以被索引6、NULL被允許在索引的列中,這個值佔每個鍵的0~1個位元組7、所有數字鍵值以高位元組優先被儲存以允許一個更高的索引壓縮8、每個MyISAM型別的表都有一個AUTO_INCREMENT的內部列,當INSERT和UPDATE操作的時候該列被更新,同時AUTO_INCREMENT列將被重新整理。所以說,MyISAM型別表的AUTO_INCREMENT列更新比InnoDB型別的AUTO_INCREMENT更快9、可以把資料檔案和索引檔案放在不同目錄10、每個字元列可以有不同的字符集11、有VARCHAR的表可以固定或動態記錄長度12、VARCHAR和CHAR列可以多達64KB使用MyISAM引擎建立資料庫,將產生3個檔案。檔案的名字以表名字開始,副檔名之處檔案型別:frm檔案儲存表定義、資料檔案的副檔名為.MYD(MYData)、索引檔案的副檔名時.MYI(MYIndex)

MEMORY儲存引擎

MEMORY儲存引擎將表中的資料儲存到記憶體中,未查詢和引用其他表資料提供快速訪問。MEMORY主要特性有:1、MEMORY表的每個表可以有多達32個索引,每個索引16列,以及500位元組的最大鍵長度2、MEMORY儲存引擎執行HASH和BTREE縮影3、可以在一個MEMORY表中有非唯一鍵值4、MEMORY表使用一個固定的記錄長度格式5、MEMORY不支援BLOB或TEXT列6、MEMORY支援AUTO_INCREMENT列和對可包含NULL值的列的索引7、MEMORY表在所由客戶端之間共享(就像其他任何非TEMPORARY表)8、MEMORY表記憶體被儲存在記憶體中,記憶體是MEMORY表和伺服器在查詢處理時的空閒中,建立的內部表共享9、當不再需要MEMORY表的內容時,要釋放被MEMORY表使用的記憶體,應該執行DELETE FROM或TRUNCATE TABLE,或者刪除整個表(使用DROP TABLE)

最後關於儲存引擎的操作

查看錶使用的儲存引擎
show table status from db_name where name='table_name';
指定儲存引擎
create table tt
(
    id bigint not null auto_increment,
    name varchar(15) not null,
    primary key (id)
) engine=INNODB;
修改儲存引擎
alter table table_name engine=innodb;