如何快速重命名MySQL数据库(更改架构名称)?


959

在MySQL手册的MySQL涵盖这一点。

通常,我只是转储数据库,然后使用新名称重新导入它。对于大型数据库,这不是一个选择。显然RENAME {DATABASE | SCHEMA} db_name TO new_db_name; 做不好的事情,仅存在于少数几个版本中,并且总体而言是个坏主意

这需要与InnoDB一起使用,后者存储的内容与MyISAM完全不同。



5
该语句RENAME DATABASE语法是在MySQL 5.1.7中添加的,但是发现它很危险,并在MySQL 5.1.23中被删除。
zloctb

11
希望MySQL将实现一个RENAME DATABASE没有任何危险的新的工作语句,因为目前尚无简便的方法来执行此任务。没有明显的理由说明文档中存在这种危险,因此他们应该可以进行替换。至少有人在其网站上发布了功能请求错误。例如,bugs.mysql.com / bug.php ? id=58593bugs.mysql.com/bug.php?id=1698
爱德华

链接现在已断开...
oldboy

Answers:


833

对于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

要么

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


26
我刚刚使用file_per_table设置对具有30多个表的InnoDB数据库进行了此操作,即使某些表超过3百万行,它也可以在不到1秒的时间内完成。它似乎只是在移动存储中的文件,而不是执行任何更复杂的操作……如果可能的话,+2 :)
Dave Rix

87
“发现重命名数据库很危险,并在MySQL 5.1.23中被删除” -from dev.mysql.com/doc/refman/5.1/en/rename-database.html
Palani 2012年

13
请注意,这不适用于视图。您不能重命名视图以使它们从数据库跳转到另一个数据库。使用DROP VIEWCREATE VIEW代替。笨拙的,是的。mysqldump在首先移动所有表之后,您可能想要执行移动视图的操作。另请注意,SHOW TABLES它将显示表和视图,因此请注意。
tuomassalo 2013年

9
同样,这不适用于任何带有触发器的表。您需要先查找,转储和删除触发器,然后再移动表,然后将转储的触发器导入目标数据库。
奥尔凡,2015年

5
更新(即正在工作)的链接记录了为何RENAME DATABASE被删除的原因:dev.mysql.com/worklog/task/?id=4030
Alexis,2016年

443

使用以下几个简单命令:

mysqldump -u username -p -v olddatabase > olddbdump.sql
mysqladmin -u username -p create newdatabase
mysql -u username -p newdatabase < olddbdump.sql

或为了减少I / O,请使用@Pablo Marin-Garcia建议的以下内容:

mysqladmin -u username -p create newdatabase
mysqldump -u username -v olddatabase -p | mysql -u username -p -D newdatabase

86
正如OP所说,“对于大型数据库,这不是一个选择。”
pilcrow,2010年

3
不要忘记删除原始数据库
Pavel Radzivilovsky 2010年

3
辉煌的答案!可能会被所有能力用Google搜索的一些进一步改进的建议:(1)将Pablo Marin-Garcia的代码片段移到顶部,因为这似乎是最好的答案(2)放置-p<password>-p所有位置而不是所有位置,因此语句运行时没有出现提示。
史蒂夫·钱伯斯

9
使用管道版本,我得到两个“输入密码:”提示,如下所示: Enter password: Enter password: 似乎只使用一个密码,但不能同时使用两个密码。我是否缺少细节?
瑞安

33
令我惊讶的是,没有人提到这一点,但是您确实也应该将该--routines标志添加到mysqldump命令中,以确保存储过程被复制。
卡洛斯P

205

我认为该解决方案更简单,并且是一些开发人员建议的。phpMyAdmin对此有一个操作。

从phpMyAdmin中,选择要选择的数据库。在选项卡中,有一个称为“操作”的选项,转到“重命名”部分。就这样。

正如许多人建议的那样,它确实使用新名称创建了一个新数据库,将旧数据库的所有表转储到新数据库中并删除了旧数据库。

在此处输入图片说明


76
假设您的环境中甚至有php或使用phpmyadmin。
克里斯(Chris)

26
即使您确实拥有phpMyAdmin,也非常危险-后端可能会在中间过程中失败,从而使两个数据库处于未知状态,或者可能花费很长时间,从而导致前端挂起或PHP超时。
mozboz 2012年

20
没错,@ mozboz确实如此,但是我已经做了10年了,从未遇到过这个问题。如果通过外壳运行命令而计算机崩溃,则该命令也是一样。有可能,但是呢?1对1万亿?
raphie 2012年

24
通过控制台编写的脚本也是可以挂起同样问题的前端。
格雷格2012年

11
但是,控制台操作比PhpMyAdmin更可靠,尤其是在涉及大型数据库的情况下(OP就是这种情况)。如果您有相当大的数据库,我个人强烈建议使用任何控制台方法而不是PMA。不用说,在小型数据库上,PMA也是一样。
Teodor Sandu

107

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

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

您可以使用以下两个脚本之一(我最初建议使用前一个脚本,有人会“改进”我的答案GROUP_CONCAT。请选择,但我更喜欢原始脚本):

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

要么

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;(或其他一些较大的数字)来更改该限制。


@BlakeFrederick它不使用RENAME DATABASE,这是什么问题?
tuxayo

如果表具有引用约束,这行得通吗?我希望不会。
支石墓

42

RENAME DATABASE在MySQL中模拟缺少的命令:

  1. 创建一个新的数据库
  2. 使用以下命令创建重命名查询:

    SELECT CONCAT('RENAME TABLE ',table_schema,'.',table_name,
        ' TO ','new_schema.',table_name,';')
    FROM information_schema.TABLES
    WHERE table_schema LIKE 'old_schema';
  3. 运行该输出

  4. 删除旧数据库

它来自于MySQL中的“模拟缺少的RENAME DATABASE”命令


1
完善!我用InnoDB和MyISAM表对此进行了测试。我测试过的最快的解决方案(对表重新命名几乎是即时的,没有延迟)!
菲利普

大!请记住,之后要修复特权。
亚当·法里纳

ps。如果正在使用实时数据库,则最好在运行重命名查询之前执行此操作。
亚当·法里纳

如果表具有引用约束,这行得通吗?我希望不会。
支石墓

24

三种选择:

  1. 创建新数据库,关闭服务器,将文件从一个数据库文件夹移动到另一个数据库文件夹,然后重新启动服务器。请注意,这仅在所有表均为MyISAM的情况下才有效。

  2. 创建新数据库,使用CREATE TABLE ... LIKE语句,然后使用INSERT ... SELECT * FROM语句。

  3. 使用mysqldump并重新加载该文件。


+供myisam参考。我不知道为什么这对我没有用。
克里斯蒂安·佩恩

5
问题指出,这必须适用于InnoDB,而不适用于MyISAM
D-Rock

@ D-Rock告诉Google,后者根据标题将人们带到这里。
jiggunjer

24

简单的方法

转到数据库目录:

cd /var/lib/mysql/

关闭MySQL ...这很重要!

/etc/init.d/mysql stop

好的,这种方法不适用于InnoDB或BDB数据库。

重命名数据库:

mv old-name new-name

或桌子

cd database/

mv old-name.frm new-name.frm

mv old-name.MYD new-name.MYD

mv old-name.MYI new-name.MYI

重启MySQL

/etc/init.d/mysql start

完成...

好的,这种方式不适用于InnoDB或BDB数据库。在这种情况下,您必须转储数据库并重新导入它。


16
重命名文件夹会破坏玩具。
ViniciusPires 2013年

1
@Rahly,即使设置了每个表一个文件,这仍然很危险,否则在设置每个表一个文件之前创建的表会遇到麻烦,除非您确定要在设置该标志后创建数据库。
钱陈

虽然总的来说,大多数人会以一种或另一种方式来拥有系统,但是人们不会在每个文件中是否有一个表的问题上随意翻动。此外,即使在您的情况下,如果表是在标记之前创建的,它们也不会首先作为单独的文件存在,因此此举将行不通,并且仍然安全,无危险。请记住,移动发生时数据库未运行。
拉希(Rahly)2015年

与在OS X上通过自制软件安装的mysql等效:launchctl unload -w ~/Library/LaunchAgents/homebrew.mxcl.mysql.plist cd /usr/local/var/mysql mv old-name new-name launchctl load -w ~/Library/LaunchAgents/homebrew.mxcl.mysql.plist
coberlin

22

您可以使用以下shell脚本:

参考:如何重命名MySQL数据库?

#!/bin/bash
set -e # terminate execution on command failure

mysqlconn="mysql -u root -proot"
olddb=$1
newdb=$2
$mysqlconn -e "CREATE DATABASE $newdb"
params=$($mysqlconn -N -e "SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES \
                           WHERE table_schema='$olddb'")
for name in $params; do
      $mysqlconn -e "RENAME TABLE $olddb.$name to $newdb.$name";
done;
$mysqlconn -e "DROP DATABASE $olddb"

工作正常:

$ sh rename_database.sh oldname newname

6
小心点。如果您不是使用root用户登录,则您的权限可能有限。导致重命名失败,但导致重命名失败,导致数据库丢失。不错的脚本,否则。
Lex

3
set -e在脚本的开头添加了代码,这将导致执行在失败时终止,并应减轻该问题。
Mikkel'4

19

我最近才遇到一种非常好的方法,可以与MyISAM和InnoDB一起使用,并且速度非常快:

RENAME TABLE old_db.table TO new_db.table;

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


@ArkadijKuzhel不这么认为。我认为您是在谈论RENAME DATABASE。
罗布·格兰特

这确实有帮助,我创建了一个新的空白数据库,然后使用代码,所有表均以所需的名称导入。
七月普通

3
这存在与接受的答案相同的问题-“发现重命名数据库很危险,并在MySQL 5.1.23中被删除”-来自dev.mysql.com/doc/refman/5.1/en/rename-database.html
布莱克·弗雷德里克(Blake Frederick)

16

进行完整重命名的最简单的防弹方法(包括最后删除旧数据库,因此它是重命名而不是副本)

mysqladmin -uroot -pmypassword create newdbname
mysqldump -uroot -pmypassword --routines olddbname | mysql -uroot -pmypassword newdbname
mysqladmin -uroot -pmypassword drop olddbname

脚步:

  1. 将这些行复制到记事本中。
  2. 用等效项替换对“ olddbname”,“ newdbname”,“ mypassword”(+可选为“ root”)的所有引用。
  3. 在命令行上一一执行(提示时输入“ y”)。

避免将密码添加到控制台,因为它不安全。如果您已完成此操作,请使用history -cw删除。而是将密码留空,然后在提示后输入密码。
Tommie C.

它花费了异常长的时间,超过20分钟而没有完成。可以取消吗?
古·玛格瓦(Sigu Magwa)'18

15

这是我用的:

$ mysqldump -u root -p olddb >~/olddb.sql
$ mysql -u root -p
mysql> create database newdb;
mysql> use newdb
mysql> source ~/olddb.sql
mysql> drop database olddb;

14
不适用于大型数据库。
mikesl 2011年

14

MySQL目前不支持通过其命令界面重命名数据库,但是如果您有权访问MySQL存储数据库的目录,则可以重命名数据库。对于默认的MySQL安装,通常位于MySQL安装目录下的Data目录中。在“数据”目录下找到要重命名的数据库的名称,然后重命名。重命名目录可能会导致一些权限问题。意识到。

注意:必须先停止MySQL,然后才能重命名数据库

我建议创建一个新的数据库(使用您想要的名称)并将所需的数据从旧数据导入/导出到新数据。很简单


13

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


4
请注意,当您单击数据库时,此功能在“操作”选项卡下有点隐藏。
Maris B.

13

那么有两种方法:

方法1:一种重命名数据库架构的著名方法是通过使用Mysqldump转储该架构并将其还原到另一个架构中,然后删除旧的架构(如果需要)。

从壳牌

 mysqldump emp > emp.out
 mysql -e "CREATE DATABASE employees;"
 mysql employees < emp.out 
 mysql -e "DROP DATABASE emp;"

尽管上述方法很容易,但是却浪费时间和空间。如果架构超过100GB怎么办?您可以通过多种方法将上述命令组合在一起以节省空间,但是这不会节省时间。

为了解决这种情况,还有另一种重命名模式的快速方法,但是在执行此操作时必须小心。

方法2: MySQL具有重命名表的很好的功能,甚至可以跨不同的模式工作。这种重命名操作是原子的,并且在重命名表时没有其他人可以访问该表。这需要很短的时间才能完成,因为更改表的名称或其模式仅是元数据更改。这是进行重命名的程序方法:

使用所需的名称创建新的数据库架构。使用MySQL的“ RENAME TABLE”命令将表从旧模式重命名为新模式。删除旧的数据库架构。 If there are views, triggers, functions, stored procedures in the schema, those will need to be recreated too。如果表上存在触发器,MySQL的“ RENAME TABLE”将失败。为了解决这个问题,我们可以做以下事情:

1) Dump the triggers, events and stored routines in a separate file.这是通过-E,-R标志(除了-t -d来转储触发器的标志来完成的,它用于mysqldump命令。转储触发器后,我们需要将其从架构中删除,以使RENAME TABLE命令起作用。

 $ mysqldump <old_schema_name> -d -t -R -E > stored_routines_triggers_events.out

2)生成仅“ BASE”表的列表。这些可以通过查询information_schema.TABLES表找到。

 mysql> select TABLE_NAME from information_schema.tables where 
    table_schema='<old_schema_name>' and TABLE_TYPE='BASE TABLE';

3)将视图转储到out文件中。可以使用同一information_schema.TABLES表上的查询找到视图。

mysql> select TABLE_NAME from information_schema.tables where 
   table_schema='<old_schema_name>' and TABLE_TYPE='VIEW';
 $ mysqldump <database> <view1> <view2>  > views.out

4)将触发器放在old_schema中的当前表上。

mysql> DROP TRIGGER <trigger_name>;
...

5)重命名在步骤2中找到的所有“基本”表后,恢复上述转储文件。

mysql> RENAME TABLE <old_schema>.table_name TO <new_schema>.table_name;
...
$ mysql <new_schema> < views.out
$ mysql <new_schema> < stored_routines_triggers_events.out

上述方法的复杂性:我们可能需要为用户更新GRANTS,以使其与正确的schema_name匹配。这些问题可以通过对mysql.columns_priv,mysql.procs_priv,mysql.tables_priv,mysql.db表进行简单更新来解决,将old_schema名称更新为new_schema并调用“刷新特权”。尽管“方法2”似乎比“方法1”要复杂一些,但这完全可以编写脚本。一个简单的bash脚本按适当的顺序执行上述步骤,可以帮助您节省空间和时间,同时下次重命名数据库架构。

Percona远程DBA团队已经编写了一个名为“ rename_db”的脚本,该脚本的工作方式如下:

[root@dba~]# /tmp/rename_db
rename_db <server> <database> <new_database>

为了演示此脚本的使用,使用了示例模式“ emp”,创建了测试触发器以及在该模式上存储了例程。将尝试使用脚本重命名数据库架构,这需要花费几秒钟来完成,而不是耗时的转储/还原方法。

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| emp                |
| mysql              |
| performance_schema |
| test               |
+--------------------+


[root@dba ~]# time /tmp/rename_db localhost emp emp_test
create database emp_test DEFAULT CHARACTER SET latin1
drop trigger salary_trigger
rename table emp.__emp_new to emp_test.__emp_new
rename table emp._emp_new to emp_test._emp_new
rename table emp.departments to emp_test.departments
rename table emp.dept to emp_test.dept
rename table emp.dept_emp to emp_test.dept_emp
rename table emp.dept_manager to emp_test.dept_manager
rename table emp.emp to emp_test.emp
rename table emp.employees to emp_test.employees
rename table emp.salaries_temp to emp_test.salaries_temp
rename table emp.titles to emp_test.titles
loading views
loading triggers, routines and events
Dropping database emp

real    0m0.643s
user    0m0.053s
sys     0m0.131s


mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| emp_test           |
| mysql              |
| performance_schema |
| test               |
+--------------------+

正如您在上面的输出中看到的那样,数据库模式“ emp”在不到一秒钟的时间内被重命名为“ emp_test”。最后,这是Percona的脚本,上面用于“方法2”。

#!/bin/bash
# Copyright 2013 Percona LLC and/or its affiliates
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 "show create database $2\G" -sss | grep ^Create | awk -F'CHARACTER SET ' '{print $2}' | awk '{print $1}'`
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

参照约束呢?
支石墓

13

脚步 :

  1. 击中 http:// localhost / phpmyadmin /
  2. 选择您的数据库
  3. 单击操作选项卡
  4. 将有一个标签“重命名数据库为”。添加新名称并检查调整权限。
  5. 单击转到。

在此处输入图片说明


1
phpMyAdmin解决方案通常是一个较差的解决方案,因为某些环境具有受限的环境。
Daniel Antunes Pinto

这不是一个“好的”解决方案,但还是要感谢,因为这正是我一直在寻找的东西。
杰米

1
如果它对您有用,请投票..它将有所帮助..谢谢
Shubham Jain19年

1
这对我有效,在phpMyAdmin环境中,+ 1
William

12

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


5
如果数据库中有任何视图或触发器,请提防此选项。该菜单选项后面是一个脚本,它将创建一个新数据库并将所有表移到上方。这不适用于视图或触发器,因此它们将留在旧数据库中。结果是需要修复两个损坏的数据库。
奥凡(Olfan)2015年

10

由于以下两个原因之一,此处的大多数答案都是错误的:

  1. 您不能只使用RENAME TABLE,因为可能会有视图和触发器。如果存在触发器,则RENAME TABLE失败
  2. 如果要“快速”(按问题要求)重命名大数据库,则不能使用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


我喜欢这个脚本,它几乎是通用的。但是,当定义器不是根目录的多个链状VIEW时,它无法处理这种情况。
ENargit '17

9

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

如果存在则删除程序mysql.rename_db;
分隔符||
创建过程mysql.rename_db(IN old_db VARCHAR(100),IN new_db VARCHAR(100))
开始
SELECT CONCAT('CREATE DATABASE',new_db,';')`#创建新数据库`;
选择CONCAT('RENAME TABLE`',old_db,'`.`',table_name,'`TO`',new_db,'`.`',table_name,'`;')`#alter table` FROM information_schema.tables table_schema = old_db;
SELECT CONCAT('DROP DATABASE`',old_db,'`;')`#删除旧数据库`;
结束||
定界符;

$ time mysql -uroot -e“调用mysql.rename_db('db1','db2');” | mysql -uroot

但是,目标数据库中的任何触发器都不满意。您需要先删除它们,然后在重命名后重新创建它们。

mysql -uroot -e“调用mysql.rename_db('test','blah2');” | mysql -uroot
第4行的错误1435(HY000):在错误的架构中触发

小调整,使它可以在mysql 5.x上工作。 mysql --batch-uroot -e "call mysql.rename_db('test', 'blah2');" | mysql -uroot 注意,您必须使用--batch将格式更改为原始格式,以输出带有零格式的结果。
mikesl 2011年

8

这是我编写的用于从命令行自动执行的批处理文件,但它适用于Windows / MS-DOS。

语法为rename_mysqldb数据库newdatabase -u [user] -p [password]

:: ***************************************************************************
:: FILE: RENAME_MYSQLDB.BAT
:: ***************************************************************************
:: DESCRIPTION
:: This is a Windows /MS-DOS batch file that automates renaming a MySQL database 
:: by using MySQLDump, MySQLAdmin, and MySQL to perform the required tasks.
:: The MySQL\bin folder needs to be in your environment path or the working directory.
::
:: WARNING: The script will delete the original database, but only if it successfully
:: created the new copy. However, read the disclaimer below before using.
::
:: DISCLAIMER
:: This script is provided without any express or implied warranties whatsoever.
:: The user must assume the risk of using the script.
::
:: You are free to use, modify, and distribute this script without exception.
:: ***************************************************************************

:INITIALIZE
@ECHO OFF
IF [%2]==[] GOTO HELP
IF [%3]==[] (SET RDB_ARGS=--user=root) ELSE (SET RDB_ARGS=%3 %4 %5 %6 %7 %8 %9)
SET RDB_OLDDB=%1
SET RDB_NEWDB=%2
SET RDB_DUMPFILE=%RDB_OLDDB%_dump.sql
GOTO START

:START
SET RDB_STEP=1
ECHO Dumping "%RDB_OLDDB%"...
mysqldump %RDB_ARGS% %RDB_OLDDB% > %RDB_DUMPFILE%
IF %ERRORLEVEL% NEQ 0 GOTO ERROR_ABORT
SET RDB_STEP=2
ECHO Creating database "%RDB_NEWDB%"...
mysqladmin %RDB_ARGS% create %RDB_NEWDB%
IF %ERRORLEVEL% NEQ 0 GOTO ERROR_ABORT
SET RDB_STEP=3
ECHO Loading dump into "%RDB_NEWDB%"...
mysql %RDB_ARGS% %RDB_NEWDB% < %RDB_DUMPFILE%
IF %ERRORLEVEL% NEQ 0 GOTO ERROR_ABORT
SET RDB_STEP=4
ECHO Dropping database "%RDB_OLDDB%"...
mysqladmin %RDB_ARGS% drop %RDB_OLDDB% --force
IF %ERRORLEVEL% NEQ 0 GOTO ERROR_ABORT
SET RDB_STEP=5
ECHO Deleting dump...
DEL %RDB_DUMPFILE%
IF %ERRORLEVEL% NEQ 0 GOTO ERROR_ABORT
ECHO Renamed database "%RDB_OLDDB%" to "%RDB_NEWDB%".
GOTO END

:ERROR_ABORT
IF %RDB_STEP% GEQ 3 mysqladmin %RDB_ARGS% drop %NEWDB% --force
IF %RDB_STEP% GEQ 1 IF EXIST %RDB_DUMPFILE% DEL %RDB_DUMPFILE%
ECHO Unable to rename database "%RDB_OLDDB%" to "%RDB_NEWDB%".
GOTO END

:HELP
ECHO Renames a MySQL database.
ECHO Usage: %0 database new_database [OPTIONS]
ECHO Options: Any valid options shared by MySQL, MySQLAdmin and MySQLDump.
ECHO          --user=root is used if no options are specified.
GOTO END    

:END
SET RDB_OLDDB=
SET RDB_NEWDB=
SET RDB_ARGS=
SET RDB_DUMP=
SET RDB_STEP=

7

TodoInTX的存储过程对我而言不太有效。这是我的目的:

-存储过程rename_db:使用表复制的方式重命名数据库。
-注意事项: 
-将破坏与“新”数据库名称相同名称的任何现有数据库。
-仅复制表格; 存储过程和其他数据库对象不会被复制。
-Tomer Altman(taltman@ai.sri.com)

分隔符//
如果存在则删除程序
创建过程rename_db(IN old_db VARCHAR(100),IN new_db VARCHAR(100))
开始
    声明current_table VARCHAR(100);
    声明完成INT默认值0;
    声明old_tables游标,用于从information_schema.tables中选择table_name,其中table_schema = old_db;
    未找到的DECLARE继续处理程序已完成= 1;

    SET @output = CONCAT('如果存在则删除模式',new_db,';'); 
    从@output准备stmt;
    执行stmt;

    SET @output = CONCAT('如果不存在则创建模式'​​,new_db,';');
    从@output准备stmt;
    执行stmt;

    OPEN old_tables;
    重复
        FETCH old_tables INTO current_table;
        如果未完成,那么
        SET @output = CONCAT('alter table',old_db,'。',current_table,'rename',new_db,'。',current_table,';');
        从@output准备stmt;
        执行stmt;

        万一;
    直到完成END REPEAT;

    CLOSE old_tables;

结束//
定界符;

这仅对表有效,并且仅在这些表没有任何触发器的情况下才有效。视图和触发器不会由此移动。
奥尔凡,2015年

7

最简单的方法是使用HeidiSQL软件。它是免费和开源的。它可以在Windows和任何带Wine的 Linux上运行(在Linux,BSD,Solaris和Mac OS X上运行Windows应用程序)。

要下载HeidiSQL,请访问http://www.heidisql.com/download.php

要下载Wine,请访问http://www.winehq.org/

要在HeidiSQL中重命名数据库,只需右键单击数据库名称,然后选择“编辑”。然后输入一个新名称,然后按“确定”。

很简单。


1
如果具有存储过程,则无法重命名。
abksharma

@abksharma实际上,您会收到消息Database "database_name" contains stored routine(s) which cannot be moved.触发器(至少对于MariDB数据库而言)被视为存储例程。我没有任何存储过程,但是在删除所有触发器之前,无法重命名数据库。
izogfif

7

对于Mac用户,您可以使用Sequel Pro(免费),它仅提供重命名数据库的选项。虽然它不会删除旧的数据库。

一旦打开相关的数据库,只需单击:Database->Rename database...


它有时会使旧的DB保持活动状态,但它是空的。不过,如果要制作副本,则可以制作副本并删除旧的副本,这仍然是2个简单步骤。
罗伊·加维雷尔

6

对服务器故障提出了一个问题,该问题是在使用MySQL代理还原非常大的数据库时试图解决停机问题。我没有取得任何成功,但最终我意识到我想要的是RENAME DATABASE功能,因为由于数据库的大小,转储/导入不是一个选择。

MySQL内置了RENAME TABLE功能,因此我最终编写了一个简单的Python脚本来为我完成这项工作。我已将其发布在GitHub上,以防其他人使用。



2
从语法而不是重命名表中删除了重命名数据库。
2012年

6

为了方便起见,下面是一个小的shellscript,必须使用两个参数来执行: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"

1
对于附加了触发器的表或无法重命名为其他数据库的视图,这也将不起作用。
奥尔凡,2015年

6

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

create database NewDatabaseName like OldDatabaseName;

然后为每个表执行以下操作:

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

然后,如果您愿意,

drop database OldDatabaseName;

这种方法的优势是可以在网络流量几乎为零的情况下在服务器上进行整个传输,因此比转储/还原要快得多。

如果您确实有存储过程/视图/等,则可能也要转移它们。


2
据我所知5.x在create database语句中不支持“ like”关键字?你从哪里得到的?
德拉加斯

这是create table like语法的链接:dev.mysql.com/doc/refman/5.7/en/create-table-like.html。至于创建数据库,似乎MySQL从此删除了该子句。
TuncayGöncüoğlu

4

如果要移动许多表,这是一种生成重命名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' ;

看起来不错,但这不会移动存储过程或视图。
davidpriceev 2015年

您可能应该添加哈希标记来包装表名和模式名
Funkodebat 2015年

4

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

13.1.32重命名数据库语法

RENAME {DATABASE | SCHEMA} db_name TO new_db_name;

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


6
您有示例语法吗?我不知道有什么方法可以alter database用来重命名数据库本身,并且链接到的文档并不暗示可以重命名。
约旦

@乔丹我也很感兴趣。我尝试并尝试后发现,它仅适用于5.1版以上,但目前无法更新。
fancyPants 2012年

5
-1:在编写建议的方法时,然后给出一个非建议的方法的示例,而该示例却完全丢失甚至无法显示示例。
hakre 2014年

3
错了 MySQL重命名数据库文档说,rename_database用于特定的重命名任务(不是数据库重命名的一般情况),现在可以通过alter database处理:'要执行使用新编码升级数据库名称的任务,请使用ALTER DATABASE db_name UPGRADE而是使用“ DATA DIRECTORY NAME”(数据目录名)来代替,您不能使用它来重命名数据库,在此命令中甚至没有任何新数据库名的位置!
卡纳特

3

在MySQL Administrator中,请执行以下操作:

  1. 在目录下,创建一个新的数据库架构。
  2. 转到备份并创建旧模式的备份。
  3. 执行备份。
  4. 转到“还原”并打开在步骤3中创建的文件。
  5. 在“目标模式”下选择“另一个模式”,然后选择新的数据库模式。
  6. 开始还原。
  7. 验证新架构,如果看起来不错,则删除旧架构。

MySQL Administrator无法处理大型数据库,而且处理起来并不快
deadprogrammer

3

phpmyadmin中,您可以轻松地重命名数据库

select database 

  goto operations tab

  in that rename Database to :

  type your new database name and click go

要求删除旧表并重新加载表数据,在两者中均单击“确定”。

您的数据库已重命名


3

如果您使用的是phpMyAdmin,则一旦选择了要重命名的数据库,就可以转到“操作”选项卡。然后转到最后一部分“将数据库复制到”(或类似名称),输入名称,然后选择以下选项。在这种情况下,我想您必须选择“结构和数据”和“在复制之前创建数据库”复选框,最后,按该部分中的“执行”按钮。

顺便说一句,我正在使用西班牙语的phpMyAdmin,所以我不确定这些部分的名称是英文。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.