MySQL手册中有介绍。

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

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


当前回答

TodoInTX的存储过程不太适合我。以下是我的尝试:

-- stored procedure rename_db: Rename a database my means of table copying.
-- Caveats: 
-- Will clobber any existing database with the same name as the 'new' database name.
-- ONLY copies tables; stored procedures and other database objects are not copied.
-- Tomer Altman (taltman@ai.sri.com)

delimiter //
DROP PROCEDURE IF EXISTS rename_db;
CREATE PROCEDURE rename_db(IN old_db VARCHAR(100), IN new_db VARCHAR(100))
BEGIN
    DECLARE current_table VARCHAR(100);
    DECLARE done INT DEFAULT 0;
    DECLARE old_tables CURSOR FOR select table_name from information_schema.tables where table_schema = old_db;
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;

    SET @output = CONCAT('DROP SCHEMA IF EXISTS ', new_db, ';'); 
    PREPARE stmt FROM @output;
    EXECUTE stmt;

    SET @output = CONCAT('CREATE SCHEMA IF NOT EXISTS ', new_db, ';');
    PREPARE stmt FROM @output;
    EXECUTE stmt;

    OPEN old_tables;
    REPEAT
        FETCH old_tables INTO current_table;
        IF NOT done THEN
        SET @output = CONCAT('alter table ', old_db, '.', current_table, ' rename ', new_db, '.', current_table, ';');
        PREPARE stmt FROM @output;
        EXECUTE stmt;

        END IF;
    UNTIL done END REPEAT;

    CLOSE old_tables;

END//
delimiter ;

其他回答

为了方便起见,下面是一个小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"

对于InnoDB,下面的方法似乎是可行的:创建新的空数据库,然后依次将每个表重命名为新的数据库:

RENAME TABLE old_db.table TO new_db.table;

之后,您将需要调整权限。

对于在shell中编写脚本,您可以使用以下任何一种:

mysql -u username -ppassword old_db -sNe 'show tables' | while read table; \ 
    do mysql -u username -ppassword -sNe "rename table old_db.$table to new_db.$table"; done

OR

for table in `mysql -u root -ppassword -s -N -e "use old_db;show tables from old_db;"`; do mysql -u root -ppassword -s -N -e "use old_db;rename table old_db.$table to new_db.$table;"; done;

注:

选项-p和密码之间没有空格。如果您的数据库没有密码,请删除-u username -ppassword部分。 如果某个表有触发器,则不能使用上述方法将其移动到另一个数据库(将导致trigger in wrong schema错误)。如果是这种情况,使用传统的方法克隆一个数据库,然后删除旧的: Mysqldump old_db | mysql new_db 如果你有存储过程,你可以在之后复制它们: mysqldump -R old_db | mysql的new_db

我使用以下方法重命名数据库

使用mysqldump或任何数据库工具备份文件,如heidiSQL,mysql管理员等 在某些文本编辑器中打开备份(例如backupfile.sql)文件。 搜索并替换数据库名称并保存文件。

4.恢复已编辑的sql文件

ALTER DATABASE是MySQL建议的解决方法,RENAME DATABASE被删除。

从13.1.32 RENAME数据库语法:

RENAME {DATABASE | SCHEMA} db_name TO new_db_name;

此语句是在MySQL 5.1.7中添加的,但被发现是危险的,在MySQL 5.1.23中被删除。

TodoInTx的解决方案和user757945的改编解决方案都不适合我的MySQL 5.5.16,所以这里是我的改编版本:

DELIMITER //
DROP PROCEDURE IF EXISTS `rename_database`;
CREATE PROCEDURE `rename_database` (IN `old_name` VARCHAR(20), IN `new_name` VARCHAR(20))
BEGIN
  DECLARE `current_table_name` VARCHAR(20);
  DECLARE `done` INT DEFAULT 0;
  DECLARE `table_name_cursor` CURSOR FOR SELECT `table_name` FROM `information_schema`.`tables` WHERE (`table_schema` = `old_name`);
  DECLARE CONTINUE HANDLER FOR NOT FOUND SET `done` = 1;

  SET @sql_string = CONCAT('CREATE DATABASE IF NOT EXISTS `', `new_name` , '`;');
  PREPARE `statement` FROM @sql_string;
  EXECUTE `statement`;
  DEALLOCATE PREPARE `statement`;

  OPEN `table_name_cursor`;
  REPEAT
    FETCH `table_name_cursor` INTO `current_table_name`;
    IF NOT `done` THEN

      SET @sql_string = CONCAT('RENAME TABLE `', `old_name`, '`.`', `current_table_name`, '` TO `', `new_name`, '`.`', `current_table_name`, '`;');
      PREPARE `statement` FROM @sql_string;
      EXECUTE `statement`;
      DEALLOCATE PREPARE `statement`;

    END IF;
  UNTIL `done` END REPEAT;
  CLOSE `table_name_cursor`;

  SET @sql_string =  CONCAT('DROP DATABASE `', `old_name`, '`;');
  PREPARE `statement` FROM @sql_string;
  EXECUTE `statement`;
  DEALLOCATE PREPARE `statement`;
END//
DELIMITER ;

希望它能帮助到像我这样处境的人!注意:@sql_string之后将在会话中逗留。不使用它,我就无法写出这个函数。