如何重命名MySQL数据库(更改模式名称)?

1141

5
还有在Serverfault上的讨论:http://serverfault.com/questions/195221/how-to-rename-a-mysql-database - Yves Martin
46个回答

8
最简单的方法是使用HeidiSQL软件。它是免费且开源的。它可以在Windows上运行,并且可以在任何安装了Wine(在Linux、BSD、Solaris和Mac OS X上运行Windows应用程序)的Linux上运行。
要下载HeidiSQL,请访问http://www.heidisql.com/download.php
要下载Wine,请访问http://www.winehq.org/
要在HeidiSQL中重命名数据库,只需右键单击数据库名称,然后选择“编辑”。然后输入新名称并按“确定”。
这非常简单。

2
如果存储过程已经存在,它就不能被重命名。 - abksharma
@abksharma 实际上,您会收到消息“数据库“database_name”包含无法移动的存储例程。” 触发器(至少对于MariDB数据库)被视为存储例程。我没有任何存储过程,但在删除所有触发器之前,无法重命名数据库。 - izogfif

7

TodoInTX的存储过程对我来说不太适用。这是我的尝试:

-- 存储过程rename_db:通过表复制重命名数据库。
-- 注意事项:
-- 会覆盖任何与“新”数据库名称相同的现有数据库。
-- 仅复制表;不复制存储过程和其他数据库对象。
-- 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 ;

这仅适用于表格,并且仅适用于这些表格没有任何触发器的情况。视图和触发器将不会被移动。 - Olfan

6

尽管有许多尝试过的答案,但你不能这样做,这是有原因的。

  • 在许多情况下,基本答案可以解决问题,但在其他情况下会导致数据损坏。
  • 需要根据对数据库进行启发式分析后选择一种策略。
  • 这就是为什么这个功能被实现,然后又被删除的原因。 [文档]

你需要导出该数据库中的所有对象类型,创建新命名的数据库,然后导入导出文件。 如果这是一个在线系统,你需要先关闭它。如果你无法关闭,则需要将此数据库设置为新数据库的复制源。

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


5

如果你需要移动多个表格,这里有一个快速生成重命名 SQL 脚本的方法。

SELECT DISTINCT CONCAT('RENAME TABLE ', t.table_schema,'.', t.table_name, ' TO ',     
t.table_schema, "_archive", '.', t.table_name, ';' ) as Rename_SQL 
FROM information_schema.tables t
WHERE table_schema='your_db_name' ;

看起来不错,但这并没有移动存储过程或视图。 - davidpricedev
你可能需要添加哈希标记来包围表名和模式名。 - dansch

5

ALTER DATABASE 是 MySQL 提出的一种解决方法,以替代被取消的 RENAME DATABASE

13.1.32 RENAME DATABASE Syntax 中可以看到:

RENAME {DATABASE | SCHEMA} db_name TO new_db_name;

这个语句是在MySQL 5.1.7中添加的,但后来被发现很危险,并在MySQL 5.1.23中被移除。


7
你有任何示例语法吗?我不知道如何使用“alter database”来重命名数据库本身,而你引用的文档也没有表明这是可能的。 - Jordan
@Jordan 我也很感兴趣。我尝试了很多次,发现只有在版本大于5.1时才能正常工作,但我现在无法更新。 - fancyPants
6
在谈论建议的方式时,却给出了一种与建议无关的例子,同时完全忽略了展示相关例子的事实。 - hakre
4
这是错误的。MySQL重命名数据库文档称rename_database仅用于特定的重命名任务(而不是一般情况下的数据库重命名),现在使用alter database处理:'要执行升级数据库名称和新编码的任务,请使用ALTER DATABASE db_name UPGRADE DATA DIRECTORY NAME'您无法随心所欲地使用此命令来重命名数据库,甚至没有任何地方用于新数据库名称! - Kanat Bolazar

5
phpmyadmin 中,您可以轻松地重命名数据库。
select database 

  goto operations tab

  in that rename Database to :

  type your new database name and click go

要求删除旧表并重新加载表数据,请在两个选项中都点击“确定”

您的数据库已被重命名


4
我是这样做的: 备份您现有的数据库。这将给您一个db.zip.tmp文件,然后在命令提示符中输入以下内容:

"C:\Program Files (x86)\MySQL\MySQL Server 5.6\bin\mysql.exe" -h localhost -u root -p[密码] [新数据库名称] < "C:\Backups\db.zip.tmp"


4
在MySQL管理员中,按照以下步骤操作:
  1. 在目录下创建一个新的数据库模式。
  2. 进入备份并创建旧模式的备份。
  3. 执行备份操作。
  4. 进入还原并打开第三步创建的文件。
  5. 在目标模式下选择“另一个模式”,并选择新的数据库模式。
  6. 开始还原操作。
  7. 验证新的模式,如果看起来不错,则删除旧模式。

MySQL管理员无法处理大型数据库,而且这并不快速。 - deadprogrammer

4
这是一个一行的Bash代码片段,可以将一个模式中的所有表移动到另一个模式中:
history -d $((HISTCMD-1)) && mysql -udb_user -p'db_password' -Dold_schema -ABNnqre'SHOW TABLES;' | sed -e's/.*/RENAME TABLE old_schema.`&` TO new_schema.`&`;/' | mysql -udb_user -p'db_password' -Dnew_schema

在开始时,history命令只是确保包含密码的MySQL命令不会保存到shell历史记录中。

请确保db_user在旧模式上具有读/写/删除权限,在新模式上具有读/写/创建权限。


3

既然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将在会话中保留。如果不使用它,我将无法编写此函数。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接