MySQL手册中有介绍。

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

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


当前回答

你不能这么做是有原因的。(尽管有很多尝试的答案)

基本的答案在许多情况下都有效,但在其他情况下会导致数据损坏。 需要根据对数据库的启发式分析来选择策略。 这就是实现这个特性,然后又删除它的原因。(医生)

您需要转储该数据库中的所有对象类型,创建新命名的对象类型,然后导入转储。如果这是一个正常的系统,你得把它关掉。如果不能,则需要设置从此数据库到新数据库的复制。

如果您想查看可以执行此操作的命令,@satishD提供了详细信息,其中传达了一些挑战,您需要围绕这些挑战构建与目标数据库匹配的策略。

其他回答

对于那些Mac用户,Sequel Pro在数据库菜单中有一个重命名数据库选项。 http://www.sequelpro.com/

在MySQL管理员中执行以下操作:

在Catalogs下,创建一个新的数据库模式。 转到备份并创建的备份 旧的模式。 执行备份。 转到恢复并打开文件 在步骤3中创建。 在目标下选择“另一个模式” 模式并选择新的数据库 模式。 开始恢复。 验证新模式,如果看起来 很好,删除旧的。

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

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

我最近才发现了一个很好的方法,使用MyISAM和InnoDB,而且非常快:

RENAME TABLE old_db.table TO new_db.table;

我不记得我在哪里读到的,但功劳归于别人,而不是我。

这里的大多数答案都是错误的,原因有两个:

不能只使用RENAME TABLE,因为可能存在视图和触发器。如果有触发器,RENAME TABLE将失败 如果你想“快速”(如问题中要求的)重命名一个大数据库,你不能使用mysqldump

Percona有一篇关于如何做到这一点的博客文章: https://www.percona.com/blog/2013/12/24/renaming-database-schema-mysql/

以及由西蒙·R·琼斯(Simon R Jones)发布的脚本(制作的?)我修复了在脚本中发现的一个错误。你可以在这里看到:

https://gist.github.com/ryantm/76944318b0473ff25993ef2a7186213d

以下是它的副本:

#!/bin/bash
# Copyright 2013 Percona LLC and/or its affiliates
# @see https://www.percona.com/blog/2013/12/24/renaming-database-schema-mysql/
set -e
if [ -z "$3" ]; then
    echo "rename_db <server> <database> <new_database>"
    exit 1
fi
db_exists=`mysql -h $1 -e "show databases like '$3'" -sss`
if [ -n "$db_exists" ]; then
    echo "ERROR: New database already exists $3"
    exit 1
fi
TIMESTAMP=`date +%s`
character_set=`mysql -h $1 -e "SELECT default_character_set_name FROM information_schema.SCHEMATA WHERE schema_name = '$2'" -sss`
TABLES=`mysql -h $1 -e "select TABLE_NAME from information_schema.tables where table_schema='$2' and TABLE_TYPE='BASE TABLE'" -sss`
STATUS=$?
if [ "$STATUS" != 0 ] || [ -z "$TABLES" ]; then
    echo "Error retrieving tables from $2"
    exit 1
fi
echo "create database $3 DEFAULT CHARACTER SET $character_set"
mysql -h $1 -e "create database $3 DEFAULT CHARACTER SET $character_set"
TRIGGERS=`mysql -h $1 $2 -e "show triggers\G" | grep Trigger: | awk '{print $2}'`
VIEWS=`mysql -h $1 -e "select TABLE_NAME from information_schema.tables where table_schema='$2' and TABLE_TYPE='VIEW'" -sss`
if [ -n "$VIEWS" ]; then
    mysqldump -h $1 $2 $VIEWS > /tmp/${2}_views${TIMESTAMP}.dump
fi
mysqldump -h $1 $2 -d -t -R -E > /tmp/${2}_triggers${TIMESTAMP}.dump
for TRIGGER in $TRIGGERS; do
    echo "drop trigger $TRIGGER"
    mysql -h $1 $2 -e "drop trigger $TRIGGER"
done
for TABLE in $TABLES; do
    echo "rename table $2.$TABLE to $3.$TABLE"
    mysql -h $1 $2 -e "SET FOREIGN_KEY_CHECKS=0; rename table $2.$TABLE to $3.$TABLE"
done
if [ -n "$VIEWS" ]; then
    echo "loading views"
    mysql -h $1 $3 < /tmp/${2}_views${TIMESTAMP}.dump
fi
echo "loading triggers, routines and events"
mysql -h $1 $3 < /tmp/${2}_triggers${TIMESTAMP}.dump
TABLES=`mysql -h $1 -e "select TABLE_NAME from information_schema.tables where table_schema='$2' and TABLE_TYPE='BASE TABLE'" -sss`
if [ -z "$TABLES" ]; then
    echo "Dropping database $2"
    mysql -h $1 $2 -e "drop database $2"
fi
if [ `mysql -h $1 -e "select count(*) from mysql.columns_priv where db='$2'" -sss` -gt 0 ]; then
    COLUMNS_PRIV="    UPDATE mysql.columns_priv set db='$3' WHERE db='$2';"
fi
if [ `mysql -h $1 -e "select count(*) from mysql.procs_priv where db='$2'" -sss` -gt 0 ]; then
    PROCS_PRIV="    UPDATE mysql.procs_priv set db='$3' WHERE db='$2';"
fi
if [ `mysql -h $1 -e "select count(*) from mysql.tables_priv where db='$2'" -sss` -gt 0 ]; then
    TABLES_PRIV="    UPDATE mysql.tables_priv set db='$3' WHERE db='$2';"
fi
if [ `mysql -h $1 -e "select count(*) from mysql.db where db='$2'" -sss` -gt 0 ]; then
    DB_PRIV="    UPDATE mysql.db set db='$3' WHERE db='$2';"
fi
if [ -n "$COLUMNS_PRIV" ] || [ -n "$PROCS_PRIV" ] || [ -n "$TABLES_PRIV" ] || [ -n "$DB_PRIV" ]; then
    echo "IF YOU WANT TO RENAME the GRANTS YOU NEED TO RUN ALL OUTPUT BELOW:"
    if [ -n "$COLUMNS_PRIV" ]; then echo "$COLUMNS_PRIV"; fi
    if [ -n "$PROCS_PRIV" ]; then echo "$PROCS_PRIV"; fi
    if [ -n "$TABLES_PRIV" ]; then echo "$TABLES_PRIV"; fi
    if [ -n "$DB_PRIV" ]; then echo "$DB_PRIV"; fi
    echo "    flush privileges;"
fi

将它保存到一个名为rename_db的文件中,并使用chmod +x rename_db使脚本可执行,然后像。/rename_db localhost old_db new_db那样使用它