MySql 转换表的引擎

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zhang_referee/article/details/82812373

有很多中方法可以将表的存储引擎转换成另外一种引擎。我们在这只讲述其中的三种方法:

ALTER TABLE

将表从一个引擎修改为另一个引擎最简单的办法是使用 ALTER TABLE语句。下面的语句将 mytable的引擎修改为 INNODB:

mysql> ALTER TABLE mytable ENGINE INNODB;

上述语法可以适用任何存储引擎。但有一个问题:需要执行很长时间。 MYSQL会按行将数据从原表复制到一张新的表中,在复制期间可能会消耗系统所有的I/O能力,同时原表上会加上读锁。所以,在繁忙的表上执行此操作要特别小心。一个替代方案是采用接下来将讨论的导出与导入的方法,手工进行表的复制。

如果转换表的存储引檠,将会失去和原引擎相关的所有特性。例如,如果将一张 INNODB表转换为 MYISAM,然后再转换回 INNODB,原 INNODB表上所有的外键将丢失。

好了,当我介绍了这第一种方法后,您先别急着去实际体验或者操作一把,因为不一定操作成功哦!啊哈哈!

下面是我的操作,反正我是操作失败了的,这种方法并不一定会操作成功,并不好用哦!

首先我先查看下想要操作的数据表表状态:

使用了 show table status like 'dye_production_schedules' \G 语句。

show table status 具体语法如下:

SHOW TABLE STATUS
    [{FROM | IN} db_name]
    [LIKE 'pattern' | WHERE expr]

看到这里,相比就不用我再解释,我之前那条语句了吧!!!

其中:

Name 表示表名

Engine: 表示表的存储引擎类型。在旧版本中,该列的名字叫Type,而不是Engine。

Version:版本 关于版本这个问题,可以参考mysql mvcc(多版本控制) ,可以参考其它文章

Row_format:行格式。对于MyISAM引擎,这可能是Dynamic,Fixed或Compressed。动态行的行长度可变,例如Varchar或Blob类型字段。固定行是指行长度不变,例如Char和Integer类型字段。

Rows:表中的行数。对于非事务性表,这个值是精确的,对于事务性引擎,这个值通常是估算的。

Avg_row_length:平均每行包含的字节数

Data_length:表数据的大小 (以字节为单位)

Max_data_length:表数据的最大容量,该值和存储引擎有关。

Index_length:索引的大小(以字节为单位)

Data_free:对于MyISAM 表,表示已分配但目前没有使用的空间。这部分空间包括了之前删除的行,以及后续可以被INSERT利用到的空间。

Auto_increment:下一个 AUTO INCREMENT的值。

Create_time:表的创建时间。

Update_time:表数据的最后修改时间

Check_time:使用 CKECK TABLE命令或者 myisamchk工具最后一次检査表的时间。

Collation:表的默认字符集和字符列排序规则。

Cksum:如果启用,保存的是整个表的实时校验和。

Create options:创建表时指定的其他选项。

Comment:该列包含了一些其他的额外信息。对于 MYISAM表,保存的是表在创建时带的注释。
对于 INNODB表,则保存的是 INNODB表空间的剩余空间信息。如果是一个视图,则
该列包含“VIEW”的文本字样。

好的,解释完了上条命令产生的结果集后,我们正式进入主题

mysql> alter table dye_production_schedules engine = myisam;
ERROR 1292 (22007): Incorrect datetime value: '0000-00-00 00:00:00' for column 'date' at row 7994
mysql>
 

纳尼?为什么在创建表的时候不报错?为什么?

这个不行?我换张表总可以了吧,嘿嘿!!我换成WordPress 库表去操作!

mysql> use wordpress;
Database changed
mysql> show tables;
+-----------------------+
| Tables_in_wordpress   |
+-----------------------+
| wp_commentmeta        |
| wp_comments           |
| wp_links              |
| wp_options            |
| wp_postmeta           |
| wp_posts              |
| wp_term_relationships |
| wp_term_taxonomy      |
| wp_termmeta           |
| wp_terms              |
| wp_usermeta           |
| wp_users              |
+-----------------------+
12 rows in set (0.00 sec)

mysql> show table status like 'wp_posts'  \G
*************************** 1. row ***************************
           Name: wp_posts
         Engine: MyISAM
        Version: 10
     Row_format: Dynamic
           Rows: 27
 Avg_row_length: 874
    Data_length: 23624
Max_data_length: 281474976710655
   Index_length: 12288
      Data_free: 0
 Auto_increment: 28
    Create_time: 2018-08-07 15:22:24
    Update_time: 2018-08-07 15:26:58
     Check_time: NULL
      Collation: utf8mb4_unicode_520_ci
       Checksum: NULL
 Create_options:
        Comment:
1 row in set (0.00 sec)

mysql> alter table wp_posts engine = InnoDB;
ERROR 1067 (42000): Invalid default value for 'post_date'
mysql>

咦?又失败了【手动惊恐中】

算了,既然失败了,就换种方式吧,就算是我姿势不对,但也未免太难用了吧,换种方式。

导出与导入

为了更好地控制转换的过程,可以使用 mysqldump工具将数据导出到文件,然后修改文件中 CREATE TABLE语句的存储引擎选项,注意同时修改表名,因为同一个数据库中不能存在相同的表名,即使它们使用的是不同的存储引擎。同时要注意 mysqldump默认会自动在 CREATE TABLE语句前加上 DROP TABLE语句,不注意这一点可能会导致数据丢失。

介绍完这种方式后,我并没有去实践下,理由很简单,懒,没错,你没看错就是懒,因为mysql高性能(第三版)作者已经说了,这种方式可能会导致数据丢失,那我干嘛还要去使用它呢?

创建与查询( CREATE和 SELECT)

第三种转换的技术综合了第一种方法的高效和第二种方法的安全。不需要导出整个表的数据,而是先创建一个新的存储引擎的表,然后利用 INSERT-… SELECT语法来导数据

mysql> CREATE TABLE innodb_table LIKE myisam_table;

mysql> ALTER TABLE innodb_table ENGINE=Innodb;

mysql> INSERT INTO innodb_table SELECT *  FROM myisam table;

数据量不大的话,这样做工作得很好。如果数据量很大,则可以考虑做分批处理,针对毎一段数据执行事务提交操作,以避免大事务产生过多的undo。假设有主键字段1d,重复运行以下语句(最小值x和最大值y进行相应的替换)将数据导入到新表:

mysql> START TRANSACTION

mysql> INSERT INTO innodb_table SELECT* FROM myisam_table WHERE id BETWEEN x AND yi

mysql> COMMIT;

这样操作完成以后,新表是原表的一个全量复制,原表还在,如果需要可以删除原表。如果有必要,可以在执行的过程中对原表加锁,以确保新表和原表的数据一致。

这种方式是我推荐的,操作简便快捷!

还是以dye_production_schedules 这个表为例,上面已经知道了它是InnoDB 引擎的,那好 ,我们就把它的存储引擎改成MyISAM 的。

mysql> create table myisam_dye_production_schedules like  dye_production_schedules;
Query OK, 0 rows affected (0.03 sec)

mysql> alter table myisam_dye_production_schedules engine = myisam;
Query OK, 0 rows affected (0.03 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> insert into myisam_dye_production_schedules select * from dye_production_schedules;
Query OK, 52122 rows affected, 14032 warnings (0.34 sec)
Records: 52122  Duplicates: 0  Warnings: 14032

哇,几乎是秒级别的,一下子就完成了操作,有warnnings是因为在该表中使用了外键,而myisam 不支持外键。

猜你喜欢

转载自blog.csdn.net/zhang_referee/article/details/82812373