重命名 MySQL 数据库 [重复]

Posted

技术标签:

【中文标题】重命名 MySQL 数据库 [重复]【英文标题】:Rename MySQL database [duplicate] 【发布时间】:2012-08-24 18:36:48 【问题描述】:

我创建了一个名为hrms 的数据库。现在我需要将数据库名称更改为sunhrm。但是,它在 mysql 工作台中被禁用。我可以在 Linux 服务器本身上执行此操作吗?

【问题讨论】:

你用的是哪个mysql版本? @Joachim Isaksson 我正在使用 mysql 5.5 服务器故障:serverfault.com/questions/195221/how-to-rename-a-mysql-database 希望 MySQL 将实现一个新的、有效的 RENAME DATABASE 语句,它没有任何危险,因为目前没有简单的方法来完成这项任务。 在documentation 中没有明显的危险原因,因此他们应该能够进行替换。 至少人们已经在他们的网站上放置了功能请求错误。例如,bugs.mysql.com/bug.php?id=58593 和 bugs.mysql.com/bug.php?id=1698。 【参考方案1】:

简而言之,没有。通常认为重命名数据库太危险了。 MySQL 曾经有过这个特性,但它被删除了。您最好使用工作台将架构和数据都导出到 SQL,然后在运行/导入之前更改 CREATE DATABASE 名称。

【讨论】:

【参考方案2】:

我认为你做不到。基本答案在许多情况下都有效,而在其他情况下会导致数据损坏。需要根据对数据库的启发式分析来选择策略。 这就是实现此功能的原因,and then removed。 [doc]

您需要转储该数据库中的所有对象类型,创建新命名的对象类型,然后导入转储。如果这是一个实时系统,您需要将其删除。如果不能,则需要设置从该数据库到新数据库的复制。

如果您想查看可以执行此操作的命令,@satishD has the details,它传达了您需要围绕这些挑战构建与目标数据库匹配的策略。 p>

【讨论】:

有意义吗?为什么 MySQL 开发者省略了这么重要的选项? 这可能是营销的一个原因。许多 MySQL 托管服务提供商为您提供免费但随机且平庸的命名数据库名称,但如果您希望将其重命名为简单易读的名称,那么您几乎必须为此付费。【参考方案3】:

创建新模式“other_db”后,您可以通过 RENAME 语句为“current_db”中的每个表执行此操作

RENAME TABLE current_db.tbl_name TO other_db.tbl_name

来源Rename Table Syntax

【讨论】:

"这个语句是在 MySQL 5.1.7 中添加的,但是发现有危险,在 MySQL 5.1.23 中被删除了"dev.mysql.com/doc/refman/5.1/en/rename-database.html 嗨 mikeslattery,我的声明是重命名表而不是重命名数据库或架构 噗,哎呀。对不起。 :)【参考方案4】:

如果您需要从命令行执行此操作,只需复制、调整和粘贴此 sn-p:

mysql -e "CREATE DATABASE \`new_database\`;"
for table in `mysql -B -N -e "SHOW TABLES;" old_database`
do 
  mysql -e "RENAME TABLE \`old_database\`.\`$table\` to \`new_database\`.\`$table\`"
done
mysql -e "DROP DATABASE \`old_database\`;"

【讨论】:

请注意,这只处理表格。视图和存储过程必须分开完成。 这个脚本的更易于使用的版本:gist.github.com/tadas-s/5411299 这里是在 MySQL 中直接在 SQL 中创建重命名表命令的另一种方法:blog.marceloaltmann.com/how-to-rename-a-database-in-mysql gist.github.com/tadas-s/5411299 上的要点对我来说效果很好。但是,如果它可以处理视图并接受一些命令行参数,那就太好了。 先删除触发器(如果有的话)!!!【参考方案5】:

首先备份名为 HRMS 的旧数据库并编辑脚本文件,将单词 HRMS 替换为 SUNHRM。在这一步之后将数据库文件导入mysql

【讨论】:

【参考方案6】:

对于不耐烦的mysql用户(比如我),解决办法是:

/etc/init.d/mysql stop
mv /var/lib/mysql/old_database /var/lib/mysql/new_database 
/etc/init.d/mysql start

【讨论】:

我试过这个。我将my_project 移动到my_project_bak,然后创建了一个名为my_project 的新空白数据库。当新的空白数据库与my_project_bak 中的表同名时,我无法在它中创建表。 虽然这做起来非常简单快捷,而且似乎很有效,但它确实导致了一些不一致,可能是由于 innodb 你要替换系统表(db mysql)中的所有权限,这个是给数据库权限use mysql; update db set Db=newdbname where Db=olddbname 如果您有 InnoDB 表,请执行此操作。仅当您的所有表都是 MyISAM 表时才使用此方法。【参考方案7】:

您可以创建一个与先前数据库完全相同的新数据库,然后在完成后删除旧数据库。使用 mysqldump 工具通过 mysqldump orig_db > orig_db.sql 创建数据库的 .sql 备份,或者如果您需要使用用户名和密码,则运行 mysqldump -u root -p orig_db > orig_db.sql。 orig_db 是您要“重命名”的数据库的名称,root 是您登录的用户,orig_db.sql 是创建的包含备份的文件。现在使用您想要的数据库名称创建一个新的空数据库。例如,mysql -u root -p -e "create database new_db"。完成后,运行mysql -u root -p new_db < orig_db.sql。 new_db 现在作为 orig_db 的完美副本存在。然后,您可以删除原始数据库,因为它现在已经存在于具有您想要的数据库名称的新数据库中。

没有上述所有解释的简短快速步骤是:

    mysqldump -u root -p original_database > original_database.sql mysql -u root -p -e "create database my_new_database" mysql -u root -p my_new_database < original_database.sql mysql -u root -p -e drop database originl_database

希望这会有所帮助,这是一种可靠的方法来完成它,而无需使用会破坏您的数据并造成不一致的特定方法。

【讨论】:

简洁、安全、最适合我(在没有触发器的简单数据库上) 只需创建数据库并将结果从一个直接传送到另一个:mysqldump -u root -p old_db|mysql -u root -p new_db 您可能需要编辑original_database.sql 文件并注释掉顶部的CREATE DATABASE …USE … 语句,以避免创建/使用原始数据库。【参考方案8】:

可以通过 mysqldump 命令复制数据库而不将转储存储到文件中:

    mysql -u root -p -e "create database my_new_database" mysqldump -u root -p original_database | mysql -u root -p my_new_database mysql -u root -p -e "drop database original_database"

【讨论】:

【参考方案9】:

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

    使用 mysqldump 或任何数据库工具(例如 heidiSQL、mysql 管理员等)备份文件

    在一些文本编辑器中打开备份(例如backupfile.sql)文件。

    搜索替换数据库名称并保存文件。

    恢复已编辑的 SQL 文件

【讨论】:

不要忘记创建要导入数据的新数据库。换句话说,就是“重命名”的数据库。【参考方案10】:

有两种方法:

方法 1:一种众所周知的重命名数据库模式的方法是使用 Mysqldump 转储模式并将其恢复到另一个模式中,然后删除旧模式(如果需要)。

来自Shell

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

上述方法虽然简单,但费时费空间。如果架构超过 100GB 怎么办?有一些方法可以将上述命令一起传递以节省空间,但不会节省时间。

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

方法 2:MySQL 有一个非常好的重命名表的特性,甚至可以跨不同的模式工作。此重命名操作是原子操作,并且在重命名表时没有其他人可以访问该表。这需要很短的时间才能完成,因为更改表的名称或其架构只是元数据更改。以下是重命名的程序方法:

    使用所需名称创建新的数据库架构。 将表从旧模式重命名为新模式,使用 MySQL 的 “重命名表”命令。 删除旧的数据库架构。

如果架构中有views, triggers, functions, stored procedures,则也需要重新创建它们。如果表上存在触发器,MySQL 的“重命名表”将失败。为了解决这个问题,我们可以做以下事情:

1) Dump the triggers, events and stored routines in a separate file. 这是使用 -E, -R 标志完成的(除了 -t -d 转储触发器)到 mysqldump 命令。一旦触发 转储,我们需要将它们从模式中删除,用于重命名表 命令工作。

  $ 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_privmysql.procs_privmysql.tables_priv、mysql.db 表上将old_schema name 更新为new_schema 并调用“刷新权限”来修复这些问题。 尽管“method 2”看起来比“method 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”。 最后,这是来自 Percona 的脚本,上面用于“method 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

【讨论】:

【参考方案11】:

另一种重命名数据库或获取数据库映像的方法是使用数据库选项卡中的逆向工程选项。它将为数据库创建一个 ERR 图。在那里重命名架构。

然后转到文件菜单并转到导出和正向工程数据库。

然后就可以导入数据库了。

【讨论】:

【参考方案12】:

如果您的数据库仅包含 MyISAM 表(如果您有 InnoDB 表,请不要使用此方法):

    关闭 MySQL 服务器 进入mysqldata目录,重命名数据库目录(注意:非字母字符需要特殊编码) 重启服务器 根据需要调整权限(授予对新数据库名称的访问权限)

您可以在一个命令中编写全部脚本,这样停机时间只需一两秒。

【讨论】:

以上是关于重命名 MySQL 数据库 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

如何在mysql中重命名数据库? [复制]

使用linux重命名mysql中的数据库[重复]

重命名 mysql 表中的列,而不必重复其类型定义

重命名mysql表中的列而不必重复其类型定义

如何在 MySQL 中重命名模式

如何在不删除或移动mysql中的表的情况下重命名数据库? [复制]