1. 程式人生 > 實用技巧 >資料庫儲存引擎

資料庫儲存引擎

參考:

https://blog.csdn.net/qq_27028821/article/details/52267991

https://blog.csdn.net/keil_wang/article/details/88392433

MySQL中四種常用儲存引擎的介紹

(1):MyISAM儲存引擎:不支援事務、也不支援外來鍵,優勢是訪問速度快,對事務完整性沒有 要求或者以select,insert為主的應用基本上可以用這個引擎來建立表

支援3種不同的儲存格式,分別是:靜態表;動態表;壓縮表

靜態表:表中的欄位都是非變長欄位,這樣每個記錄都是固定長度的,優點儲存非常迅速,容易快取,出現故障容易恢復;缺點是佔用的空間通常比動態表多(因為儲存時會按照列的寬度定義補足空格)ps:在取資料的時候,預設會把欄位後面的空格去掉,如果不注意會把資料本身帶的空格也會忽略。

動態表:記錄不是固定長度的,這樣儲存的優點是佔用的空間相對較少;缺點:頻繁的更新、刪除資料容易產生碎片,需要定期執行OPTIMIZE TABLE或者myisamchk-r命令來改善效能

壓縮表:因為每個記錄是被單獨壓縮的,所以只有非常小的訪問開支

(2)InnoDB儲存引擎*

該儲存引擎提供了具有提交、回滾和崩潰恢復能力的事務安全。但是對比MyISAM引擎,寫的處理效率會差一些,並且會佔用更多的磁碟空間以保留資料和索引。
InnoDB儲存引擎的特點:支援自動增長列,支援外來鍵約束

(3):MEMORY儲存引擎

Memory儲存引擎使用存在於記憶體中的內容來建立表。每個memory表只實際對應一個磁碟檔案,格式是.frm。memory型別的表訪問非常的快,因為它的資料是放在記憶體中的,並且預設使用HASH索引,但是一旦服務關閉,表中的資料就會丟失掉。
MEMORY儲存引擎的表可以選擇使用BTREE索引或者HASH索引,兩種不同型別的索引有其不同的使用範圍

Hash索引優點:
Hash 索引結構的特殊性,其檢索效率非常高,索引的檢索可以一次定位,不像B-Tree 索引需要從根節點到枝節點,最後才能訪問到頁節點這樣多次的IO訪問,所以 Hash 索引的查詢效率要遠高於 B-Tree 索引。
Hash索引缺點: 那麼不精確查詢呢,也很明顯,因為hash演算法是基於等值計算的,所以對於“like”等範圍查詢hash索引無效,不支援;

Memory型別的儲存引擎主要用於哪些內容變化不頻繁的程式碼表,或者作為統計操作的中間結果表,便於高效地對中間結果進行分析並得到最終的統計結果,。對儲存引擎為memory的表進行更新操作要謹慎,因為資料並沒有實際寫入到磁碟中,所以一定要對下次重新啟動服務後如何獲得這些修改後的資料有所考慮。

(4)MERGE儲存引擎

Merge儲存引擎是一組MyISAM表的組合,這些MyISAM表必須結構完全相同,merge表本身並沒有資料,對merge型別的表可以進行查詢,更新,刪除操作,這些操作實際上是對內部的MyISAM表進行的。

MySQL儲存引擎的區別與比較

儲存引擎,即表型別(table_type)

使用者可以根據應用的需求選擇如何來儲存資料、索引、是否使用事務等。選擇合適的儲存引擎往往能夠有效的提高資料庫的效能和資料的訪問效率,另外一個數據庫中的多個表可以使用不同引擎的組合以滿足各種效能和實際需求。

MySQL支援很多儲存引擎,包括MyISAM、InnoDB、BDB、MEMORY、MERGE、EXAMPLE、NDB Cluster、ARCHIVE等,其中InnoDB和BDB支援事務安全。它還支援一些第三方的儲存引擎,例如TokuDB(高寫效能高壓縮儲存引擎)、Infobright(列式儲存引擎)。

檢視當前表使用的儲存引擎

mysql> show create table emp;

或者

mysql> show table status like 'emp' \G;

檢視當前資料庫支援的儲存引擎

mysql> show engines \G;

定義儲存引

在建立表的時候,在create語句最後加上engine=innodb/...

或者用alter table語句修改

mysql> alter table emp engine=innodb;

下面介紹一些常用的儲存引擎和各自的優缺點以及應用場景


MyISAM

它是MySQL5.5之前的預設儲存引擎

優勢:訪問速度快

適用場景:對事務的完整性沒有要求,或以select、insert為主的應用基本都可以選用MYISAM。在Web、資料倉庫中應用廣泛。

特點:

1、不支援事務、外來鍵

2、每個myisam在磁碟上儲存為3個檔案,檔名和表名相同,副檔名分別是

.frm -------儲存表定義

.MYD --------MYData,儲存資料

.MYI --------MYIndex,儲存索引

資料檔案和索引檔案可以放在不同的目錄,平均分佈IO,加快訪問速度,在建立表的時候通過 data directory和index directory來指定儲存路徑

3、myisam表還支援三種不同的儲存格式

(1)、靜態表(fixed)

預設的儲存格式

靜態表中的欄位都是非變長欄位,每個記錄都是固定的長度,當表不包含變數長度列(VARCHAR, BLOB, 或TEXT)時,使用這個格式。

優點:儲存迅速,出現故障容易恢復

缺點:佔用空間比動態表大,靜態表在進行資料儲存時會按照事先定義的列寬度補足空格,但在訪問的時候會去掉這些空格

注意:如果資料本身帶有空格,在返回的時候會去掉資料本身自帶的末尾的空格,前面的會保留

(2)、動態表(dynamic)

包含變長欄位,例如varchar、、text、blob,如果一個MyISAM表包含任何可變長度的欄位(varchar、blob、text),或者該表建立時用row_format=dynamic指定,則該表使用動態格式儲存

優點:佔用空間小

缺點:頻繁的更新和刪除操作會產生碎片,需要定期用optimize table語句或myisamchk -r命令來改善效能,並且在出現故障後較難恢復

(3)、壓縮表

由myisampack工具建立,佔據非常小的磁碟空間,因為每個記錄都是被單獨壓縮的


InnoDB

MySQL5.5之後的預設儲存引擎

應用場景:如果應用對事務的完整性有較高的要求,在併發條件下要求資料的一致性,資料操作中包含讀、插入、刪除、更新,那InnoDB是最好的選擇。在計費系統、財務系統等對資料的準確性要求較高的系統中被廣泛應用。

優點:提供了具有提交(Commit)、回滾(Rollback)、崩潰恢復能力的事務安全,支援外來鍵。

缺點:相比較於MyISAM,寫的處理效率差一點,並且會佔用更多的磁碟空間來儲存資料和索引

特點:

1、自動增長列

innoDB表的自動增長列必須是索引,如果是組合索引,也必須是組合索引的第一列

MyISAM表的自動增長列可以是組合索引的其他列

設定自動增長列:create表時,在欄位後加auto_increment

可以通過alter table emp auto_increment=n 來強制設定自動增長列的初始值,預設是1,但是該強制指定的值是儲存在記憶體中的,所以在資料庫重啟後會失效,需要重新設定

2、外來鍵約束

MySQL的儲存引擎中只有innoDB支援外來鍵約束

注意:當某個表被其它表建立了外來鍵參照,那麼該表對應的索引和主鍵禁止被刪除

當匯入多個表的資料時,如果要忽略表之前匯入順序,或者當執行load data和alter table操作,為了提高處理速度的時候,可以暫時關閉外來鍵約束,命令是

mysql> set foreign_key_checks=0;

執行完之後,再使其為1 ,開啟外來鍵。

檢視外來鍵資訊

show create table 或show table status

3、儲存方式

innoDB儲存資料和索引有共享表空間儲存和獨佔表空間儲存兩種方式,通過引數innodb_file_per_table控制,0表示共享空間,也是預設的,1表示獨佔空間

兩種方式的表結構(描述)都儲存在.frm檔案中

共享表空間:

每一個數據庫的所有表的資料、索引都儲存在一個檔案中,預設在data目錄下,名為ibdata1,大小為10M的檔案,可以通過引數innodn_data_file_path=/data/ibdata1:2000M來指定儲存路徑。

優點:

(1)、可以將表空間分為多個檔案放在不同的磁碟上,分佈IO,提高效能。innodn_data_file_path=/data/ibdata1:2000M;/db/ibdata2:2000M:autoextend

autoextend表示如果指定的2000M空間用滿後,該檔案自動增長。

也就是說採用共享空間儲存,儲存空間的大小不受檔案系統下檔案大小的限制了,而取決於自身的限制,官方文件顯示,表空間的最大限制是64TB。

(2)、表資料和表結構放在一起,方便管理

缺點:由於所有的資料和索引都是在一個檔案中混合儲存,這樣的話對一個表做了大量的刪除操作後,表空間中會產生大量的空隙

獨佔表空間儲存:

每一張表都有自己獨立的表空間,表的結構依然在.frm檔案中,還有一個字尾為.ibd的檔案,儲存了這張表的資料和索引。

優點:

  1. 每張表都有自己獨立的表空間,可實現單表在不同資料庫中移動
  2. 空間可回收。drop table會自動回收;刪除資料後,通過alter table emp engine=innodb也可回收不用的表空間
  3. 效率和效能會好一些

缺點:由於每個表的資料都是以一個單獨的檔案來存放,所以會受到檔案系統的大小限制


MEMORY

MEMORY儲存引擎是用儲存在記憶體中的資料來建立表,每個memory表對應一個磁碟檔案。格式是.frm

特點:由於他的資料是存放在記憶體中的,並且預設使用HASH索引,所以它的訪問速度特別快,同時也造成了他的缺點,就是資料庫服務一旦關閉,資料就會丟失,另外對錶的大小有限制

每個memary表中可儲存資料量的大小,受到max_heap_table_size變數的約束,他的初始值是16MB,可以在定義Memary表的時候通過max_rows指定表的最大行數

適用場景:內容變化不頻繁的程式碼表,作為統計操作的中間結果表,便於利用它速率快的優勢高效的對中間結果進分析。


MERGE

Merge表是一組MyISAM表的組合,這些myisam表的結構必須完全相同,MERGE表本身並沒有資料,對它的操作實際上是對內部MYISAM表的操作。

MERGE表在磁碟上保留兩個檔案,.frm檔案儲存表的定義,.mrg檔案儲存組合表的資訊

應用場景:用於將一系列MyISAM表以邏輯方式組合在一起,並作為一個物件引用它們

優點:突破對單個MyISAM表的大小限制,通過將不同的表分佈在多個磁碟上,提高訪問效率

例:

mysql>create table emp1(

->id int,

->name varchar(11),

->salary decimal(8,2)

->)engine=myisam;

mysql>create table emp2(

->id int,

->name varchar(11),

->salary decimal(8,2)

->)engine=myisam;

mysql>create table emp-all(

->id int,

->name varchar(11),

->salary decimal(8,2)

->)engine=merge union=(emp1,emp2) insert_method=last;

insert_method=first/last/no 表示對MERGE表插入操作時,作用物件是誰。first表示作用於第一張myisam表,last作用於最後一張myisam表,no或者不指定表示不能對該MERGE表進行插入操作。

附錄:

外來鍵約束

http://c.biancheng.net/view/2441.html

MySQL外來鍵約束(FOREIGN KEY)是表的一個特殊欄位,經常與主鍵約束一起使用。對於兩個具有關聯關係的表而言,相關聯欄位中主鍵所在的表就是主表(父表),外來鍵所在的表就是從表(子表)。

外來鍵用來建立主表與從表的關聯關係,為兩個表的資料建立連線,約束兩個表中資料的一致性和完整性。比如,一個水果攤,只有蘋果、桃子、李子、西瓜等 4 種水果,那麼,你來到水果攤要買水果就只能選擇蘋果、桃子、李子和西瓜,其它的水果都是不能購買的。

主表刪除某條記錄時,從表中與之對應的記錄也必須有相應的改變。一個表可以有一個或多個外來鍵,外來鍵可以為空值,若不為空值,則每一個外來鍵的值必須等於主表中主鍵的某個值。

定義外來鍵時,需要遵守下列規則:

  • 主表必須已經存在於資料庫中,或者是當前正在建立的表。如果是後一種情況,則主表與從表是同一個表,這樣的表稱為自參照表,這種結構稱為自參照完整性。
  • 必須為主表定義主鍵。
  • 主鍵不能包含空值,但允許在外來鍵中出現空值。也就是說,只要外來鍵的每個非空值出現在指定的主鍵中,這個外來鍵的內容就是正確的。
  • 在主表的表名後面指定列名或列名的組合。這個列或列的組合必須是主表的主鍵或候選鍵。
  • 外來鍵中列的數目必須和主表的主鍵中列的數目相同。
  • 外來鍵中列的資料型別必須和主表主鍵中對應列的資料型別相同。

在建立表時設定外來鍵約束

在 CREATE TABLE 語句中,通過FOREIGN KEY關鍵字來指定外來鍵,具體的語法格式如下:

[CONSTRAINT <外來鍵名>] FOREIGN KEY 欄位名 [,欄位名2,…]
REFERENCES <主表名> 主鍵列1 [,主鍵列2,…]

例 1

為了展現表與表之間的外來鍵關係,本例在 test_db 資料庫中建立一個部門表 tb_dept1,表結構如下表所示。

欄位名稱資料型別備註
id INT(11) 部門編號
name VARCHAR(22) 部門名稱
location VARCHAR(22) 部門位置


建立 tb_dept1 的 SQL 語句和執行結果如下所示。

mysql> CREATE TABLE tb_dept1
    -> (
    -> id INT(11) PRIMARY KEY,
    -> name VARCHAR(22) NOT NULL,
    -> location VARCHAR(50)
    -> );
Query OK, 0 rows affected (0.37 sec)

建立資料表 tb_emp6,並在表 tb_emp6 上建立外來鍵約束,讓它的鍵 deptId 作為外來鍵關聯到表 tb_dept1 的主鍵 id,SQL 語句和執行結果如下所示。

mysql> CREATE TABLE tb_emp6
    -> (
    -> id INT(11) PRIMARY KEY,
    -> name VARCHAR(25),
    -> deptId INT(11),
    -> salary FLOAT,
    -> CONSTRAINT fk_emp_dept1
    -> FOREIGN KEY(deptId) REFERENCES tb_dept1(id)
    -> );
Query OK, 0 rows affected (0.37 sec)

mysql> DESC tb_emp6;
+--------+-------------+------+-----+---------+-------+
| Field  | Type        | Null | Key | Default | Extra |
+--------+-------------+------+-----+---------+-------+
| id     | int(11)     | NO   | PRI | NULL    |       |
| name   | varchar(25) | YES  |     | NULL    |       |
| deptId | int(11)     | YES  | MUL | NULL    |       |
| salary | float       | YES  |     | NULL    |       |
+--------+-------------+------+-----+---------+-------+
4 rows in set (1.33 sec)

以上語句執行成功之後,在表 tb_emp6 上添加了名稱為 fk_emp_dept1 的外來鍵約束,外來鍵名稱為 deptId,其依賴於表 tb_dept1 的主鍵 id。

注意:從表的外來鍵關聯的必須是主表的主鍵,且主鍵和外來鍵的資料型別必須一致。例如,兩者都是 INT 型別,或者都是 CHAR 型別。如果不滿足這樣的要求,在建立從表時,就會出現“ERROR 1005(HY000): Can't create table”錯誤。