一、查看支持的存储引擎以及设置修改存储引擎

  1.查看默认存储引擎:show variables like '%storage_engine%';

  2.查看当前数据库支持的存储引擎:show ENGINES \G

  3.查看某个表使用的存储引擎: show create table 表名;

  4.创建新表时指定存储引擎(如果不设置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.04 sec)

  5.将一个已经存在的表修改成其他的存储引擎:ALTER TABLE ai ENGINE=innodb;

  二、各种存储引擎的特性

  1.MyISAM

  MyISAM是默认的MySQL插件式存储引擎。如果应用是以读操作和插入操作为主,只有很少的更新操作和删除操作,并且对事务的完整性、并发性要求不是很高,那么选择这个存储引擎是非常适合的。MyISAM是在Web、数据仓储和其他应用环境下最长使用的存储引擎之一。

  MyISAM是MySQL默认的存储引擎。

  MyISAM不支持事务、也不支持外键,其优势是访问的速度快,对事务完整性没有要求或者以SELECT、INSET为主的应用基本上都可以使用MyISAM来创建表。

  每个MyISAM在磁盘上存储成3个文件,扩展名分别是:.frm(存储表定义)、.MYD(MYData,存储数据)、.MYI(MYIndex,存储索引)

  数据文件和索引文件可以防止在不同的目录,平均分布IO,获得更快的速度。

  MyISAM表还支持3中不同的存储格式:

  • 静态(固定长度)表: 静态表是默认的存储格式。静态表中的字段都是非变长地段,这样每个记录都是固定长度的,这种存储方式的优点是存储非常迅速,容易缓存,出现故障容易恢复;缺点是占用的空间比动态表多。静态表的数据在存储时会按照列的宽度定义补足空格,但是在应用访问的时候并不会得到这些空格,这些空格在返回应用之前已经去掉。
  • 动态表:动态表中包含变长字段,记录不是固定长度的,这样存储的优点是占用的空间相对较少,但是频繁地更新和删除记录会产生碎片,需要定期执行OPTIMIZE TABLE语句或myisamchk -r命令来改善性能,并且在出现故障时恢复相对比较困难。
  • 压缩表:由myisampack工具创建,占据非常小的磁盘空间。因为每个记录是被单独压缩的,所以只有非常小的访问开支。

  

  2.InnoDB

  InnoDB用于事务处理应用程序,支持外键、如果应用对事务的完整性有比较高的要求,在并发条件下要去数据的一致性,数据操作除了插入和查询以外,还包括很多的更新和删除操作,那么InnoDB是比较合适的选择。InnoDB除了有效地降低由于删除和更新导致的锁定,还可以确保事务的完整提交(Commit)和回滚(Rollback),以及崩溃恢复能力的事务安全,对于类似计费系统或者财务系统等对数据准确性要求比较高的系统,InnoDB都是合适的选择。

  InnoDB不同于其他存储引擎的表的特点:自动增长列、外键约束、存储方式

  (1)自动增长列

  InnoDB表的自动增长列可以手动插入,当插入的值是0或者null时,实际插入的将是自动增长后的值。如果跳跃着插入,则从插入的第一个值开始增长。

  对于InnoDB表,自动增长列必须是索引。如果是组合索引,也必须是组合索引的第一列。

  但是对于MyISAM表,自动增长列可以是组合索引的其他列,这样插入记录后,自动增长列是按照组合索引的前面几列进行排序后递增的。

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.04 sec) mysql> insert into autoincre_demo values(1,''),(0,''),(null,'');
Query OK, 3 rows affected (0.01 sec)
Records: 3 Duplicates: 0 Warnings: 0 mysql> select * from autoincre_demo;
+---+------+
| i | name |
+---+------+
| 1 | 1 |
| 2 | 2 |
| 3 | 3 |
+---+------+
3 rows in set (0.00 sec) mysql> insert into autoincre_demo values(1,''),(0,''),(null,'');
ERROR 1062 (23000): Duplicate entry '' for key 'PRIMARY'
mysql> insert into autoincre_demo values(5,''),(0,''),(null,'');
Query OK, 3 rows affected (0.01 sec)
Records: 3 Duplicates: 0 Warnings: 0 mysql> select * from autoincre_demo;
+---+------+
| i | name |
+---+------+
| 1 | 1 |
| 2 | 2 |
| 3 | 3 |
| 5 | 1 |
| 6 | 2 |
| 7 | 3 |
+---+------+
6 rows in set (0.00 sec) mysql> select LAST_INSERT_ID();
+------------------+
| LAST_INSERT_ID() |
+------------------+
| 6 |
+------------------+
1 row in set (0.00 sec) mysql> insert into autoincre_demo values('');
ERROR 1136 (21S01): Column count doesn't match value count at row 1
mysql> insert into autoincre_demo values(9,'5');
Query OK, 1 row affected (0.00 sec) mysql> select LAST_INSERT_ID();
+------------------+
| LAST_INSERT_ID() |
+------------------+
| 6 |
+------------------+
1 row in set (0.00 sec) mysql> insert into autoincre_demo values(10,'1'),(0,'2'),(null,'3');
Query OK, 3 rows affected (0.00 sec)
Records: 3 Duplicates: 0 Warnings: 0 mysql> select LAST_INSERT_ID();
+------------------+
| LAST_INSERT_ID() |
+------------------+
| 11 |
+------------------+
1 row in set (0.00 sec) mysql> show tables;
+----------------+
| Tables_in_tmz |
+----------------+
| ai |
| autoincre_demo |
| dept |
| emp |
| emp1 |
| salary |
| settest |
| t1 |
| t2 |
| t3 |
| t6 |
+----------------+
11 rows in set (0.00 sec) mysql> drop autoincre_demo;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'autoincre_demo' at line 1
mysql> drop table autoincre_demo;
Query OK, 0 rows affected (0.04 sec) mysql> show tables;
+---------------+
| Tables_in_tmz |
+---------------+
| ai |
| dept |
| emp |
| emp1 |
| salary |
| settest |
| t1 |
| t2 |
| t3 |
| t6 |
+---------------+
10 rows in set (0.00 sec) mysql> create table autoincre_demo
-> (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_demo(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_demo;
+----+----+------+
| 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)

自动增长列使用举例

  (2)外键约束(TODO)

  MySQL支持外键约束的只有InnoDB。在创建外键的时候,要求父表必须有对应的索引,子表在创建外键的时候也会自动地创建相应的索引。

  (3)存储方式

  • 使用共享表空间存储:表结构保存在.frm文件中,数据和索引保存在innodb_data_home_dir和innodb_data_file_path定义的表空间中,可以多个文件。
  • 使用多表空间存储:表结构仍然保存在.frm文件中,但是每个表的数据和索引单独保存在.ibd中。如果是个分区表,则每个分区对应单独的.ibd文件。

  

  3.MEMROY

  MEMORY将所有数据保存在RAM中,在需要快速定位记录和其他类似数据的环境下,可 提供极快的访问。MEMORY的缺陷是对表的大小有限制,太大的表无法缓存在内存中,其次是要确保表的数据可以恢复,数据库异常终止后表中的数据是可以恢复的。MEMORY表通常用于更新不太频繁的小表,可以快速得到访问结果。

  MEMORY存储引擎使用存在于内存中的内容来创建表。每个MEMORY表只实际对应一个磁盘文件,格式是.frm。MEMORY类型的表访问非常地块,因为它的数据是放在内存中的,并且默认使用HASH索引,也可以指定使用BTREE索引,但是一旦服务关闭,表中的数据就会丢失掉。

  MEMORY主要用于内容变化不频繁的表,或者作为统计操作的中间结果表,便于高效地对中间结果进行分析并得到最终的统计结果。对MEMORY的表进行更新操作要谨慎,因为数据并没有实际写入到磁盘中,所以一定要对下次重新启动服务后如何获得这些修改后的数据有所考虑。

  

  4.MERGE

  MERGE用于将一系列等同的MyISAM表以逻辑方式组合在一起,并作为一个对象引用它们。MERGE表的优点在于可以突破对单个MyISAM表大小的限制,并且通过将不同的表分布在多个磁盘上,可以有效地改善MERGE表的访问效率。这对于诸如数据仓储等VLDB环境十分适合。

  MERGE存储引擎是一组MyISAM表的组合,这些MyISAM表必须结构完全相同,MERGE表本身并没有数据,对MERGE类型的表可以进行查询、更新、删除操作,这些操作实际上是对内部的MyISAM表进行的。

  在定义MERGE表时,需要声明union和INSERT_METHOD,假如INSERT_METHOD=LAST,那么执行向MERGE表中插入数据时,就会向UNION中最后一个表中插入数据,这也是MERGE表和分区表的区别,MERGE表并不能智能地将记录写到对应的表中,而分区表是可以的。

1.新建两个MyISAM表和一个MERGE表
mysql> create table payment_2006(
-> country_id smallint,
-> payment_date datetime,
-> amount decimal(15,2),
-> key idx_fk_country_id(country_id)
-> )engine=myisam;
Query OK, 0 rows affected (0.01 sec) mysql> create table payment_2007(
-> country_id smallint,
-> payment_date datetime,
-> amount decimal(15,2),
-> key idx_fk_country_id(country_id)
-> )engine=myisam;
Query OK, 0 rows affected (0.01 sec) mysql> create table payment_all(
-> country_id smallint,
-> payment_date datetime,
-> amount decimal(15,2),
-> INDEX(country_id)
-> )engine=merge union=(payment_2006, payment_2007) INSERT_METHOD=LAST;
Query OK, 0 rows affected (0.01 sec) 2.分别向两个MyISAM表中插入数据并查看三个表中的内容
mysql> insert into payment_2006 values(1,'2006-05-01',100000),(2,'2006-08-15',150000);
Query OK, 2 rows affected (0.00 sec)
Records: 2 Duplicates: 0 Warnings: 0 mysql> insert into payment_2007 values(1,'2007-02-20',35000),(2,'2007-07-15',220000);
Query OK, 2 rows affected (0.00 sec)
Records: 2 Duplicates: 0 Warnings: 0 mysql> select * from payment_2006;
+------------+---------------------+-----------+
| country_id | payment_date | amount |
+------------+---------------------+-----------+
| 1 | 2006-05-01 00:00:00 | 100000.00 |
| 2 | 2006-08-15 00:00:00 | 150000.00 |
+------------+---------------------+-----------+
2 rows in set (0.00 sec) mysql> select * from payment_2007;
+------------+---------------------+-----------+
| country_id | payment_date | amount |
+------------+---------------------+-----------+
| 1 | 2007-02-20 00:00:00 | 35000.00 |
| 2 | 2007-07-15 00:00:00 | 220000.00 |
+------------+---------------------+-----------+
2 rows in set (0.00 sec) mysql> select * from payment_all;
+------------+---------------------+-----------+
| country_id | payment_date | amount |
+------------+---------------------+-----------+
| 1 | 2006-05-01 00:00:00 | 100000.00 |
| 2 | 2006-08-15 00:00:00 | 150000.00 |
| 1 | 2007-02-20 00:00:00 | 35000.00 |
| 2 | 2007-07-15 00:00:00 | 220000.00 |
+------------+---------------------+-----------+
4 rows in set (0.00 sec) 3.向MERGE表中插入数据,则可以看到的是向最后的MyISAM表中插入的
mysql> insert into payment_all values(3,'2006-03-31',112200);
Query OK, 1 row affected (0.00 sec) mysql> select * from payment_all;
+------------+---------------------+-----------+
| country_id | payment_date | amount |
+------------+---------------------+-----------+
| 1 | 2006-05-01 00:00:00 | 100000.00 |
| 2 | 2006-08-15 00:00:00 | 150000.00 |
| 1 | 2007-02-20 00:00:00 | 35000.00 |
| 2 | 2007-07-15 00:00:00 | 220000.00 |
| 3 | 2006-03-31 00:00:00 | 112200.00 |
+------------+---------------------+-----------+
5 rows in set (0.00 sec)

MERGE表使用示例

  

MySQL开发篇(4)表类型(存储引擎)的选择的更多相关文章

  1. Mysql表类型(存储引擎)的比较

    面试官问:你知道mysql有哪些存储引擎,区别是啥? 我:一脸闷逼,于是乎下来补一补,以作备查 1.和大多数数据库不同,MySQL 中有一个存储引擎的概念,针对不同的存储需求可以选择最优的存储引擎. ...

  2. MySQL查看和修改表的存储引擎(转载+加点东西)

    1 查看系统支持的存储引擎 show engines; 2 查看表使用的存储引擎 两种方法: a.show table status from YOUR_DB_NAME where name='YOU ...

  3. MySQL查看和修改表的存储引擎

    1 查看系统支持的存储引擎 show engines; 2 查看表使用的存储引擎 两种方法: a.show table status from db_name where name='table_na ...

  4. MySQL开发——【多表关系、引擎、外键、三范式】

    多表关系 一对一关系 一对多或多对一关系 多对多关系 MySQL引擎 所谓的MySQL引擎就是数据的存储方式,常用的数据库引擎有以下几种: Myisam与InnoDB引擎之间的区别(面试) ①批量插入 ...

  5. MySQL开发篇,存储引擎的选择真的很重要吗?

    前言 谁说MySQL查询千万级别的数据很拉跨?我今天就要好好的和你拉拉家常,畅谈到深夜,一起过除夕!这篇文章也是年前的最后一篇,希望能带给大家些许收获,不知不觉查找文档和参考实体书籍就写了这么多,自己 ...

  6. MySql(一)表类型(存储引擎)

    MySql(一)表类型(存储引擎) 一.MYSQL存储引擎概述 二.存储引擎的特性对比 2.1 MyISAM 2.2 InnoDB 2.2.1 自动增长列 2.2.2 外键约束 2.2.3 存储方式 ...

  7. mysql 开发基础系列8 表的存储引擎

    一. 表的存储引擎 1. 概述 插件式存储引擎是mysql数据库最重要的特性之一, 用户可以根据应用的需要选择如何存储和索引数据,是否使用事务等.在mysql 5.0里支持的引擎包括: MyISAM, ...

  8. mysql修改表的存储引擎(myisam<=>innodb)

    查看当前数据库的所支持的数据库引擎以及默认数据库引擎 mysql> show engines; +--------------------+---------+----------------- ...

  9. MySQL更改数据库表的存储引擎

    MySQL更改数据库表的存储引擎 1.查看表的原存储引擎 show create table user; 'user', 'CREATE TABLE `user` (\n `id` int(11) N ...

随机推荐

  1. java自学小测试 九九乘法表

    public class Ninenine { public static void main(String[] args) { for(int i=1;i<=9;i++){ for(int j ...

  2. 先森林后树木:Elasticsearch各版本升级核心内容必看

    在学习Elasticsearch 时候,因为各个版本的问题,搞不清,非常的头疼,官方也给出了各个版本更新的情况,不过是英文版本,版本更新信息又特别多,最近学习,看了很多资料,没有一个整理很清楚的,然后 ...

  3. centos 7 常用yum源配置

    使用centos系统最熟悉的莫过于yum命令,yum命令可以让安装软件变得那么简单,编译安装的依赖关系大部分都会解决. 工具/原料   centos 7 wget yum 方法/步骤     什么是y ...

  4. FTP协议的主动模式和被动模式的区别

    最近准备做一个<FtpCopy系列教程>,主要讲解Ftp协议主动模式和被动模式的区别.以及FTP服务器的安装部署,然后通过几个常用实例演示,详细讲解如何使用FtpCopy进行数据自动备份. ...

  5. 链表二:链表中倒数第k个结点

    题目:链表中倒数第k个结点描述:输入一个链表,输出该链表中倒数第k个结点.解决方案:思路: 根据规律得出倒数第k个节点是 n-k+1个节点 方法一:先计算出链表的长度,在循环走到n-k+1步.(相当于 ...

  6. nginx(tengine)访问日志分片

    说明 nginx日志按天分片是运维的基本要求,不仅可以减小文件大小,方便检索关键数据,也可以定时删除过期的日志.可是nginx和tengine默认并不支持文件分片,因此需要额外处理. 另外,日志分片需 ...

  7. GoLang 获取两个时间相差多少小时

    package main import ( "fmt" "time" ) func main() { fmt.Println(getHourDiffer(&qu ...

  8. golang的生产者消费者模型示例

    package main import "fmt" func Producer(ch chan int) { for i := 1; i <= 10; i++ { ch &l ...

  9. 移动端border-radius的几个BUG

    个人博客: http://mcchen.club 一.Android 2.3 自带浏览器不支持 % 通常我们实现一个正圆只需要border-radius: 50%即可,大致代码如下 .foo { wi ...

  10. Java读源码之ThreadLocal

    前言 JDK版本: 1.8 之前在看Thread源码时候看到这么一个属性 ThreadLocal.ThreadLocalMap threadLocals = null; ThreadLocal实现的是 ...