【问题标题】:How do I quickly rename a MySQL database (change schema name)?如何快速重命名 MySQL 数据库(更改架构名称)?
【发布时间】:2010-09-09 04:29:42
【问题描述】:

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

通常我只是转储数据库并用新名称重新导入它。对于非常大的数据库,这不是一个选项。显然是RENAME {DATABASE | SCHEMA} db_name TO new_db_name;does bad things, exist only in a handful of versions, and is a bad idea overall

这需要与InnoDB 一起使用,它存储的东西与MyISAM 非常不同。

【问题讨论】:

标签: mysql database innodb rename


【解决方案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

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

【讨论】:

  • 如果您的数据库很大但您没有那么多表(或者您愿意编写一个脚本来循环所有表),这是一个不错的选择和方法。除了在 innodb 中,它只是一个逻辑重命名,而在 MyISAM 中,取决于您的文件系统,它可能是一个逻辑重命名或磁盘上的真实复制数据。
  • 我刚刚使用 file_per_table 设置对具有 30 多个表的 InnoDB 数据库进行了此操作,即使某些表有 3+ 百万行,它也可以在
  • 请注意,这不适用于视图。您不能重命名视图以使它们从一个数据库跳转到另一个。请改用DROP VIEWCREATE VIEW。笨拙,是的。在首先移动所有表之后,您可能想要执行mysqldump 来移动视图。另请注意,SHOW TABLES 将显示表格和视图,所以要小心。
  • 这也不适用于任何带有触发器的表。您需要在移动表之前找到、转储和删除触发器,然后将转储的触发器导入目标数据库。
  • 更新(即工作)链接记录了为什么 RENAME DATABASE 被删除:dev.mysql.com/worklog/task/?id=4030
【解决方案2】:

使用这几个简单的命令:

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

或者按照@Pablo Marin-Garcia 的建议使用以下方法来减少 I/O:

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

【讨论】:

  • 正如 OP 所说,“[t]这不是非常大的数据库的选择。”
  • 别忘了删除原始数据库
  • 绝妙的答案!一些进一步改进的建议,因为这可能正在被所有能力所搜索:(1) 将 Pablo Marin-Garcia 的代码片段移到顶部,因为它似乎是最好的答案 (2) 将-p&lt;password&gt; 而不是-p 放在任何地方,所以语句运行时不出现提示。
  • 使用管道版本我得到两个“输入密码:”提示,如下所示:Enter password: Enter password: 似乎需要一个密码,但不是两个。我错过了一个细节吗?
  • 我很惊讶没有人提到这一点,但你真的应该在 mysqldump 命令中添加--routines 标志,以确保复制存储过程。
【解决方案3】:

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

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

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

【讨论】:

  • 假设您的环境中甚至有 php 或使用 phpmyadmin。
  • 即使你有 phpMyAdmin 也相当危险 - 后端可能会在进程中失败,使两个数据库处于未知状态,或者可能需要很长时间,导致前端挂起或PHP 超时。
  • 这是真的@mozboz,但我已经这样做了 10 年,从来没有遇到过这个问题。如果您通过外壳运行命令并且您的计算机崩溃,则相同。有可能,但什么? 1 到 1 万亿?
  • 通过控制台的脚本也是一个前端,可能会出现同样的问题。
  • 然而控制台操作比 PhpMyAdmin 可靠得多,尤其是在涉及大型数据库的情况下,这是 OP 的情况。如果你有一个相当大的数据库,我个人强烈建议使用任何控制台方法而不是 PMA。不用说,在小型数据库上 PMA 也同样出色。
【解决方案4】:

您可以使用 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 那么有什么问题?
  • 如果表有引用约束,这是否有效?我希望不会。
【解决方案5】:

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

  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. 删除旧数据库

取自Emulating The Missing RENAME DATABASE Command in MySQL

【讨论】:

  • 完美!我用 InnoDB 和 MyISAM 表对此进行了测试。我测试过的最快的解决方案(重命名表几乎是即时的,没有延迟)!
  • 太棒了!请记住事后修复权限。
  • ps。如果您正在使用实时数据库,最好在运行重命名查询之前执行此操作。
  • 如果表有引用约束,这是否有效?我希望不会。
【解决方案6】:

你可以使用这个 shell 脚本:

参考:How to rename a MySQL database?

#!/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

【讨论】:

  • 小心这个。如果您没有使用 root 用户登录,您的权限可能有限。导致重命名失败但删除成功导致数据库删除。否则很好的脚本。
  • 我在脚本的开头添加了set -e,这将导致执行在失败时终止,应该可以缓解这个问题。
  • 在中间的某个地方,我在第 1 行收到错误 ERROR 1435 (HY000): Trigger in wrong schema
  • @pymen 你能分享一下截图吗?
【解决方案7】:

三个选项:

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

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

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

【讨论】:

  • + 用于 myisam 参考。我不明白为什么这对我不起作用。
  • 问题指出这必须适用于 InnoDB,而不是 MyISAM
  • @D-Rock 告诉谷歌,谷歌会根据标题将人们带到这里。
【解决方案8】:

简单的方法

切换到数据库目录:

cd /var/lib/mysql/

关闭 MySQL...这很重要!

/etc/init.d/mysql stop

好的,这种方式不适用于 InnoDB 或 BDB-Databases。

重命名数据库:

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 数据库。在这种情况下,您必须转储数据库并重新导入。

【讨论】:

  • 重命名文件夹会破坏玩具。
  • @Rahly,即使设置了一个表一个文件,还是很危险的,在设置一个表一个文件之前创建的表会有问题,除非你确定数据库是在之后创建的该标志已设置。
  • 虽然一般来说,大多数人都会以一种方式或另一种方式来使用他们的系统,人们不会在每个文件是否有一张桌子上随机翻转。此外,即使在您的场景中,如果表是在标志之前创建的,它们首先不会作为单独的文件存在,因此移动不会起作用并且它仍然安全,没有危险。请记住,移动发生时数据库并未运行。
  • 在 OS X 上与 homebrew 一起安装的 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
  • 小心重命名文件夹名称,它可能包含引用旧文件夹的隐藏文件
【解决方案9】:

进行完整重命名的最简单的防弹方法(包括在末尾删除旧数据库,使其成为重命名而不是副本)

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 删除。而是将密码留空,并在提示后输入。
  • 异常耗时,20多分钟未完成。可以取消吗?
【解决方案10】:

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

RENAME TABLE old_db.table TO new_db.table;

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

【讨论】:

  • @ArkadijKuzel 不这么认为。我认为您在谈论重命名数据库。
  • 这真的很有帮助,我创建了一个新的空白数据库,然后使用代码,所有表都以所需的名称导入。
  • 这与接受的答案存在相同的问题——“重命名数据库被发现是危险的,并在 MySQL 5.1.23 中被删除”——来自 dev.mysql.com/doc/refman/5.1/ zh/rename-database.html
【解决方案11】:

步骤:

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

【讨论】:

  • 一个 phpMyAdmin 解决方案通常是一个糟糕的解决方案,因为某些环境有限制环境。
  • 不是一个“好”的解决方案,但非常感谢,因为它是我正在寻找的。​​span>
  • 如果它对你有用,请投赞成票..它会有所帮助..谢谢
  • 这对我有用,在 phpMyAdmin 环境中,+1
【解决方案12】:

这是我用的:

$ 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;

【讨论】:

  • 不适用于大型数据库。
【解决方案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 的“重命名表”将失败。为了解决这个问题,我们可以做以下事情:

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) 将视图转储到输出文件中。可以使用对同一个 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 Remote 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”。最后,这是上面用于“方法 2”的 Percona 脚本。

#!/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

【讨论】:

  • 引用约束呢?
【解决方案14】:

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

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

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

【讨论】:

    【解决方案15】:

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

    【讨论】:

    • 请注意,当您单击数据库时,此功能会在“操作”选项卡下隐藏。
    【解决方案16】:

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

    【讨论】:

    • 如果您的数据库中有任何视图或触发器,请注意此选项。此菜单选项后面是一个脚本,它将创建一个新数据库并移动所有表。这不适用于视图或触发器,因此它们将留在旧数据库中。结果是两个损坏的数据库需要修复。
    【解决方案17】:

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

    1. 您不能只使用 RENAME TABLE,因为可能存在视图和触发器。如果有触发器,RENAME TABLE 会失败
    2. 如果您想“快速”(按照问题中的要求)重命名大型数据库,则不能使用 mysqldump

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

    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 一样使用它

    【讨论】:

    • 我喜欢这个脚本,它几乎是通用的。但是,当定义者不是 root 的多个链式 VIEW 时,它无法处理一个案例。
    【解决方案18】:

    可以将一个数据库中的所有表重命名为另一个数据库下,而无需进行完全转储和恢复。

    删除过程如果存在 mysql.rename_db; 分隔符 || 创建过程 mysql.rename_db(在 old_db VARCHAR(100),在 new_db VARCHAR(100)) 开始 SELECT CONCAT('CREATE DATABASE', new_db, ';') `# 创建新数据库`; 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, '`;') `# 删除旧数据库`; 结束|| 分隔符; $ time mysql -uroot -e "调用 mysql.rename_db('db1', 'db2');" | mysql -uroot

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

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

    【讨论】:

    • 使用 mysql 5.x mysql --batch-uroot -e "call mysql.rename_db('test', 'blah2');" | mysql -uroot 进行这项工作的小调整注意,您必须使用 --batch 将格式更改为原始格式,从而输出带有零格式的结果。
    【解决方案19】:

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

    create database NewDatabaseName like OldDatabaseName;
    

    然后为每个表做:

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

    那么,如果你愿意,

    drop database OldDatabaseName;
    

    这种方法的优势是在服务器上进行整个传输,网络流量几乎为零,因此它比转储/恢复要快得多。

    如果您确实有存储过程/视图/等,您可能也希望传输它们。

    【讨论】:

    • 据我所知,5.x 不支持create database 语句中的“like”关键字?你从哪里得到的?
    • 这里是create table like 语法的链接:dev.mysql.com/doc/refman/5.7/en/create-table-like.html。至于创建数据库之类的,似乎 MySQL 从此放弃了该子句。
    【解决方案20】:

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

    打开相关数据库后,只需点击:Database --> Rename database...

    【讨论】:

    • 它有时会保留旧数据库,但它是空的。尽管如此,如果它复制,您可以复制并删除旧的,仍然是两个简单的步骤。
    • 我的stored proceduresviews 没有与重命名一起复制
    【解决方案21】:

    这是我编写的一个批处理文件,用于从命令行自动执行它,但它适用于 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=
    

    【讨论】:

      【解决方案22】:

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

      -- 存储过程rename_db:重命名数据库我的表复制方式。 -- 注意事项: -- 将破坏与“新”数据库名称同名的任何现有数据库。 -- 只复制表格;存储过程和其他数据库对象不会被复制。 -- 托默奥特曼 (taltman@ai.sri.com) 分隔符 // 如果存在则删除程序 rename_db; 创建过程 rename_db(在 old_db VARCHAR(100)中,在 new_db VARCHAR(100)中) 开始 声明 current_table VARCHAR(100); 声明完成 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, ';'); 从@output准备stmt; 执行语句; SET @output = CONCAT('CREATE SCHEMA IF NOT EXISTS', new_db, ';'); 从@output准备stmt; 执行语句; 打开旧表; 重复 FETCH old_tables INTO current_table; 如果没有完成 那么 SET @output = CONCAT('alter table', old_db, '.', current_table, 'rename', new_db, '.', current_table, ';'); 从@output准备stmt; 执行语句; 万一; 直到完成 END REPEAT; 关闭旧表; 结尾// 分隔符;

      【讨论】:

      • 这仅适用于表,并且仅当这些表没有任何触发器时。视图和触发器不会因此而移动。
      【解决方案23】:

      posed a question on Server Fault 试图在使用 MySQL 代理恢复非常大的数据库时避免停机。我没有成功,但我最终意识到我想要的是重命名数据库功能,因为由于我们数据库的大小,转储/导入不是一个选项。

      MySQL 内置了一个重命名表功能,因此我最终编写了一个简单的 Python 脚本来为我完成这项工作。我已经posted it on GitHub 以防它对其他人有用。

      【讨论】:

      【解决方案24】:

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

      【讨论】:

      • 这也不适用于带有触发器的表,或无法重命名为其他数据库的视图。
      【解决方案25】:

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

      要下载 HeidiSQL,请转到 http://www.heidisql.com/download.php

      要下载 Wine,请转到 http://www.winehq.org/

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

      就是这么简单。

      【讨论】:

      • 如果有存储过程则不能重命名。
      • @abksharma 实际上你会收到消息Database "database_name" contains stored routine(s) which cannot be moved. 触发器(至少对于 MariDB 数据库)被计为存储例程。我没有任何存储过程,但在删除所有触发器之前无法重命名数据库。
      【解决方案26】:

      在 MySQL Administrator 中执行以下操作:

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

      【讨论】:

      • MySQL 管理员无法处理大型数据库,而且没有什么快速的
      【解决方案27】:

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

      select database 
      
        goto operations tab
      
        in that rename Database to :
      
        type your new database name and click go
      

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

      您的数据库已重命名

      【讨论】:

        【解决方案28】:

        如果您有很多表要移动,这里是生成重命名 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' ;
        

        【讨论】:

        • 看起来不错,但这不会移动存储过程或视图。
        • 您可能应该添加哈希标记来环绕表名和模式名
        【解决方案29】:

        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 中被删除了。

        【讨论】:

        • 您有任何示例语法吗?我不知道有什么方法可以使用alter database 重命名数据库本身,并且您链接到的文档并不表明可以这样做。
        • @Jordan 我也会感兴趣。我试了又试,发现它只适用于 > 5.1 版本,但我现在无法更新。
        • -1:用于撰写建议的方式,然后给出非建议方式的示例,而完全没有显示示例。
        • 这是错误的。 MySQL rename database documentation 说 rename_database 用于非常具体的重命名任务(不是数据库重命名的一般情况),现在由 alter database 处理:'要使用新编码执行升级数据库名称的任务,请使用 ALTER DATABASE db_name UPGRADE DATA DIRECTORY NAME instead' 你不能用它来重命名数据库,在这个命令中甚至没有新的数据库名称的地方!
        【解决方案30】:

        如果您使用phpMyAdmin,您可以在选择要重命名的数据库后转到“操作”选项卡。然后转到最后一部分“将数据库复制到”(或类似的内容),命名,然后选择下面的选项。在这种情况下,我猜你必须选择“结构和数据”和“复制前创建数据库”复选框,最后按下该部分中的“开始”按钮。

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

        【讨论】:

          猜你喜欢
          • 2011-08-19
          • 2013-09-14
          • 1970-01-01
          • 2013-11-17
          • 2010-10-15
          • 2017-10-04
          • 1970-01-01
          • 2011-02-21
          • 1970-01-01
          相关资源
          最近更新 更多