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

我想知道是否有一种方法可以快速将它们全部更改为InnoDB?


当前回答

如果您使用的是Windows,您可以在批处理文件中使用以下循环完成此任务。

set database=YOURDATABASENAME
for /F "tokens=1 skip=1 usebackq" %%a in (`mysql %%database%% -e "show table status where Engine != 'InnoDB';"`) do (
    mysql %database% -e "ALTER TABLE %%a ENGINE = 'InnoDB';"
)

只需将YOURDATABASENAME更改为目标数据库的名称,或者使用%~1通过命令行传递数据库名称。

所有当前不是InnoDB的表都将被转换为InnoDB。如果您像问题所建议的那样专门针对MyISAM,下面的代码有一个仅针对MyISAM的更新的MySQL条件。

set database=YOURDATABASENAME
for /F "tokens=1 skip=1 usebackq" %%a in (`mysql %%database%% -e "show table status where Engine = 'MyISAM';"`) do (
    mysql %database% -e "ALTER TABLE %%a ENGINE = 'InnoDB';"
)

其他回答

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

如果你在DB服务器之间迁移(或者有其他原因你需要转储和重新加载你的dta),你可以修改mysqldump的输出:

mysqldump --no-data DBNAME | sed 's/ENGINE=MyISAM/ENGINE=InnoDB/' > my_schema.sql;
mysqldump --no-create-info DBNAME > my_data.sql;

然后再次加载:

mysql DBNAME < my_schema.sql && mysql DBNAME < my_data.sql

(此外,根据我有限的经验,这可能是一个比“实时”修改表快得多的过程。这可能取决于数据和索引的类型。)

您可以用您最喜欢的脚本语言编写一个脚本来完成它。该脚本将执行以下操作:

Issue显示满表。对于返回的每一行,检查第二列是否显示为“BASE TABLE”而不是“VIEW”。如果它不是'VIEW',发出适当的ALTER TABLE命令。

一个简单的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;

当表很大时,最好从控制台进行操作

convert-to-innodb.sh

#!/usr/bin/env bash

# Usage: ./convert-to-innodb.sh 'db' 'user' 'password' | mysql 'db' -u  user -p password


set -eu

db="$1"
user="$2"
pass="$3"


sql="SET @DATABASE_NAME = '${db}';"

sql+="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;"

echo $sql | mysql -u${user} -p${pass} | tail -n +2 

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

  ALTER TABLE table_name ENGINE = INNODB;