テーブルタイプの選択(ストレージエンジン)
1. MySQLストレージエンジンの概要
プラグインストレージエンジンはMySQLデータベースの最も重要な機能の1つであり、ユーザーはアプリケーションのニーズに応じて、データの格納方法とインデックス付け方法、トランザクションを使用するかどうかなどを選択できます。MySQLは、さまざまな分野のデータベースアプリケーションのニーズを満たすために、デフォルトで複数のストレージエンジンをサポートしています。
MySQL 5.xでサポートされるストレージエンジンには、MyISAM、InnoDB、BDB、MEMORY、MERGE、EXAMPLE、NDB Cluster、ARCHIVE、CSV、BLACKHOLE、FEDERATEDなどがあります。これらの中で、InnoDBとBDBはトランザクションセーフテーブルを提供します。
テーブルの作成時にストレージエンジンを指定しない場合、システムはデフォルトのストレージエンジンを使用します。MySQLのデフォルトエンジンはInnoDBです。デフォルトのストレージエンジンを変更する場合は、パラメーターファイルでdefault_storage_engineを設定できます。現在のデフォルトのストレージエンジンを表示するには、次のコマンドを使用できます。
mysql> show variables like '%storage_engine%';
+----------------------------------+--------+
| Variable_name | Value |
+----------------------------------+--------+
| default_storage_engine | InnoDB |
| default_tmp_storage_engine | InnoDB |
| disabled_storage_engines | |
| internal_tmp_disk_storage_engine | InnoDB |
+----------------------------------+--------+
4 rows in set (0.00 sec)
次の方法で、現在のデータベースでサポートされているストレージタイプをクエリできます。
mysql> show engines \G
*************************** 1. row ***************************
Engine: InnoDB
Support: DEFAULT
Comment: Supports transactions, row-level locking, and foreign keys
Transactions: YES
XA: YES
Savepoints: YES
*************************** 2. row ***************************
Engine: MRG_MYISAM
Support: YES
Comment: Collection of identical MyISAM tables
Transactions: NO
XA: NO
Savepoints: NO
*************************** 3. row ***************************
Engine: MEMORY
Support: YES
Comment: Hash based, stored in memory, useful for temporary tables
Transactions: NO
XA: NO
Savepoints: NO
...
テーブルを作成するときに、ENGINEキーワードを追加して、新しいテーブルのストレージエンジンを設定できます。次に例を示します。
mysql> create table ai(
-> i bigint(20) NOT NULL AUTO_INCREMENT,
-> PRIMARY KEY(i)
-> )ENGINE = MyISAM DEFAULT charset = gbk;
Query OK, 0 rows affected (0.00 sec)
mysql> create table country(
-> country_id SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT,
-> conutry VARCHAR(50) NOT NULL,
-> last_update TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
-> PRIMARY KEY(country_id)
-> )ENGINE=InnoDB DEFAULT charset=gbk;
Query OK, 0 rows affected (0.01 sec)
alter tableを使用して、既存のテーブルを別のストレージエンジンに変更できます。
mysql> alter table ai engine = innodb;
Query OK, 0 rows affected (0.00 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> show create table ai \G
*************************** 1. row ***************************
Table: ai
Create Table: CREATE TABLE `ai` (
`i` bigint(20) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`i`)
) ENGINE=InnoDB DEFAULT CHARSET=gbk
1 row in set (0.00 sec)
2.さまざまなストレージエンジンの機能
特徴 | MyISAM | InnoDB | メモリー | メガ | NDB |
---|---|---|---|---|---|
保管制限 | 持ってる | 64 TB | 持ってる | 番号 | 持ってる |
トランザクションのセキュリティ | 待機する | ||||
ロック機構 | テーブルロック | 行ロック | テーブルロック | テーブルロック | 行ロック |
Bツリーインデックス | 待機する | 待機する | 待機する | 待機する | 待機する |
ハッシュインデックス | 待機する | 待機する | |||
全文索引 | 待機する | ||||
クラスターインデックス | 待機する | ||||
インデックスキャッシュ | 待機する | 待機する | 待機する | 待機する | 待機する |
データを圧縮できる | 待機する | ||||
スペースの使用 | 低い | 高い | なし | 低い | 低い |
メモリ使用量 | 低い | 高い | 中 | 低い | 高い |
一括挿入速度 | 高い | 低い | 高い | 高い | 高い |
外部キーをサポートする | 待機する |
2.1、MyISAM
MyISAMはトランザクションも外部キーもサポートしていません。その利点は、迅速にアクセスできることと、トランザクションの整合性を必要としないアプリケーション、または主にSELECTとINSERTを必要としないアプリケーションが、基本的にこのエンジンを使用してテーブルを作成できることです。
各MyISAMはディスク上に3つのファイルとして保存され、ファイル名はテーブル名と同じですが、拡張子は次のとおりです。
- .frm(ストレージテーブル定義);
- .MYD(MYData、ストレージデータ);
- .MYI(MYIndex、ストレージインデックス)。
データファイルとインデックスファイルは異なるディレクトリに配置でき、I / Oを均等に分散して速度を上げることができます。
インデックスファイルとデータファイルのパスを指定するには、テーブルの作成時にDATA DIRECTORYステートメントとINDEX DIRECTORYステートメントを指定する必要があります。
MyISAMタイプのテーブルは、さまざまな理由で破損している可能性があります。破損したテーブルにはアクセスできない可能性があり、修復する必要があるか、アクセス後に誤った結果が返されます。MyISAMタイプのテーブルは修復ツールを提供します。CHECKTABLEステートメントを使用してMyISAMテーブルの状態をチェックし、REPAIRE TABLEステートメントを使用して破損したテーブルを修復できます。
MyISAMテーブルは、3つの異なるストレージ形式もサポートしています。
- 静的(固定長)テーブル。
- 動的テーブル
- テーブルを圧縮します。
その中で、静的テーブルはデフォルトのストレージ形式です。静的テーブルのフィールドはすべて可変長フィールドであるため、各レコードは固定長です。このストレージ方式の利点は、ストレージが非常に高速で、キャッシュしやすく、障害から簡単に回復できることです。欠点は、通常、動的テーブルよりも多くのスペースを使用することです。 。静的テーブルのデータは、格納時に列幅の定義に従ってスペースで埋められますが、アプリケーションがアクセスすると、これらのスペースは取得されません。これらのスペースは、アプリケーションに返される前に削除されています。
mysql> create table Myisam_char(name char(10))engine=MyISAM;
Query OK, 0 rows affected (0.00 sec)
mysql> insert into Myisam_char values('abcde'),('abcde '),(' abcde'),(' abcde ');
Query OK, 4 rows affected (0.01 sec)
Records: 4 Duplicates: 0 Warnings: 0
mysql> select name,length(name) from Myisam_char;
+---------+--------------+
| name | length(name) |
+---------+--------------+
| abcde | 5 |
| abcde | 5 |
| abcde | 7 |
| abcde | 6 |
+---------+--------------+
4 rows in set (0.00 sec)
上記の例は、挿入されたレコードの後のスペースが削除され、前のスペースが予約されていることを示しています。
動的テーブルには可変長フィールドが含まれており、レコードは固定長ではありません。このストレージの利点は、使用するスペースが少なくなることですが、レコードの頻繁な更新と削除により断片化が発生します。改善するには、OPTIMIZE TABLEステートメントまたはmyisamchk -rコマンドを定期的に実行する必要がありますパフォーマンス、および障害発生時の回復は比較的困難です。
圧縮されたテーブルはmyisampackツールによって作成され、ディスク容量をほとんど消費しません。
2.2、InnoDB
InnoDBストレージエンジンは、コミット、ロールバック、およびクラッシュリカバリ機能を備えたトランザクションセキュリティを提供します。ただし、MyISAMのストレージエンジンと比較すると、InnoDBの書き込み処理効率は低下し、データとインデックスを保持するためにより多くのディスク領域を消費します。
以下は、使用中の他のストレージエンジンのテーブルとは異なるストレージエンジンInnoDBテーブルの特性に焦点を当てています。
2.2.1、自動成長カラム
自動拡張の列の場合、手動で値を挿入できますが、0または空を挿入すると、実際に挿入される値は自動的に増加します。
mysql> create table autoincre_demo(
-> i smallint not null auto_increment,
-> name varchar(10),primary key(i)
-> )engine = innodb;
Query OK, 0 rows affected (0.00 sec)
mysql> insert into autoincre_demo values(1,"1"),(0,'2'),(null,'3'),(5,'4'),(0,'5');
Query OK, 5 rows affected (0.00 sec)
Records: 5 Duplicates: 0 Warnings: 0
mysql> select * from autoincre_demo;
+---+------+
| i | name |
+---+------+
| 1 | 1 |
| 2 | 2 |
| 3 | 3 |
| 5 | 4 |
| 6 | 5 |
+---+------+
5 rows in set (0.00 sec)
「alter table table name auto_increment = n;」ステートメントを使用して、自動インクリメント列の初期値を強制的に設定できます。デフォルトは1から始まりますが、初期値はメモリに保持されます。データベースが再起動する前に値が使用される場合、これは必須ですデフォルト値は失われます。
last_insert_id()を使用して、現在のスレッドによって挿入された最後のレコードで使用された値をクエリできます。一度に複数のレコードが挿入された場合、最初のレコードで使用された自動インクリメント値が返されます。
mysql> insert into autoincre_demo values(7,"7");
Query OK, 1 row affected (0.00 sec)
mysql> select LAST_INSERT_ID();
+------------------+
| LAST_INSERT_ID() |
+------------------+
| 2 |
+------------------+
1 row in set (0.00 sec)
mysql> insert into autoincre_demo(name) values('8'),('9');
Query OK, 2 rows affected (0.00 sec)
Records: 2 Duplicates: 0 Warnings: 0
mysql> select LAST_INSERT_ID();
+------------------+
| LAST_INSERT_ID() |
+------------------+
| 8 |
+------------------+
1 row in set (0.00 sec)
InnoDBテーブルの場合、自動拡張列はインデックスである必要があります。複合インデックスの場合は、複合インデックスの最初の列でもある必要があります。ただし、MyISAMテーブルの場合、自動拡張列は複合インデックスの他の列にすることもできるため、データが挿入された後、自動拡張列は複合インデックスの最初のいくつかの列に従ってソートされ、次に増加します。例えば:
mysql> create table autoincre_myisam(
-> d1 smallint not null auto_increment,
-> d2 smallint not null,
-> name varchar(10),
-> index(d2,d1) #自动增长列作为了组合索引的第二列
-> )engine = myisam;
Query OK, 0 rows affected (0.00 sec)
mysql> insert into autoincre_myisam(d2,name) values(2,'2'),(3,'3'),(4,'4'),(2,'2'),(3,'3'),(4,'4');
Query OK, 6 rows affected (0.00 sec)
Records: 6 Duplicates: 0 Warnings: 0
mysql> select * from autoincre_myisam;
+----+----+------+
| d1 | d2 | name |
+----+----+------+
| 1 | 2 | 2 |
| 1 | 3 | 3 |
| 1 | 4 | 4 |
| 2 | 2 | 2 |
| 2 | 3 | 3 |
| 2 | 4 | 4 |
+----+----+------+
6 rows in set (0.00 sec)
mysql> create table autoincre_innodb(
-> d1 smallint not null auto_increment,
-> d2 smallint not null,
-> name varchar(10),
-> index(d2,d1)
-> )engine = innodb;
ERROR 1075 (42000): Incorrect table definition; there can be only one auto column and it must be defined as a key #提示自动增长列必须是组合索引的第一列
2.2.2、外部キー制約
MySQLはInnoDBのみの外部キーの保存をサポートします。外部キーを作成する場合、親テーブルには対応するインデックスが必要です。外部キーを作成すると、子テーブルは対応するインデックスを自動的に作成します。
次の例:データベースには2つのテーブルがあり、countryは親テーブル、country_idは主キーインデックス、cityは子テーブル、country_idフィールドは外部キーで、countryテーブルのcountry_id主キーに対応しています。
mysql> create table city(
-> city_id smallint unsigned not null auto_increment,
-> city varchar(50) not null,
-> country_id smallint unsigned not null,
-> last_update timestamp not null default current_timestamp on update current_timestamp,
-> primary key(city_id),
-> foreign key (country_id) references country (country_id) on delete restrict on update cascade
-> )engine=InnoDB default charset=utf8;
Query OK, 0 rows affected (0.00 sec)
インデックスを作成するときに、親テーブルを削除または更新するときに子テーブルで実行される対応する操作(RESTRICT、CASCADE、SET NULL、NO ACTIONなど)を指定できます。それらのうち、RestrictとNO ACTIONは同じです。つまり、子テーブルに関連レコードがある場合、親テーブルは更新できません。CASCADEは、親テーブルが更新または削除されると、テーブルの対応するレコードが更新または削除されます。SETNULLは、親テーブルが更新または削除する場合、サブテーブルの対応するフィールドはSET NULLです。
2.2.3、保管方法
InnoDBストレージテーブルとインデックステーブルには、次の2つのストレージメソッドがあります。
- 共有テーブルスペースストレージを使用して、この方法で作成されたテーブルのテーブル構造は.frmファイルに格納され、データとインデックスはinnodb_data_home_dirとinnodb_data_file_pathによって定義されたテーブルスペースに格納されます。
- マルチテーブルスペースストレージを使用すると、この方法で作成されたテーブルのテーブル構造は.frmファイルに保存されますが、各テーブルのデータとインデックスは.idbに個別に保存されます。パーティションテーブルの場合、各パーティションは個別の.idbファイルに対応し、ファイル名は「テーブル名+パーティション名」です。パーティションの作成時に、各パーティションのデータファイルの場所を指定して、テーブルのIOを変更できます。複数のディスクに均等に分散されます。
2.3、メモリ
MEMORYストレージエンジンは、メモリに存在するコンテンツを使用してテーブルを作成します。各MEMORYテーブルは実際には1つのディスクファイルのみに対応し、形式は.frmです。MEMORYタイプのテーブルアクセスは、データがメモリに格納され、デフォルトでHASHインデックスが使用されるため、非常に高速ですが、サービスが閉じられると、テーブルのデータは失われます。
mysql> create table tab_memory engine = memory
-> select city_id ,city,country_id
-> from city group by city_id;
Query OK, 0 rows affected (0.00 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> select count(*) from tab_memory;
+----------+
| count(*) |
+----------+
| 0 |
+----------+
1 row in set (0.00 sec)
mysql> show table status like 'tab_memory' \G
*************************** 1. row ***************************
Name: tab_memory
Engine: MEMORY
Version: 10
Row_format: Fixed
Rows: 0
Avg_row_length: 155
Data_length: 0
Max_data_length: 16252835
Index_length: 0
Data_free: 0
Auto_increment: NULL
Create_time: 2020-08-19 08:24:33
Update_time: NULL
Check_time: NULL
Collation: utf8_general_ci
Checksum: NULL
Create_options:
Comment:
1 row in set (0.00 sec)