myisam存儲引擎的一些特性

mysql一個比較重要的特性就是使用插件式存儲引擎,這個特性允許用戶可以根據應用的需要來選擇存儲引擎來處理數據,從而更好的支持應用。
現在的mysql支持很多的存儲引擎,以5.5.18爲例:
mysql> show engines;
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
| Engine             | Support | Comment                                                        | Transactions | XA   | Savepoints |
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
| CSV                | YES     | CSV storage engine                                             | NO           | NO   | NO         |
| MRG_MYISAM         | YES     | Collection of identical MyISAM tables                          | NO           | NO   | NO         |
| MEMORY             | YES     | Hash based, stored in memory, useful for temporary tables      | NO           | NO   | NO         |
| BLACKHOLE          | YES     | /dev/null storage engine (anything you write to it disappears) | NO           | NO   | NO         |
| MyISAM             | YES     | MyISAM storage engine                                          | NO           | NO   | NO         |
| FEDERATED          | NO      | Federated MySQL storage engine                                 | NULL         | NULL | NULL       |
| ARCHIVE            | YES     | Archive storage engine                                         | NO           | NO   | NO         |
| InnoDB             | DEFAULT | Supports transactions, row-level locking, and foreign keys     | YES          | YES  | YES        |
| PERFORMANCE_SCHEMA | YES     | Performance Schema                                             | NO           | NO   | NO         |
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
9 rows in set (0.00 sec)
當前數據庫默認使用那個存儲引擎,可以通過參數default_store_engine指定;
mysql> show variables like '%engine%';
+---------------------------+--------+
| Variable_name             | Value  |
+---------------------------+--------+
| default_storage_engine    | InnoDB |
| engine_condition_pushdown | ON     |
| storage_engine            | InnoDB |
+---------------------------+--------+
3 rows in set (0.00 sec)
修改這個值,如果創建數據庫沒有明確指定存儲引擎的話,創建的數據庫表使用的就是該存儲引擎。

mysql> create table test (id int);
Query OK, 0 rows affected (0.01 sec)

mysql> show create table test;
+-------+------------------------------------------------------------------------------------------+
| Table | Create Table                                                                             |
+-------+------------------------------------------------------------------------------------------+
| test  | CREATE TABLE `test` (
  `id` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1 |
+-------+------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
可以看到,我們當前默認的存儲引擎是innodb,創建數據庫表的時候沒有指定存儲引擎,那麼我們創建的表使用就是默認存儲引擎。
如果要創建其他存儲引擎的數據庫表,可以在create語句中明確指定存儲引擎或者修改默認的存儲引擎。

mysql> create table test1 (id int) engine=myisam;
Query OK, 0 rows affected (0.01 sec)

mysql> set session default_storage_engine='myisam';
Query OK, 0 rows affected (0.00 sec)

mysql> create table test2 (id int);
Query OK, 0 rows affected (0.01 sec)

mysql> show create table test1;
+-------+-------------------------------------------------------------------------------------------+
| Table | Create Table                                                                              |
+-------+-------------------------------------------------------------------------------------------+
| test1 | CREATE TABLE `test1` (
  `id` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1 |
+-------+-------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

mysql> show create table test2;
+-------+-------------------------------------------------------------------------------------------+
| Table | Create Table                                                                              |
+-------+-------------------------------------------------------------------------------------------+
| test2 | CREATE TABLE `test2` (
  `id` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1 |
+-------+-------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
可以看到我們創建的數據庫表test1和test2現在使用的都是myisam存儲引擎。

myisam存儲引擎和innodb存儲引擎應該是現在使用比多的。
myisam存儲引擎不支持事務,也不支持外鍵,特點是操作速度快。
myisam存儲引擎的數據庫表有三個文件構成,數據結構是一個以frm結尾的文件,數據文件是一個MYD結尾的文件,索引文件是一個MYI結尾的文件。
這些文件的文件名是相同的。
myisam存儲引擎數據庫表可以指定數據文件和索引文件中不同的目錄,這樣可以平均分配IO,提高性能。
在創建表的時候指定data directory放置數據文件,指定index directory放置索引文件。
mysql> create table test3 (id int(2),name varchar(10)) DATA DIRECTORY='/tmp' index DIRECTORY='/opt/index';
Query OK, 0 rows affected (0.01 sec)
這樣就完成了把數據文件和索引文件放置在不同目錄了。

數據文件和索引文件分開放置時,這兩個文件不能放在datadir目錄下的子目錄內,需要mysql用戶具有讀寫權限,還要注意SElinux的權限。
mysql> show variables like '%datadir%';
+---------------+-----------------+
| Variable_name | Value           |
+---------------+-----------------+
| datadir       | /var/lib/mysql/ |
+---------------+-----------------+
1 row in set (0.00 sec)

mysql> create table test5 (id int(2),name varchar(10)) DATA DIRECTORY='/var/lib/mysql/test1' index DIRECTORY='/var/lib/mysql';
ERROR 1210 (HY000): Incorrect arguments to DATA DIRECTORY
mysql>
如果使用的話,創建表就不能成功。


mysql的myisam存儲引擎支持動態表,靜態表和壓縮表。這個寫不同的表各有特長。
其中靜態表是myisam存儲引擎默認的存儲格式,字段都是非變長字段,字段長度固定,長度不足的字段以空格自動填充。這種表讀寫速度快,便於緩存和修復,但是比較佔空間。
動態表是字段長度不固定的,比較容易產生碎片,速度不如靜態表,出問題是不容易修復,但是節省空間。
壓縮表是由myisampack工具創建的,佔用更少的磁盤空間。


mysql> create table test6 (username char(20)) engine=myiisam;
Query OK, 0 rows affected, 2 warnings (0.04 sec)
這樣我們創建了一個靜態表.

ysql> insert into test6 values('aaa'),(' aaa'),('aaa '),(' aaa ');
Query OK, 4 rows affected (0.01 sec)
Records: 4  Duplicates: 0  Warnings: 0
我們往表裏面插入了4條數據。

mysql> select username,length(username) from test6;
+----------+------------------+
| username | length(username) |
+----------+------------------+
| aaa      |                3 |
|  aaa     |                4 |
| aaa      |                3 |
|  aaa     |                4 |
+----------+------------------+
4 rows in set (0.00 sec)
查詢到結果看到字段後面的空格已經被自動去掉了。

默認的myisam存儲引擎表是靜態表,但是如果這個字段是一個可變長的自動(如varchar,varbinary,blob或者text)會有個警告信息,指定的表格是將被忽略。
在創建表的時候可以使用row_format=fixed或者dynamic參數,指定是靜態表還是動態表。前提是字段的類型要是正確的。
動態表使用過程中容易產生碎片,需要使用optimize table語句,或者myisamchk命令消除碎片,提高性能。

mysql> select table_name,engine,data_free from information_schema.tables where engine='myisam'and data_free>0;
+------------+--------+-----------+
| table_name | engine | data_free |
+------------+--------+-----------+
| user       | MyISAM |        88 |
+------------+--------+-----------+
1 row in set, 1 warning (1.12 sec)

mysql> optimize table mysql.user;
+------------+----------+----------+----------+
| Table      | Op       | Msg_type | Msg_text |
+------------+----------+----------+----------+
| mysql.user | optimize | status   | OK       |
+------------+----------+----------+----------+
1 row in set (0.00 sec)

mysql> select table_name,engine,data_free from information_schema.tables where engine='myisam'and data_free>0;
Empty set, 1 warning (0.62 sec)

mysql>
user權限表data_free大於0說明有碎片,optimize table執行過後碎片消除。


myisam存儲引擎還是有一些其他的特性,比如一個表限制有(1.844E+19)行,每個表支持64給索引等等。
 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章