如何将所有表从MyISAM转换为InnoDB?

Pen*_*m10 245 mysql sql innodb

我知道我可以单独发出一个alter table来将表存储从MyISAM更改为InnoDB.

我想知道是否有办法快速将所有这些更改为InnoDB?

小智 527

运行此SQL语句(在MySQL客户端,phpMyAdmin或其中),以检索数据库中的所有MyISAM表.

name_of_your_db用您的数据库名称替换变量的值.

SET @DATABASE_NAME = 'name_of_your_db';

SELECT  CONCAT('ALTER TABLE `', table_name, '` ENGINE=InnoDB;') AS sql_statements
FROM    information_schema.tables AS tb
WHERE   table_schema = @DATABASE_NAME
AND     `ENGINE` = 'MyISAM'
AND     `TABLE_TYPE` = 'BASE TABLE'
ORDER BY table_name DESC;
Run Code Online (Sandbox Code Playgroud)

然后,复制输出并作为新的SQL查询运行.

  • 如果您处理多个数据库并且不想每次都更改数据库,请将``CONCAT('ALTER TABLE',table_name,'ENGINE = InnoDB;')``更改为``CONCAT('ALTER TABLE',@ DATABASE_NAME ,'.',table_name,'ENGINE = InnoDB;')`` (11认同)
  • 这很好用!我在这里把它放到一个示例shell脚本中:http://shrubbery.mynetgear.net/c/display/W/Shell+and+MySQL#ShellandMySQL-ConvertMyISAMtablestoInnoDB (4认同)
  • "#1267非法混合排序......"我收到这个错误,它不起作用 (4认同)
  • 如果要获取所有数据库(MySQL 系统数据库除外)的语句:`SELECT CONCAT('ALTER TABLE \`', table_schema, '\`.\`', table_name, '\` ENGINE=InnoDB;' ) AS sql_statements FROM information_schema.tables WHERE table_schema NOT IN ('information_schema', 'performance_schema', 'mysql') AND engine = 'MyISAM' AND table_type = 'BASE TABLE' ORDER BY table_schema,table_name` (3认同)
  • 只是出于好奇,显式降序的意义是什么?(`ORDER BY 表名 DESC`) (2认同)

Gaj*_*ang 162

    // Actual code starts here 

    $sql = "SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
        WHERE TABLE_SCHEMA = 'your_database_name' 
        AND ENGINE = 'MyISAM'";

    $rs = mysql_query($sql);

    while($row = mysql_fetch_array($rs))
    {
        $tbl = $row[0];
        $sql = "ALTER TABLE `$tbl` ENGINE=INNODB";
        mysql_query($sql);
    }
?>
Run Code Online (Sandbox Code Playgroud)

  • PHP的`mysql_*`接口已弃用并从版本7中删除.请勿按原样使用此代码. (6认同)
  • 将此限制在您关注的数据库中可能会更好.添加"AND TABLE_SCHEMA ='dbname',否则这可以/将所有互联网MySQL表更改为innodb(当其中一些应该是内存时) (5认同)
  • @GajendraBang - 是的,答案在提出时有效.但对于新手来说,它已不再有效.我的意图是警告不要使用它_as is_. (3认同)
  • 最近的编辑怎么没有被标记?MySQL 部分是 Will Jones 答案的直接副本。查看每个编辑历史记录,发现 Will 的答案出现在 2013 年,而这个答案出现在 2019 年。因此,这个问题的完整性受到了损害。 (2认同)

小智 54

SELECT CONCAT('ALTER TABLE ',TABLE_NAME,' ENGINE=InnoDB;') 
FROM INFORMATION_SCHEMA.TABLES
WHERE ENGINE='MyISAM'
AND table_schema = 'mydatabase';
Run Code Online (Sandbox Code Playgroud)

奇迹般有效.

这将为您提供可以批量运行的alter query的所有表的列表

  • 运行此操作后,首先需要执行以下查询:USE databasename; 然后,您可以使用上述脚本提供的查询. (5认同)
  • 它甚至可以在 2018 年和 Percona Cluster 上运行。如果从 PHPMyAdmin 使用它,您只会得到 20 个左右的名称,然后是“...”或分页 >> 符号。这意味着您必须单击并继续复制所有下一页,这样您就不会错过任何表格。如果你忘记了,你可以安全地重新应用上面的查询,它会给你下一个 MyISAM 表来转换。 (2认同)

Vij*_*dan 23

在下面的脚本中,将<username>,<password>和<schema>替换为您的特定数据.

要显示可以复制粘贴到mysql客户端会话的语句,请键入以下内容:

echo 'SHOW TABLES;' \
 | mysql -u <username> --password=<password> -D <schema> \
 | awk '!/^Tables_in_/ {print "ALTER TABLE `"$0"` ENGINE = InnoDB;"}' \
 | column -t \
Run Code Online (Sandbox Code Playgroud)

要简单地执行更改,请使用以下命令:

echo 'SHOW TABLES;' \
 | mysql -u <username> --password=<password> -D <schema> \
 | awk '!/^Tables_in_/ {print "ALTER TABLE `"$0"` ENGINE = InnoDB;"}' \
 | column -t \
 | mysql -u <username> --password=<password> -D <schema>
Run Code Online (Sandbox Code Playgroud)

信用:这是本文中概述的变体.


小智 21

一条线:

 mysql -u root -p dbName -e 
 "show table status where Engine='MyISAM';" | awk 
 'NR>1 {print "ALTER TABLE "$1" ENGINE = InnoDB;"}'  | 
  mysql -u root -p dbName
Run Code Online (Sandbox Code Playgroud)


小智 20

在phpMyAdmin中将其用作sql查询

SELECT CONCAT('ALTER TABLE ',table_schema,'.',table_name,' engine=InnoDB;') 
FROM information_schema.tables 
WHERE engine = 'MyISAM';
Run Code Online (Sandbox Code Playgroud)

  • 这似乎并没有真正将表转换为InnoDB. (3认同)
  • 这会输出一个脚本然后运行以转换表 - 这是两个步骤.它尝试转换INFORMATION_SCHEMA表 - 这是一件坏事.需要将其限制在正确的数据库中. (3认同)
  • 非常好。我还使用以下查询转义了表名称并忽略了系统表: ```SELECT CONCAT('ALTER TABLE `',table_schema,'`.`',table_name,'` engine=InnoDB;') FROM information_schema.tables WHERE 引擎 = 'MyISAM' 且 table_schema 不在 ('information_schema','mysql','performance_schema','sys');``` (2认同)

Hen*_*ann 17

您可以在mysql命令行工具中执行此语句:

echo "SELECT concat('ALTER TABLE `',TABLE_NAME,'` ENGINE=InnoDB;')
FROM Information_schema.TABLES 
WHERE ENGINE != 'InnoDB' AND TABLE_TYPE='BASE TABLE' 
AND TABLE_SCHEMA='name-of-database'" | mysql > convert.sql
Run Code Online (Sandbox Code Playgroud)

您可能需要使用以下命令指定用户名和密码:mysql -u username -p结果是一个sql脚本,您可以将其重新导入mysql:

mysql name-of-database < convert.sql
Run Code Online (Sandbox Code Playgroud)

在上面的语句和命令行中替换"name-of-database".

  • 那就对了。但是您提到过“ mysql命令行工具” (2认同)

Sac*_*une 10

这很简单只有两步就是复制和粘贴:

步骤1.

  SET @DATABASE_NAME = 'name_of_your_db';
  SELECT  CONCAT('ALTER TABLE `', table_name, '` ENGINE=InnoDB;') AS  sql_statements FROM information_schema.tables AS tb WHERE   table_schema = @DATABASE_NAME AND `ENGINE` = 'MyISAM' AND `TABLE_TYPE` = 'BASE TABLE' ORDER BY table_name DESC;
Run Code Online (Sandbox Code Playgroud)

(将所有结果复制并粘贴到sql选项卡中)

步骤2 :(将所有结果复制到sql选项卡中)并粘贴到该行的下方

开始交易;

承诺;

例如.开始交易;

ALTER TABLE admin_filesENGINE = InnoDB;

承诺;


Qui*_*ant 8

它还没有被提及,所以我会为后人写它:

如果您在数据库服务器之间迁移(或者有其他原因要转储并重新加载您的dta),您只需修改输出mysqldump:

mysqldump --no-data DBNAME | sed 's/ENGINE=MyISAM/ENGINE=InnoDB/' > my_schema.sql;
mysqldump --no-create-info DBNAME > my_data.sql;
Run Code Online (Sandbox Code Playgroud)

然后再次加载:

mysql DBNAME < my_schema.sql && mysql DBNAME < my_data.sql
Run Code Online (Sandbox Code Playgroud)

(另外,在我有限的经验中,这可能比更改表'live'要快得多.它可能取决于数据和索引的类型.)


lee*_*ech 7

这是Django用户的一种方法:

from django.core.management.base import BaseCommand
from django.db import connections


class Command(BaseCommand):

    def handle(self, database="default", *args, **options):

        cursor = connections[database].cursor()

        cursor.execute("SHOW TABLE STATUS");

        for row in cursor.fetchall():
            if row[1] != "InnoDB":
                print "Converting %s" % row[0],
                result = cursor.execute("ALTER TABLE %s ENGINE=INNODB" % row[0])
                print result
Run Code Online (Sandbox Code Playgroud)

在文件夹管理/命令下将其添加到您的应用程序/然后您可以使用manage.py命令转换所有表:

python manage.py convert_to_innodb
Run Code Online (Sandbox Code Playgroud)


Lav*_*dor 7

要为所有非系统模式中的所有表生成ALTER语句,请按这些模式/表排序,运行以下命令:

SELECT  CONCAT('ALTER TABLE ',TABLE_SCHEMA,'.', table_name, ' ENGINE=InnoDB;') AS sql_statements
FROM    information_schema.tables
WHERE   TABLE_SCHEMA NOT IN ('mysql', 'information_schema', 'performance_schema', 'innodb', 'sys', 'tmp')
AND     `ENGINE` = 'MyISAM'
AND     `TABLE_TYPE` = 'BASE TABLE'
ORDER BY TABLE_SCHEMA, table_name DESC;
Run Code Online (Sandbox Code Playgroud)

之后,通过客户端运行这些查询以执行更改.

  • 答案基于以上答案,但改进了架构处理.


小智 7

只是测试了另一种(简单?)方法,并为我工作。

只需将数据库导出为 .sql 文件,然后使用 gedit 或记事本进行编辑即可;

替换ENGINE=MyISAMENGINE=INNODB并保存编辑的文件

完成的数量或更换应该是您的桌子的数量

将其导入MySQL(phpMyAdmin或命令行)

瞧!


PJ *_*net 5

从mysql内部,您可以使用文本编辑器进行搜索/替换:

SELECT table_schema, table_name FROM INFORMATION_SCHEMA.TABLES WHERE engine = 'myisam';
Run Code Online (Sandbox Code Playgroud)

注意:你或许应该忽略INFORMATION_SCHEMA和MySQL,因为"mysql和INFORMATION_SCHEMA数据库,实现一些MySQL的内部,依然使用MyISAM特别的,你不能切换授权表中使用InnoDB." (http://dev.mysql.com/doc/refman/5.5/en/innodb-default-se.html)

在任何情况下,请注意要忽略并运行的表:

SELECT table_name FROM INFORMATION_SCHEMA.TABLES WHERE engine = 'myisam';
Run Code Online (Sandbox Code Playgroud)

现在只需将该列表复制/粘贴到文本编辑器中并搜索/替换"|" 用"ALTER TABLE"等

然后你会有一个这样的列表,你可以简单地粘贴到你的mysql终端:

ALTER TABLE arth_commentmeta           ENGINE=Innodb;
ALTER TABLE arth_comments              ENGINE=Innodb;
ALTER TABLE arth_links                 ENGINE=Innodb;
ALTER TABLE arth_options               ENGINE=Innodb;
ALTER TABLE arth_postmeta              ENGINE=Innodb;
ALTER TABLE arth_posts                 ENGINE=Innodb;
ALTER TABLE arth_term_relationships    ENGINE=Innodb;
ALTER TABLE arth_term_taxonomy         ENGINE=Innodb;
ALTER TABLE arth_terms                 ENGINE=Innodb;
ALTER TABLE arth_usermeta              ENGINE=Innodb;
Run Code Online (Sandbox Code Playgroud)

如果你的文本编辑器不能轻易做到这一点,这里是另一个解决方案,从linux终端获取一个类似的列表(你可以粘贴到mysql)只为数据库的一个前缀:

mysql -u [username] -p[password] -B -N -e 'show tables like "arth_%"' [database name] | xargs -I '{}' echo "ALTER TABLE {} ENGINE=INNODB;"
Run Code Online (Sandbox Code Playgroud)


Dev*_*per 5

使用此行更改单个表的数据库引擎。

  ALTER TABLE table_name ENGINE = INNODB;
Run Code Online (Sandbox Code Playgroud)


小智 5

一个普通的MySQL版本。

您可以简单地启动mysql可执行文件,使用数据库并复制粘贴查询。

这会将当前数据库中的所有MyISAM表转换为INNODB表。

DROP PROCEDURE IF EXISTS convertToInnodb;
DELIMITER //
CREATE PROCEDURE convertToInnodb()
BEGIN
mainloop: LOOP
  SELECT TABLE_NAME INTO @convertTable FROM information_schema.TABLES
  WHERE `TABLE_SCHEMA` LIKE DATABASE()
  AND `ENGINE` LIKE 'MyISAM' ORDER BY TABLE_NAME LIMIT 1;
  IF @convertTable IS NULL THEN 
    LEAVE mainloop;
  END IF;
  SET @sqltext := CONCAT('ALTER TABLE `', DATABASE(), '`.`', @convertTable, '` ENGINE = INNODB');
  PREPARE convertTables FROM @sqltext;
  EXECUTE convertTables;
  DEALLOCATE PREPARE convertTables;
  SET @convertTable = NULL;
END LOOP mainloop;

END//
DELIMITER ;

CALL convertToInnodb();
DROP PROCEDURE IF EXISTS convertToInnodb;
Run Code Online (Sandbox Code Playgroud)