如何快速重命名 MySQL 数据库(更改架构名称)?
题
MySQL 手册位于 MySQL 涵盖了这一点。
通常我只是转储数据库并使用新名称重新导入它。对于非常大的数据库来说,这不是一个选项。显然 RENAME {DATABASE | SCHEMA} db_name TO new_db_name;
做了坏事,只存在于少数版本中,总体来说是一个坏主意.
解决方案
对于 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
其他提示
使用以下几个简单的命令:
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
我认为解决方案更简单,是一些开发人员建议的。phpMyAdmin 有一个针对此的操作。
从 phpMyAdmin 中,选择您要选择的数据库。在选项卡中,有一个名为“操作”的选项卡,请转到“重命名”部分。就这样。
正如许多人所建议的那样,它会使用新名称创建一个新数据库,将旧数据库的所有表转储到新数据库中并删除旧数据库。
您可以使用 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;
(或其他一些大数字)。
模仿失踪者 RENAME DATABASE
MySQL 中的命令:
- 创建一个新数据库
使用以下命令创建重命名查询:
SELECT CONCAT('RENAME TABLE ',table_schema,'.',table_name, ' TO ','new_schema.',table_name,';') FROM information_schema.TABLES WHERE table_schema LIKE 'old_schema';
运行该输出
- 删除旧数据库
三个选项:
创建新数据库,关闭服务器,将文件从一个数据库文件夹移动到另一个数据库文件夹,然后重新启动服务器。请注意,只有当所有表都是 MyISAM 时,这才有效。
创建新数据库,使用 CREATE TABLE ...LIKE 语句,然后使用 INSERT ...SELECT * FROM 语句。
使用 mysqldump 并重新加载该文件。
简单的方法
切换到数据库目录:
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 数据库。在这种情况下,您必须转储数据库并重新导入它。
我最近才发现一种非常好的方法,可以与 MyISAM 和 InnoDB 配合使用,而且速度非常快:
RENAME TABLE old_db.table TO new_db.table;
我不记得我在哪里读到的,但功劳归于别人而不是我。
您可以使用这个 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
这就是我使用的:
$ 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;
最简单的万无一失的方法 完全的 改名 (包括最后删除旧数据库,这样它是重命名而不是副本):
mysqladmin -uroot -pmypassword create newdbname
mysqldump -uroot -pmypassword --routines olddbname | mysql -uroot -pmypassword newdbname
mysqladmin -uroot -pmypassword drop olddbname
脚步:
- 将这些行复制到记事本中。
- 将所有对“olddbname”、“newdbname”、“mypassword”(+ 可选“root”)的引用替换为您的等效项。
- 在命令行中一一执行(提示时输入“y”)。
MySQL 目前不支持通过其命令界面重命名数据库,但如果您有权访问 MySQL 存储其数据库的目录,则可以重命名数据库。对于默认的 MySQL 安装,这通常位于 MySQL 安装目录下的 Data 目录中。在Data目录下找到要重命名的数据库名称并重命名。不过,重命名目录可能会导致一些权限问题。意识到。
笔记: 您必须先停止 MySQL,然后才能重命名数据库
我建议创建一个新数据库(使用您想要的名称)并将您需要的数据从旧数据库导出/导入到新数据库。很简单。
当您在 PHPMyAdmin 中重命名数据库时,它会创建一个转储,然后删除并使用新名称重新创建数据库。
对于 Mac 用户,Sequel Pro 在“数据库”菜单中有一个“重命名数据库”选项。http://www.sequelpro.com/
那么有2种方法:
方法一: 重命名数据库模式的一种众所周知的方法是使用 Mysqldump 转储模式并将其恢复到另一个模式中,然后删除旧模式(如果需要)。
来自壳牌
mysqldump emp > emp.out
mysql -e "CREATE DATABASE employees;"
mysql employees < emp.out
mysql -e "DROP DATABASE emp;"
上述方法虽然简单,但是费时费空间。如果模式不止一个怎么办 100GB? 有一些方法可以将上述命令连接在一起以节省空间,但它不会节省时间。
为了解决这种情况,还有另一种快速方法来重命名模式,但是,执行此操作时必须小心。
方法二: 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.
这是使用 mysqldump 命令的 -E、-R 标志(除了转储触发器的 -t -d 之外)完成的。一旦触发器被转储,我们需要将它们从模式中删除,以便 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 表进行简单的 UPDATE 来修复,将 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
可以将一个数据库中的所有表重命名为另一个数据库下的表,而无需执行完整转储和恢复。
DROP PROCEDURE IF EXISTS mysql.rename_db; DELIMITER || CREATE PROCEDURE mysql.rename_db(IN old_db VARCHAR(100), IN new_db VARCHAR(100)) BEGIN SELECT CONCAT('CREATE DATABASE ', new_db, ';') `# create new database`; 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, '`;') `# drop old database`; END|| DELIMITER ; $ time mysql -uroot -e "call mysql.rename_db('db1', 'db2');" | mysql -uroot
然而,目标数据库中的任何触发器都不会满意。您需要先删除它们,然后在重命名后重新创建它们。
mysql -uroot -e "call mysql.rename_db('test', 'blah2');" | mysql -uroot ERROR 1435 (HY000) at line 4: Trigger in wrong schema
这里的大多数答案都是错误的,原因有二:
- 您不能只使用 RENAME TABLE,因为可能存在视图和触发器。如果有触发器,RENAME TABLE 失败
- 如果您想“快速”(按照问题中的要求)重命名大数据库,则不能使用 mysqldump
Percona 有一篇关于如何做好这一点的博客文章:https://www.percona.com/blog/2013/12/24/renaming-database-schema-mysql/
西蒙·R·琼斯发布(制作?)的脚本执行了该帖子中建议的操作。我修复了脚本中发现的错误。你可以在这里看到它:
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
这是我编写的一个批处理文件,用于从命令行自动执行它,但它适用于 Windows/MS-DOS。
语法是 rename_mysqldb database newdatabase -u [用户] -p[密码]
:: ***************************************************************************
:: 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=
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 ;
我 提出了关于服务器故障的问题 试图通过使用 MySQL 代理恢复非常大的数据库时避免停机。我没有取得任何成功,但我最终意识到我想要的是重命名数据库功能,因为由于我们数据库的大小,转储/导入不是一个选项。
MySQL 内置了 RENAME TABLE 功能,因此我最终编写了一个简单的 Python 脚本来帮我完成这项工作。我有 将其发布到 GitHub 上 以防对其他人有用。
为了您的方便,下面是一个必须使用两个参数执行的小 shell 脚本:数据库名称和新数据库名称。
如果您不使用主目录中的 .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"
最简单的方法是使用 HeidiSQL 软件。它是免费且开源的。它可以在 Windows 和任何 Linux 上运行 葡萄酒 (在 Linux、BSD、Solaris 和 Mac OS X 上运行 Windows 应用程序)。
要下载 HeidiSQL,请转到 http://www.heidisql.com/download.php.
要下载 Wine,请转到 http://www.winehq.org/.
要在 HeidiSQL 中重命名数据库,只需右键单击数据库名称并选择“编辑”。然后输入新名称并按“确定”。
就是这么简单。
如果您有许多表要移动,这里是生成重命名 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' ;
似乎没有人提到这一点,但这是另一种方式:
create database NewDatabaseName like OldDatabaseName;
然后对每个表执行以下操作:
create NewDatabaseName.tablename like OldDatabaseName.tablename;
insert into NewDataBaseName.tablename select * from OldDatabaseName.tablename;
那么,如果你愿意的话,
drop database OldDatabaseName;
这种方法的优点是可以在网络流量接近于零的服务器上完成整个传输,因此它比转储/恢复要快得多。
如果您确实有存储过程/视图/等,您可能也想传输它们。
对于 Mac 用户,您可以使用 Sequel Pro
(免费),它只提供重命名数据库的选项。虽然它不会删除旧数据库。
打开相关数据库后,只需单击: Database
--> Rename database...
在 MySQL 管理器中执行以下操作:
- 在目录下,创建一个新的数据库架构。
- 转到备份并创建旧模式的备份。
- 执行备份。
- 转到Restore并打开步骤3中创建的文件。
- 在目标架构下选择“另一个模式”,然后选择新的数据库架构。
- 开始恢复。
- 验证新模式,如果看起来不错,请删除旧模式。
在 phpmyadmin 您可以轻松地重命名数据库
select database
goto operations tab
in that rename Database to :
type your new database name and click go
要求删除旧表并重新加载表数据,然后在两者中单击“确定”
您的数据库已重命名
如果您正在使用 php我的管理员 选择要重命名的数据库后,您可以转到“操作”选项卡。然后转到最后一部分“将数据库复制到”(或类似的内容),给出名称,然后选择下面的选项。在这种情况下,我想您必须选择“结构和数据”和“复制之前创建数据库”复选框,最后按该部分中的“执行”按钮。
顺便说一句,我使用西班牙语的 phpMyAdmin,所以我不确定这些部分的英文名称是什么。
下面是一个单行 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
对旧模式具有读/写/删除权限,对新模式具有读/写/创建权限。