1. 程式人生 > >MySQL 存儲引擎

MySQL 存儲引擎

單表 智能 裝載 手動 pat 最大 table 放置 大小

  在MySQL中有一個存儲引擎的概念,針對不同的存儲需求可以選擇最優的存儲引擎。

一、概述

  MySQL 5.0 支持的存儲引擎包括MyISAM、InnoDB、BDB、MEMORY、MERGE、EXAMPLE、NDB Cluster、ARCHIVE、CSV、BLACKHOLE、FEDERATED等,其中InnoDB和BDB提供事務安全表,其他存儲引擎都是非事務安全表。

  MySQL5.5之前的默認存儲是MyISAM,5.5之後是InnoDB。如果要修改默認的存儲引擎,可以在參數文件中設置default-table-type。在創建表時,可以通過增加engine關鍵字設置新建表的存儲引擎,例如:表auth_type

的存儲引擎是MyISAM,auth_type的存儲引擎是InnoDB

CREATE TABLE `auth_type` (
  `id` int(11) NOT NULL,
  `type_code` char(3) DEFAULT NULL COMMENT ‘授權類型編號‘,
   `type_name` varchar(255) DEFAULT NULL COMMENT ‘授權類型名稱‘,
   PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4;

CREATE TABLE `auth_user` (
  `id` int(11) NOT NULL,
   `user_name` varchar(30) DEFAULT NULL COMMENT ‘授權用戶名稱‘,
  `token` char(64) DEFAULT NULL COMMENT ‘訪問授權token‘,
  `created_at` timestamp NULL DEFAULT NULL COMMENT ‘記錄創建時間‘,
  `updated_at` timestamp NULL DEFAULT NULL COMMENT ‘記錄最後修改時間‘,
  `deleted_at` timestamp NULL DEFAULT NULL COMMENT ‘記錄刪除時間‘,
PRIMARY KEY (`id`)
) ENGINE=InnoDB

DEFAULT CHARSET=utf8mb4 COMMENT=‘授權用戶表‘;

也可以使用ALERT TABLE語句,將一個已經存在的表改成其他的存儲引擎。alert table auth_type engine = InnoDB

二、各種存儲引擎特性

  先看下表各個存儲引擎之間的區別

特 點 MyISAM InnoDB Memory Merge NDB
存儲限制 64TB 沒有
事務安全 支持
鎖機制 表鎖 行鎖 表鎖 表鎖 行鎖
B樹索引 支持 支持 支持 支持 支持
哈希索引 支持 支持
全文索引 支持
集群索引 支持
數據緩存 支持 支持 支持
索引緩存 支持 支持 支持 支持 支持
數據可壓縮 支持
空間使用 N/A
內存使用 中等
批量插入速度
支持外鍵 支持

  下面將介紹最常用的4種存儲引擎:MyISAM、InnoDB、Memory和Merge。

1、MyISAM

  MyISAM 不支持事務、不支持外鍵,其優勢是訪問的速度快,對事務的完整性沒有要求或者以SELECT\INSERT為主的應用基本上可以使用這個引擎來創建表。

  每個MyISAM在磁盤上存儲成3個文件,其文件名都和表名相同,但擴展名分別是:

  .frm(存儲表定義)

  .MYD(MYData,存儲數據)

  .MYI(MYIndex,存儲索引)

  數據文件和索引文件可以放置在不同的目錄,平均分布IO,獲得更快的速度。

  在創建表的時候通過DATA DIRECTORYINDEX DIRECTORY語句指定數據文件索引文件的路徑,該路徑需要絕對路徑,並且具有訪問權限

  MyISAM類型的表可能會被損壞,各種各樣的原因被損壞。損壞後的表可能不能被訪問,會提示需要修復或者返回錯誤結果。MyISAM類型的表提供了修復工具,

CHECK TABLE 語句用於檢查表的健康,REPAIR TABLE 語句用來修復一個損壞的表。表的損壞還可能導致數據庫的異常啟動,需要盡快修復並盡可能地確認損壞的原因。

  MyISAM的表還支持3種不同的存儲格式,分別是:靜態(固定長度)表、動態表、壓縮表。

  靜態表:表中的字段是非變長字段,這樣每個字段都是固定長度,如char(20)。這種存儲的優點是:存儲非常迅速,容易緩存,出現故障容易恢復;缺點是:占用的空間通常比動態表多。靜態表的數據存儲時會按給定的列寬度定義補足空格,但是應用訪問時並不會得到這些空格。

  動態表:表中包含變長字段,比如varchar(20),記錄不是固定長度。哪怕只有一個字段是變長字段,也是動態表。這種存儲的優點是:占用的空間相對較少,但是頻繁地更新和刪除記錄會產生碎片,需要定期執行 OPTIMIZE TABLE 或者 myisamchk-r 命令來改善性能,並且在出現故障時恢復相對比較困難。

  壓縮表:表由myisampack工具創建,占據非常小的磁盤空間。因為記錄是被單個壓縮的,所以只有非常小的開支。

2、InnoDB

  InnoDB存儲引擎提供了具有提交、回滾和崩潰恢復能力的事務安全。但是對比MyISAM存儲引擎,InnoDB寫的處理效率差點,並且會占用更多的磁盤空間以保留數據和索引。

  InnoDB存儲引擎的特點:

  2.1、自動增長列

  InnoDB表的自動增長可以手動插入,但是插入的值如果是空或者是0,則實際插入的將是自動增長後的值。例如:下表auth_user中,列id為自動增長列,通過AUTO_INCREMENT指定。

  CREATE TABLE `auth_user` (
     `id` int(11) NOT NULL AUTO_INCREMENT,
    `user_name` varchar(30) DEFAULT NULL COMMENT ‘授權用戶名稱‘,
    `token` char(64) DEFAULT NULL COMMENT ‘訪問授權token‘,
    `created_at` timestamp NULL DEFAULT NULL COMMENT ‘記錄創建時間‘,
    `updated_at` timestamp NULL DEFAULT NULL COMMENT ‘記錄最後修改時間‘,
    `deleted_at` timestamp NULL DEFAULT NULL COMMENT ‘記錄刪除時間‘,
    PRIMARY KEY (`id`)
   ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT=‘授權用戶表‘;
  還可通過“ALTER TABLE auth_user AUTO_INCREMENT = n;”語句強制設置自動增長的初始值,默認從1開始,但是該強制的默認值是保留在內存中的,如果該值在使用之前數據庫重新啟動,那麽這個強制的默認值就會丟失,就需要在數據庫啟動後重新設置。
  可以會用LAST_INSERT_ID()查詢當前線程最後插入記錄使用的值。如果一次插入多條記錄,那麽返回的是第一條記錄使用的自動增長值。

  對於InnoDB表,自動增長列必須是索引。如果是組合索引,也必須是組合索引的第一列,但是對於MyISAM表,自動增長列可以是組合索引的其他列,這樣插入記錄後,自動增長列是按照組合索引的前列進行排序後遞增的。如:

  CREATE TABLE `autoincre_demo` (
     `id1` int(11) NOT NULL AUTO_INCREMENT,

     `id2` int(11) NOT NULL,
    `name` varchar(30) DEFAULT NULL COMMENT ‘名稱‘
    index (`id1`,`id2`)
   ) ENGINE=MyISAM;

  insert into `autoincre_demo`(`id2`,‘name‘) values(2,‘2‘),(3,‘3‘),(4,‘4‘);

  結果是:select * from `autoincre_demo`;

  

id1 id2 name
1 2 2
1 3 3
1 4 4
2 2 2
2 3 3
2 4 4

  2.2、外鍵約束

  MySQL支持外鍵的存儲引擎只有InnoDB,在創建外鍵的時候,要求父表必須有對應的索引,子表在創建外鍵的時候也會自動創建對應的索引。

  在創建索引時,可以指定在刪除、更新附表時,對子表的相應操作,包括restrict、cascade、set null和no action。

    restrict 和 no action相同,是指限制在子表有關聯記錄時父表不能更新。

    cascade是指,父表在更新或刪除時,更新或者刪除子表對應記錄。

    set null是指,父表在更新或者刪除時,子表對應的字段被set null。

  當某個表被其他表創建了外鍵參照,那麽該表的對應索引或者主鍵禁止被刪除。

  在導入多個表的數據時,如果需要忽略表之前的導入順序,可以暫時關閉外鍵的檢查;同樣,在執行LOAD DATA和ALTER TABLE操作的時候,可以通過暫時關閉外鍵約束來加快處理的速度,關閉的命令是“SET FOREING_KEY_CHECKS = 0;”,執行完成後,通過執行“SET FOREING_KEY_CHECKS = 1;”語句返回原狀。

  2.3、存儲方式

  InnoDB存儲表和索引有以下兩種方式。

  使用共享表空間存儲,這種方式創建的表的表結構保存在.frm文件中,數據和索引保存在innod_data_home_dir和innod_data_file_path定義的表空間中,可以是多個文件。

  使用多表空間存儲,這種方式創建的表的表結構保存在.frm文件中,但是每個表的數據和索引單獨保存在.ibd中。如果是個分區表,則每個分區對應單獨的.ibd文件,文件名是“表名+分區名”,可以在創建分區的時候指定每個分區的數據文件位置,以此來將表的IO均分在多個磁盤上。

  要使用多表空間的存儲方式,需要設置參數innodb_file_per_table,並且重新啟動服務才可以生效,對於新建的表按照多表空間的方式創建,已有的表仍使用共享表空間存儲。如果將已有的多表空間方式修改回共享表空間的方式,則新建表會在共享表空間的創建,但已有的多表空間表仍然保存原來的存儲方式。

  多表空間的數據文件沒有大小限制,不需要設置初始大小,也不需要設置文件的最大限制、擴展大小等參數。

  對於使用多表空間特性的表,可以比較方便的進行單表備份和恢復操作,但是直接復制.ibd文件是不行的,因為沒有共享表的數據字典信息,直接復制的.ibd文件和.frm文件恢復時是不能被識別的,但是可以通過以下命令:

  ALTER TABLE tbl_name DISCARD TABLESPACE;

  ALTER TABLE tbl_name IMPORT TABLESPACE;

  將備份恢復到數據庫,但是這只能恢復到表原來所在的數據庫中,不能恢復到其他的數據庫中。可以通過mysqldump和mysqlimport來將單表恢復到目標數據庫。

  註意:即便在多表空間的存儲方式下,共享表空間仍然是必須的,InnoDB把內部數據詞典和在線重做日誌放在這個文件中。

3、Memory

  Memory存儲引擎使用存在於內存中的內容來創建表。每個Memory表只實際上對應一個磁盤文件,格式是.frm。Memory類型的表訪問速度非常快,因為它的數據是放在內存中的,並且默認使用HASH索引,但是一旦服務關閉,表中的數據就會丟失。

  在啟動MySQL服務的時候使用--init--file選項,把INSERT INTO ... SELECTLOAD DATA INFILE 這樣的語句放入這個文件中,就可以在服務啟動時從持久穩固的數據源裝載表。

  服務器需要足夠內存來維持所有在同一時間使用的Memory表,當不再需要Memory表的內容之時,要釋放被Memory表使用的內存,應該執行DELETE FROMTRUNCATE TABLE,或者整個的刪除表(使用DROP TABLE操作)。

  每個Memory表中可以放置的數據量大小,受到max_heap_table_size系統變量的約束,這個系統變量的初始值是16MB,可以根據需要加大。此外,在定義Memory表的時候,可以通過MAX_ROWS子句指定表的最大行數。

  Memory類型的存儲引擎主要應用於那些語句變化不頻繁的代碼表,或者作為統計操作的中間結果表,便於高效地對中間結果進行分析並得到最終的統計結果。對存儲引擎為Memory的表進行更新操作要謹慎,因為數據並沒有實際寫入到磁盤中,所以一定要對下次重啟服務後如何獲得這些修改的數據有所考慮。

4、Merge

  Merge存儲引擎是一組MyISAM表的組合,這些MyISAM表必須結構完全相同,Merge表本身並沒有數據,對Merge類型的表可以進行查詢、更新、刪除,這些操作實際上是對內部的MyISAM表進行的。對於Merge類型表的插入操作,是通過INSERT_METHOD子句定義插入的表,可以有3個不同的值,使用FIRST或者LAST值使得插入操作被相應地作用在第一個或者最後一個表上,不定義這個子句或者定義為NO,表示不能對這個Merger表進行操作。

  可以對Merge表進行DROP操作,這個操作只是刪除Merge的定義,對內部的表沒有任何的影響。

  在磁盤上保留兩個文件,文件名以表的名字開始,一個.frm文件存儲表定義,另一個.mrg文件包含組合表的信息,包含Merge表由哪些表組成、插入新數據的依據。可以通過修改.mrg文件來修改Merge表,但是修改後要通過flush tables刷新。

  Merger表和分區表的區別是,Merger表並不能智能地將記錄寫到對應的表中,而是寫入到使用FIRST或者LAST值指定的表中。但是分區表可以。通常我們使用Merger表來透明地對多個表進行查詢和更新操作,而這種按照時間記錄的操作日誌表則可以透明地進行插入操作。

三、如何選擇合適的存儲引擎

四、小結

MySQL 存儲引擎