MySQL的存储引擎

MySQL5.0支持的存储引擎包括 MyISAM,InnoDB,MEMORY,MERGE , BDB, EXAMPLE,NDB Cluster,ARCHIVE, CSV, BLACKHOLE,FEDERATED

1.MyISAM

  • 不支持事务,也不支持外键
  • 访问速度快
  • 对事务完整性没有要求或者以select,insert为主的应用基本都可以使用MyISAM
  • 每个MyISAM在磁盘上存储成3个文件,文件名和表名都相同,扩展名分别是:

    • .frm(存储表定义)
    • .MYD(MYdata,存储数据)
    • .MYI(MYIndex,存储索引)

    MyISAM类型的表可能会损坏,损坏后的表不能被访问,会提示需要修复或者访问后返回错误的结果。
    MyISAM类型的表提供修复的工具,可以用CHECK TABLE检查是否损坏,REPAIR TABLE鞋服一个损坏的MyISAM表。
    MyISAM支持3种不同的存储格式:

    • 静态(固定长度)表:会丢失尾部空格
    • 动态表:频繁的更新和删除记录会产生碎片,需定期执行OPTIMIZE TABLE 语句或者myisamchk-r命令来改善性能,出现故障恢复困难。
    • 压缩表:有myisampack工具创建

    2. InnoDB

    InnoDB存储引擎提供了具有提交,回滚和崩溃恢复能力的事务安全,但是对比MyISAM存储引擎,InnoDB写的处理效率差一些,并且会占用更多的磁盘空间以保留数据和索引。

    • 自动增长列:InnoDB的自动增长列可以手工插入,但是插入的值如果是空或者0,则实际插入的将是自动增长后的值。

      alter table autoincre_demo auto_increment = n; 强制设置自动增长列的初始值,默认从1开始,但是该强制的默认值是保留在内存中的,如果该值在使用之前数据库重新启动,那么这个强制的默认值就会丢失,需要在数据库启动以后重新设置。

      last_insert_id()//查询当前线程最后插入记录使用的值,如果一次插入多条记录,那么返回的是第一条记录使用的自动增长值。

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

    • 外键约束
      MySQL支持外键的存储引擎只有InnoDB,在创建外键的时候,要求父表必须有对应的索引,子表在创建外键的时候也会创建对应的索引

     create table country(
     country_id smallint unsigned not null auto_increment,
     country varchar(50) not null,
     last_update timestamp not null default current_timestamp on update current_timestamp,
     primary key (country_id)
)engine=innodb default charset=utf8;

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),
key idx_fk_country_id (country_id),
constraint 'fk_city_country' foreign key (country_id) references country (country_id) on delete restrict on update cascade
)engine=innodb default charset=utf8;

在创建索引时,可以指定在删除,更新父表时,对子表进行的相应操作,包括restrict,cascade,set null和no action。
其中,restrict和no action 相同,是指限制在子表有关联记录的情况下父表不能更新;
cascade表示父表在更新或者删除时,更新或者删除子表对应记录;
set null则表示父表在更新或者删除的时候,子表的对应字段被set null。
选择后两种方式时要谨慎,因为可能错误的操作导致数据的丢失

当某个表被其他表创建了外键参照,呢么该表的对应索引或者主键禁止被删除。
导入多个表的数据时,如要忽略表之前的导入顺序,或者在执行load data和alter table操作时,可以暂时关闭外键约束来加快处理速度。
关闭命令:set foreign_key_checks=0;
还原:set foreign_key_checks=1;
对于InnoDB的表,外键信息通过使用show create table或者show table status命令都能实现
如:show table status like ‘city’\G

  • InnoDB的存储方式
    InnoDB存储表和索引有以下两种方式:
    • 使用共享表存储
    • 使用多表空间存储

3.MEMORY

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

create table tab_memory engine=memory select city_id,city,country_id from city group by city_id;

给memory表创建索引的时候,可以指定使用HASH索引还是BTREE索引:

create index mem_hash using hash on tab_memory (city_id);
show index from tab_memory \G;//显示索引信息

当不再需要memory表的内容之时,要释放被memory表使用的内存,应该执行delete from 或truncate table,或者整个的删除表(drop table)
MEMORY类型的存储引擎主要用于那些内容变化不频繁的代码表,或者作为统计操作的中间结果表,便于高效的对中间结果进行分析并得到最终统计结果。
对MEMORY引擎的表进行更新要谨慎,因为数据并没有实际写到磁盘中,所以一定要对下次重新启动服务后如何获得这些修改后的数据有所考虑。

4.MERGE

MERGE是一组MyISAM表的组合,这些MyISAM表结构完全相同,MERGE表本身并没有数据,对MERGE类型的表进行的查询,更新,删除操作,这些操作实际上是对内部的MyISAM表进行的。对MERGE类型的表插入操作,是通过INSERT_METHOD子句定义插入的表,可以有3个不同的值,使用FIRST或LAST值使得插入操作被相应的作用在第一或最后一个表上,不定义这个子句或者定义为NO,表示不能对这个MERGE表执行插入操作。
可以对MERGE表进行DROP操作,这个操作只删除MERGE的定义,对内部的表没有任何影响
MERGE表在磁盘上保留两个文件,文件名以表的名字开始

  • .frm文件存储表定义
  • .MRG文件包含组合表的信息,包括MERGE表由哪些表组成,插入新的数据时的依据。可以通过修改.MRG文件来修改MERGE表,但是修改后要通过FLUSH TABLES刷新
create table payment_2006( country_id smallint, payment_date datetime, amount decimal(15,2), key idx_fk_country_id(country_id) )engine=myisam;

create table payment_2007( country_id smallint, payment_date datetime, amount decimal(15,2), key idx_fk_country_id(country_id) )engine=myisam;

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;
//分别向payment_2006和payment_2007表中插入测试数据:
insert into payment_2006 values(1,'2006-05-01',100000),(2,'2006-08-15',150000);
insert into payment_2007 values(1,'2007-02-20',350000),(2,'2007-07-15',220000);
//查看3个表里的记录
select * from payment_2006;
select * from payment_2007;
select * from payment_all;

//向payment_all中插入一条记录,由于payment_all定义的是insert_method=last,就会向最后一个表中插入记录(payment_2007)
insert into payment_all values(3,'2006-03-31',112200);

这是MERGE表和分区表的区别,MERGE表并不能智能的将记录写到对应的表中,而分区表是可以的。
通常我们使用MERGE表来透明的对多个表进行查询和更新,而对这种按照时间记录的操作日志则可以透明的进行插入操作。

5.第三方存储引擎

  • 列式存储引擎Infobright
  • 高写性能高压缩的TokuDB
    TokuDB是一个高性能,支持事务处理的MySQL和MariaDB的存储引擎,具有高扩展性,高压缩率,高效的写入性能,支持大多数在线DDL操作。
    TokuDB特性:
    • 使用Fractal树索引保证高效的插入性能
    • 优秀的压缩特性,比InnoDB高近10倍
    • Hot Schema CHanges特性支持在线创建索引和添加、删除属性列等DDL操作
    • 使用Bulk Loader达到快速加载大量数据
    • 提供了主从延迟消除技术
    • 支持ACID和MVCC
      TOkuDB适用于:
      • 日志数据(日志通常插入频繁且存储量大)
      • 历史数据,通常不会再有写操作,可以利用TokuDB的高压缩特性进行存储
      • 在线DDL较频繁的场景,使用TokuDB大大增加系统的可用性

你可能感兴趣的:(mysql,引擎)