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

发布于 2024-07-05 08:49:14 字数 489 浏览 6 评论 0原文

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

通常我只是转储数据库并使用新名称重新导入它。 对于非常大的数据库来说,这不是一个选项。 显然重命名{数据库| SCHEMA} db_name TO new_db_name; 做了坏事,仅存在于少数版本中,总体来说是一个坏主意

这需要与 InnoDB 配合使用,它存储的内容与 MyISAM

How do I quickly rename a MySQL database (change its schema name)?

Usually I just dump a database and re-import it with a new name. This is not an option for very big databases. Apparently RENAME {DATABASE | SCHEMA} db_name TO new_db_name; does bad things, exists only in a handful of versions, and is a bad idea overall.

This needs to work with InnoDB, which stores things very differently than MyISAM.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(30

荒芜了季节 2024-07-12 08:49:14

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

  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< /代码>

Most of the answers here are wrong for one of two reasons:

  1. You cannot just use RENAME TABLE, because there might be views and triggers. If there are triggers, RENAME TABLE fails
  2. You cannot use mysqldump if you want to "quickly" (as requested in the question) rename a big database

Percona has a blog post about how to do this well:
https://www.percona.com/blog/2013/12/24/renaming-database-schema-mysql/

and script posted (made?) by Simon R Jones that does what is suggested in that post. I fixed a bug I found in the script. You can see it here:

https://gist.github.com/ryantm/76944318b0473ff25993ef2a7186213d

Here is a copy of it:

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

Save it to a file called rename_db and make the script executable with chmod +x rename_db then use it like ./rename_db localhost old_db new_db

淡忘如思 2024-07-12 08:49:14

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

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

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

MySQL does not support the renaming of a database through its command interface at the moment, but you can rename the database if you have access to the directory in which MySQL stores its databases. For default MySQL installations this is usually in the Data directory under the directory where MySQL was installed. Locate the name of the database you want to rename under the Data directory and rename it. Renaming the directory could cause some permissions issues though. Be aware.

Note: You must stop MySQL before you can rename the database

I would recommend creating a new database (using the name you want) and export/import the data you need from the old to the new. Pretty simple.

烦人精 2024-07-12 08:49:14

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

For those who are Mac users, Sequel Pro has a Rename Database option in the Database menu.
http://www.sequelpro.com/

奈何桥上唱咆哮 2024-07-12 08:49:14

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

create database NewDatabaseName like OldDatabaseName;

然后对每个表执行:

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

然后,如果您愿意,

drop database OldDatabaseName;

这种方法的优点是在网络流量接近零的服务器上进行整个传输,因此它会比转储/恢复。

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

Seems noone mentioned this but here is another way:

create database NewDatabaseName like OldDatabaseName;

then for each table do:

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

then, if you want to,

drop database OldDatabaseName;

This approach would have the advantage of doing the entire transfer on server with near zero network traffic, so it will go a lot faster than a dump/restore.

If you do have stored procedures/views/etc you might want to transfer them as well.

小草泠泠 2024-07-12 08:49:14

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

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

It is possible to rename all tables within a database to be under another database without having to do a full dump and restore.

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

However any triggers in the target db will not be happy. You'll need to drop them first then recreate them after the rename.

mysql -uroot -e "call mysql.rename_db('test', 'blah2');" | mysql -uroot
ERROR 1435 (HY000) at line 4: Trigger in wrong schema
浅笑依然 2024-07-12 08:49:14

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

打开相关数据库后,只需单击:Database --> 重命名数据库...

For mac users, you can use Sequel Pro (free), which just provide the option to rename Databases. Though it doesn't delete the old DB.

once open the relevant DB just click: Database --> Rename database...

倾城花音 2024-07-12 08:49:14

为了您的方便,下面是一个小的 shell 脚本,必须使用两个参数执行: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"

For your convenience, below is a small shellscript that has to be executed with two parameters: db-name and new db-name.

You might need to add login-parameters to the mysql-lines if you don't use the .my.cnf-file in your home-directory. Please make a backup before executing this script.


#!/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"
优雅的叶子 2024-07-12 08:49:14

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

Here is a batch file I wrote to automate it from the command line, but it for Windows/MS-DOS.

Syntax is rename_mysqldb database 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=
且行且努力 2024-07-12 08:49:14

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

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

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

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

就是这么简单。

The simplest method is to use HeidiSQL software. It's free and open source. It runs on Windows and on any Linux with Wine (run Windows applications on Linux, BSD, Solaris and Mac OS X).

To download HeidiSQL, goto http://www.heidisql.com/download.php.

To download Wine, goto http://www.winehq.org/.

To rename a database in HeidiSQL, just right click on the database name and select 'Edit'. Then enter a new name and press 'OK'.

It is so simple.

撩人痒 2024-07-12 08:49:14

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 ([email protected])

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 ;

TodoInTX's stored procedure didn't quite work for me. Here's my stab at it:

-- 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 ([email protected])

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 ;
兔姬 2024-07-12 08:49:14

您不能这样做是有原因的。 (尽管尝试了所有答案)

  • 基本答案在许多情况下都有效,但在其他情况下会导致数据损坏。
  • 需要根据数据库的启发式分析来选择策略。
  • 这就是此功能被实现的原因,然后被删除。 strong> [doc]

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

如果您想查看可以执行此操作的命令,@satishD 有详细信息,其中传达了一些您需要围绕这些挑战制定与您的目标数据库相匹配的策略。

There is a reason you cannot do this. (despite all the attempted answers)

  • Basic answers will work in many cases, and in others cause data corruptions.
  • A strategy needs to be chosen based on heuristic analysis of your database.
  • That is the reason this feature was implemented, and then removed. [doc]

You'll need to dump all object types in that database, create the newly named one and then import the dump. If this is a live system you'll need to take it down. If you cannot, then you will need to setup replication from this database to the new one.

If you want to see the commands that could do this, @satishD has the details, which conveys some of the challenges around which you'll need to build a strategy that matches your target database.

烟花易冷人易散 2024-07-12 08:49:14

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

Here is a quick way to generate renaming sql script, if you have many tables to move.

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' ;
吻泪 2024-07-12 08:49:14

ALTER DATABASE 是MySQL 提出的解决此问题的方法和 RENAME DATABASE 已被删除。

来自 13.1.32 RENAME DATABASE 语法< /em>:

RENAME {DATABASE | SCHEMA} db_name TO new_db_name;

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

ALTER DATABASE is the proposed way around this by MySQL and RENAME DATABASE is dropped.

From 13.1.32 RENAME DATABASE Syntax:

RENAME {DATABASE | SCHEMA} db_name TO new_db_name;

This statement was added in MySQL 5.1.7, but it was found to be dangerous and was removed in MySQL 5.1.23.

梦里人 2024-07-12 08:49:14

在 MySQL Administrator 中执行以下操作:

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

In MySQL Administrator do the following:

  1. Under Catalogs, create a new database schema.
  2. Go to Backup and create a backup of
    the old schema.
  3. Execute backup.
  4. Go to Restore and open the file
    created in step 3.
  5. Select 'Another Schema' under Target
    Schema and select the new database
    schema.
  6. Start Restore.
  7. Verify new schema and, if it looks
    good, delete the old one.
辞慾 2024-07-12 08:49:14

下面是一个单行 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 对旧架构拥有读/写/删除权限,并对新架构拥有读/写/创建权限。

Here is a one-line Bash snippet to move all tables from one schema to another:

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

The history command at the start simply ensures that the MySQL commands containing passwords aren't saved to the shell history.

Make sure that db_user has read/write/drop permissions on the old schema, and read/write/create permissions on the new schema.

葮薆情 2024-07-12 08:49:14

我是这样做的:
备份您现有的数据库。 它会给你一个 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”

I did it this way:
Take backup of your existing database. It will give you a db.zip.tmp and then in command prompt write following

"C:\Program Files (x86)\MySQL\MySQL Server 5.6\bin\mysql.exe" -h
localhost -u root -p[password] [new db name] < "C:\Backups\db.zip.tmp"

合约呢 2024-07-12 08:49:14

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 随后将在会话中徘徊。 如果不使用它,我就无法编写这个函数。

Neither TodoInTx's solution nor user757945's adapted solution worked for me on MySQL 5.5.16, so here is my adapted version:

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 ;

Hope it helps someone who is in my situation! Note: @sql_string will linger in the session afterwards. I was not able to write this function without using it.

留蓝 2024-07-12 08:49:14

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

select database 

  goto operations tab

  in that rename Database to :

  type your new database name and click go

要求删除旧表并重新加载表数据,然后单击“确定”,

您的数据库已重命名

in phpmyadmin you can easily rename the database

select database 

  goto operations tab

  in that rename Database to :

  type your new database name and click go

ask to drop old table and reload table data click OK in both

Your database is renamed

不顾 2024-07-12 08:49:14

使用这几个简单的命令:

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

Use these few simple commands:

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

Or to reduce I/O use the following as suggested by @Pablo Marin-Garcia:

mysqladmin -u username -p create newdatabase
mysqldump -u username -v olddatabase -p | mysql -u username -p -D newdatabase
莳間冲淡了誓言ζ 2024-07-12 08:49:14

对于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 部分。
  • 如果某个表有触发器,则无法使用上述方法将其移动到另一个数据库(将导致触发器错误架构错误)。 如果是这种情况,请使用传统方法克隆数据库,然后删除旧数据库:

    <代码>mysqldump old_db | mysql new_db

  • 如果你有存储过程,你可以随后复制它们:

    <代码>mysqldump -R old_db | mysql new_db

For InnoDB, the following seems to work: create the new empty database, then rename each table in turn into the new database:

RENAME TABLE old_db.table TO new_db.table;

You will need to adjust the permissions after that.

For scripting in a shell, you can use either of the following:

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

OR

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;

Notes:

  • There is no space between the option -p and the password. If your database has no password, remove the -u username -ppassword part.
  • If some table has a trigger, it cannot be moved to another database using above method (will result Trigger in wrong schema error). If that is the case, use a traditional way to clone a database and then drop the old one:

    mysqldump old_db | mysql new_db

  • If you have stored procedures, you can copy them afterwards:

    mysqldump -R old_db | mysql new_db

因为看清所以看轻 2024-07-12 08:49:14

您可以使用 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;(或其他一些大数字)来更改该限制。

You can use SQL to generate an SQL script to transfer each table in your source database to the destination database.

You must create the destination database before running the script generated from the command.

You can use either of these two scripts (I originally suggested the former and someone "improved" my answer to use GROUP_CONCAT. Take your pick, but I prefer the original):

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

or

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

($1 and $2 are source and target respectively)

This will generate a SQL command that you'll have to then run.

Note that GROUP_CONCAT has a default length limit that may be exceeded for databases with a large number of tables. You can alter that limit by running SET SESSION group_concat_max_len = 100000000; (or some other large number).

纵性 2024-07-12 08:49:14

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

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

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

在此处输入图像描述

I think the solution is simpler and was suggested by some developers. phpMyAdmin has an operation for this.

From phpMyAdmin, select the database you want to select. In the tabs there's one called Operations, go to the rename section. That's all.

It does, as many suggested, create a new database with the new name, dump all tables of the old database into the new database and drop the old database.

Enter image description here

撞了怀 2024-07-12 08:49:14

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

  1. 创建新数据库

  2. 创建重命名查询:

     SELECT CONCAT('重命名表',table_schema,'.`',table_name, 
           '` TO ','new_schema.`',table_name,'`;') 
       来自 information_schema.TABLES 
       WHERE table_schema LIKE 'old_schema'; 
      
  3. 运行该输出

  4. 删除旧数据库

它取自模拟丢失的重命名数据库MySQL 中的命令

Emulating the missing RENAME DATABASE command in MySQL:

  1. Create a new database

  2. Create the rename queries with:

     SELECT CONCAT('RENAME TABLE ',table_schema,'.`',table_name,
         '` TO ','new_schema.`',table_name,'`;')
     FROM information_schema.TABLES
     WHERE table_schema LIKE 'old_schema';
    
  3. Run that output

  4. Delete old database

It was taken from Emulating The Missing RENAME DATABASE Command in MySQL.

你的他你的她 2024-07-12 08:49:14

您可以使用以下 shell 脚本:

参考:如何重命名 MySQL 数据库?< /em>

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

You may use this shell script:

Reference: 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"

It's working:

$ sh rename_database.sh oldname newname
蓝眸 2024-07-12 08:49:14

三个选项:

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

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

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

Three options:

  1. Create the new database, bring down the server, move the files from one database folder to the other, and restart the server. Note that this will only work if ALL of your tables are MyISAM.

  2. Create the new database, use CREATE TABLE ... LIKE statements, and then use INSERT ... SELECT * FROM statements.

  3. Use mysqldump and reload with that file.

迷路的信 2024-07-12 08:49:14

简单的方法

切换到数据库目录:

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

The simple way

Change to the database directory:

cd /var/lib/mysql/

Shut down MySQL... This is important!

/etc/init.d/mysql stop

Okay, this way doesn't work for InnoDB or BDB-Databases.

Rename database:

mv old-name new-name

...or the table...

cd database/

mv old-name.frm new-name.frm

mv old-name.MYD new-name.MYD

mv old-name.MYI new-name.MYI

Restart MySQL

/etc/init.d/mysql start

Done...

OK, this way doesn't work with InnoDB or BDB databases. In this case you have to dump the database and re-import it.

始终不够 2024-07-12 08:49:14

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

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”)。

Simplest bullet-and-fool-proof way of doing a complete rename (including dropping the old database at the end so it's a rename rather than a copy):

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

Steps:

  1. Copy the lines into Notepad.
  2. Replace all references to "olddbname", "newdbname", "mypassword" (+ optionally "root") with your equivalents.
  3. Execute one by one on the command line (entering "y" when prompted).
北方的韩爷 2024-07-12 08:49:14

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

RENAME TABLE old_db.table TO new_db.table;

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

I've only recently came across a very nice way to do it, works with MyISAM and InnoDB and is very fast:

RENAME TABLE old_db.table TO new_db.table;

I don't remember where I read it but credit goes to someone else not me.

眉目亦如画i 2024-07-12 08:49:14

这就是我使用的:

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

This is what I use:

$ 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;
浅暮の光 2024-07-12 08:49:14

有两种方法:

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

From Shell

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

上面的方法虽然简单,但是比较费时间和空间。 如果架构超过100GB怎么办?有一些方法可以将上述命令连接在一起以节省空间,但不会节省时间。

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

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

使用所需名称创建新的数据库模式。
使用 MySQL 的“RENAME TABLE”命令将表从旧模式重命名为新模式。
删除旧的数据库架构。
如果架构中存在视图、触发器、函数、存储过程,那么这些也需要重新创建。 如果表上存在触发器,MySQL 的“RENAME TABLE”将失败。 为了解决这个问题,我们可以执行以下操作:

1) 将触发器、事件和存储例程转储到单独的文件中。这可以使用 -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 表进行简单的 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

Well there are 2 methods:

Method 1: A well-known method for renaming database schema is by dumping the schema using Mysqldump and restoring it in another schema, and then dropping the old schema (if needed).

From Shell

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

Although the above method is easy, it is time and space consuming. What if the schema is more than a 100GB? There are methods where you can pipe the above commands together to save on space, however it will not save time.

To remedy such situations, there is another quick method to rename schemas, however, some care must be taken while doing it.

Method 2: MySQL has a very good feature for renaming tables that even works across different schemas. This rename operation is atomic and no one else can access the table while its being renamed. This takes a short time to complete since changing a table’s name or its schema is only a metadata change. Here is procedural approach at doing the rename:

Create the new database schema with the desired name.
Rename the tables from old schema to new schema, using MySQL’s “RENAME TABLE” command.
Drop the old database schema.
If there are views, triggers, functions, stored procedures in the schema, those will need to be recreated too. MySQL’s “RENAME TABLE” fails if there are triggers exists on the tables. To remedy this we can do the following things :

1) Dump the triggers, events and stored routines in a separate file. This done using -E, -R flags (in addition to -t -d which dumps the triggers) to the mysqldump command. Once triggers are dumped, we will need to drop them from the schema, for RENAME TABLE command to work.

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

2) Generate a list of only “BASE” tables. These can be found using a query on information_schema.TABLES table.

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

3) Dump the views in an out file. Views can be found using a query on the same information_schema.TABLES table.

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) Drop the triggers on the current tables in the old_schema.

mysql> DROP TRIGGER <trigger_name>;
...

5) Restore the above dump files once all the “Base” tables found in step #2 are renamed.

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

Intricacies with above methods : We may need to update the GRANTS for users such that they match the correct schema_name. These could fixed with a simple UPDATE on mysql.columns_priv, mysql.procs_priv, mysql.tables_priv, mysql.db tables updating the old_schema name to new_schema and calling “Flush privileges;”. Although “method 2″ seems a bit more complicated than the “method 1″, this is totally scriptable. A simple bash script to carry out the above steps in proper sequence, can help you save space and time while renaming database schemas next time.

The Percona Remote DBA team have written a script called “rename_db” that works in the following way :

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

To demonstrate the use of this script, used a sample schema “emp”, created test triggers, stored routines on that schema. Will try to rename the database schema using the script, which takes some seconds to complete as opposed to time consuming dump/restore method.

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               |
+--------------------+

As you can see in the above output the database schema “emp” was renamed to “emp_test” in less than a second. Lastly, This is the script from Percona that is used above for “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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文