MySQL手册中有介绍。

通常我只是转储数据库并用一个新名称重新导入它。这不是非常大的数据库的一个选项。重命名数据库| SCHEMA} db_name TO new_db_name做坏事,只存在于少数版本中,总的来说是个坏主意。

这需要与InnoDB一起工作,InnoDB存储的东西与MyISAM非常不同。


当前回答

可以将一个数据库中的所有表重命名为另一个数据库下的所有表,而不必执行完整的转储和恢复。

DROP PROCEDURE IF EXISTS mysql.rename_db;
DELIMITER ||
CREATE PROCEDURE mysql.rename_db(IN old_db VARCHAR(100), IN new_db VARCHAR(100))
BEGIN
SELECT CONCAT('CREATE DATABASE ', new_db, ';') `# create new database`;
SELECT CONCAT('RENAME TABLE `', old_db, '`.`', table_name, '` TO `', new_db, '`.`', table_name, '`;') `# alter table` FROM information_schema.tables WHERE table_schema = old_db;
SELECT CONCAT('DROP DATABASE `', old_db, '`;') `# drop old database`;
END||
DELIMITER ;

$ time mysql -uroot -e "call mysql.rename_db('db1', 'db2');" | mysql -uroot

然而,目标db中的任何触发器都不会开心。您需要先删除它们,然后在重命名后重新创建它们。

mysql -uroot -e "call mysql.rename_db('test', 'blah2');" | mysql -uroot
ERROR 1435 (HY000) at line 4: Trigger in wrong schema

其他回答

当您在PHPMyAdmin中重命名数据库时,它会创建一个转储,然后删除并使用新名称重新创建数据库。

似乎没有人提到这一点,但这里有另一种方式:

create database NewDatabaseName like OldDatabaseName;

然后对每个表执行:

create NewDatabaseName.tablename like OldDatabaseName.tablename;
insert into NewDataBaseName.tablename select * from OldDatabaseName.tablename;

然后,如果你想,

drop database OldDatabaseName;

这种方法的优点是可以在几乎为零的网络流量的情况下在服务器上完成整个传输,因此它比转储/恢复快得多。

如果你有存储过程/视图等,你可能也想要传输它们。

可以使用SQL生成SQL脚本,将源数据库中的每个表传输到目标数据库。

在运行该命令生成的脚本之前,必须先创建目标数据库。

您可以使用这两个脚本中的任何一个(我最初建议使用前者,有人“改进”了我的回答,使用GROUP_CONCAT。随你挑,但我更喜欢原版):

SELECT CONCAT('RENAME TABLE $1.', table_name, ' TO $2.', table_name, '; ')
FROM information_schema.TABLES 
WHERE table_schema='$1';

or

SELECT GROUP_CONCAT('RENAME TABLE $1.', table_name, ' TO $2.', table_name SEPARATOR '; ')
FROM information_schema.TABLES 
WHERE table_schema='$1';

($1和$2分别是源和目标)

这将生成一个SQL命令,然后必须运行该命令。

注意,GROUP_CONCAT有一个默认的长度限制,对于包含大量表的数据库可能会超过这个长度限制。您可以通过执行SET SESSION group_concat_max_len = 100000000来更改该限制;(或其他较大的数字)。

为了方便起见,下面是一个小shell脚本,必须使用两个参数执行:db-name和new db-name。

如果您不使用主目录中的.my.cnf文件,则可能需要在mysql行中添加登录参数。请在执行此脚本之前进行备份。


#!/usr/bin/env bash

mysql -e "CREATE DATABASE $2 DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;"
for i in $(mysql -Ns $1 -e "show tables");do
    echo "$1.$i -> $2.$i"
    mysql -e "rename TABLE $1.$i to $2.$i"
done
mysql -e "DROP DATABASE $1"

这里已经有很多非常好的答案,但我没有看到PHP版本。这将在大约一秒钟内复制一个800M DB。

$oldDbName = "oldDBName";
$newDbName = "newDBName";
$oldDB     = new mysqli("localhost", "user", "pass", $oldDbName);
if($oldDB->connect_errno){
    echo "Failed to connect to MySQL: (" . $oldDB->connect_errno . ") " . $oldDB->connect_error;
    exit;
}
$newDBQuery = "CREATE DATABASE IF NOT EXISTS {$newDbName}";
$oldDB->query($newDBQuery);
$newDB = new mysqli("localhost", "user", "pass");
if($newDB->connect_errno){
    echo "Failed to connect to MySQL: (" . $newDB->connect_errno . ") " . $newDB->connect_error;
    exit;
}

$tableQuery  = "SHOW TABLES";
$tableResult = $oldDB->query($tableQuery);
$renameQuery = "RENAME TABLE\n";
while($table = $tableResult->fetch_array()){
    $tableName = $table["Tables_in_{$oldDbName}"];
    $renameQuery .= "{$oldDbName}.{$tableName} TO {$newDbName}.{$tableName},";
}
$renameQuery = substr($renameQuery, 0, strlen($renameQuery) - 1);
$newDB->query($renameQuery);