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

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

mysql上的mysql手册涵盖了这一点。

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

这需要与InnoDB一起工作,InnoDB存储的内容与MyISAM非常不同。


对于InnoDB,以下方法似乎有效:创建新的空数据库,然后将每个表依次重命名为新数据库:

1
RENAME TABLE old_db.table TO new_db.table;

之后需要调整权限。

对于在shell中编写脚本,可以使用以下任一项:

1
2
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

1
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


使用以下几个简单命令:

1
2
3
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:

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


我认为这个解决方案更简单,是一些开发人员提出的。phpmyadmin对此有一个操作。

从phpmyadmin中,选择要选择的数据库。在选项卡中有一个名为"操作"的选项卡,请转到"重命名"部分。这就是全部。

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

Enter image description here


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

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

您可以使用这两个脚本中的任何一个(我最初建议使用前者,并且有人"改进"了我的答案以使用GROUP_CONCAT。你挑吧,但我更喜欢原版的):

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

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


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

  • 创建新数据库
  • 创建重命名查询时使用:

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

  • 删除旧数据库
  • 它是从模仿MySQL中缺失的重命名数据库命令中提取的。


    三种选择:

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

  • 创建新数据库,使用创建表…就像语句,然后使用insert…选择*From语句。

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


  • 简单的方法

    更改到数据库目录:

    1
    cd /var/lib/mysql/

    关闭MySQL…这很重要!

    1
    /etc/init.d/mysql stop

    好吧,这种方法不适用于innodb或bdb数据库。

    重命名数据库:

    1
    mv old-name new-name

    ……或者桌子……

    1
    2
    3
    4
    5
    6
    7
    cd database/

    mv old-name.frm new-name.frm

    mv old-name.MYD new-name.MYD

    mv old-name.MYI new-name.MYI

    重新启动MySQL

    1
    /etc/init.d/mysql start

    完成...

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


    我最近才发现一种非常好的方法,可以与myisam和innodb一起工作,而且速度非常快:

    1
    RENAME TABLE old_db.table TO new_db.table;

    我不记得我在哪里读到的,但是信用卡给了别人而不是我。


    您可以使用此shell脚本:

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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    #!/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"

    它的工作原理是:

    1
    $ sh rename_database.sh oldname newname


    这是我使用的:

    1
    2
    3
    4
    5
    6
    $ 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;


    最简单的完全重命名方法(包括将旧数据库放在末尾,使其成为重命名而不是副本):

    1
    2
    3
    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的目录下的数据目录中。在数据目录下找到要重命名的数据库的名称,然后将其重命名。但是,重命名目录可能会导致一些权限问题。注意。

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

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


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


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


    有两种方法:

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

    从外壳

    1
    2
    3
    4
     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命令的。一旦触发器被转储,我们将需要从模式中删除它们,以便重命名表命令工作。

    1
     $ mysqldump  -d -t -R -E > stored_routines_triggers_events.out

    2)只生成"基本"表的列表。这些可以通过查询information_schema.TABLES表来找到。

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

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

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

    4)删除旧模式中当前表上的触发器。

    1
    2
    mysql> DROP TRIGGER <trigger_name>;
    ...

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

    1
    2
    3
    4
    mysql> RENAME TABLE .table_name TO <new_schema>.table_name;
    ...
    $ mysql <new_schema> < views.out
    $ mysql <new_schema> < stored_routines_triggers_events.out

    上述方法的复杂性:我们可能需要更新用户的授权,使它们与正确的模式名称相匹配。这些可以通过对mysql.columns_priv、mysql.procs_priv、mysql.tables_priv、mysql.db表的简单更新来修复,将旧的_schema名称更新为新的_schema,并调用"flush privileges;"。尽管"方法2"看起来比"方法1"要复杂一些,但这是完全可脚本化的。一个简单的bash脚本以正确的顺序执行上述步骤,可以帮助您在下次重命名数据库模式时节省空间和时间。

    Percona远程DBA团队编写了一个名为"Rename_DB"的脚本,其工作方式如下:

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

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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    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脚本。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    #!/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

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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    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

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

    1
    2
    mysql -uroot -e"call mysql.rename_db('test', 'blah2');" | mysql -uroot
    ERROR 1435 (HY000) at line 4: Trigger in wrong schema


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

  • 不能只使用重命名表,因为可能存在视图和触发器。如果有触发器,则重命名表失败
  • 如果要"快速"(如问题所要求)重命名一个大数据库,则不能使用mysqldump。
  • Percona有一篇关于如何做好这件事的博客:https://www.percona.com/blog/2013/12/24/renaming-database-schema-mysql/

    和脚本发布(制作?)西蒙·R·琼斯写的,按照那篇文章的建议做。我修复了在脚本中发现的一个错误。你可以在这里看到:

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

    这是一份副本:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    #!/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[user]-p[password]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    :: ***************************************************************************
    :: 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的存储过程对我来说不太管用。这是我的一招:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    -- 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 ;


    为了方便起见,下面是一个小的shellscript,它必须用两个参数执行:db name和new db name。

    如果不在主目录中使用.my.cnf文件,可能需要向MySQL行添加登录参数。请在执行此脚本之前进行备份。

    1
    2
    3
    4
    5
    6
    7
    8
    #!/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"


    步骤:

  • 点击http://localhost/phpmyadmin/
  • 选择数据库
  • 单击操作选项卡
  • 将有一个选项卡,名为"将数据库重命名为"。添加新名称并选中调整权限。
  • 点击Go。
  • enter image description here


    我提出了一个关于服务器故障的问题,试图在使用mysql代理恢复非常大的数据库时避开停机时间。我没有任何成功,但最终我意识到我想要的是重命名数据库功能,因为转储/导入不是一个选项,因为我们的数据库太大。

    MySQL内置了一个重命名表功能,所以我最后编写了一个简单的python脚本来完成这项工作。我已经把它贴在Github上了,以防对其他人有用。


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

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

    要下载葡萄酒,请访问http://www.winehq.org/。

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

    这很简单。


    如果有许多表要移动,下面是生成重命名SQL脚本的快速方法。

    1
    2
    3
    4
    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' ;


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

    1
    create database NewDatabaseName like OldDatabaseName;

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

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

    如果你想,

    1
    drop database OldDatabaseName;

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

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


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

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


    在MySQL管理员中,执行以下操作:

  • 在目录下,创建一个新的数据库模式。
  • 转到备份并创建的备份旧的模式。
  • 执行备份。
  • 转到还原并打开文件在步骤3中创建。
  • 在目标下选择"另一个架构"架构并选择新数据库图式。
  • 开始恢复。
  • 验证新架构,如果它看起来好的,删除旧的。

  • 如果您使用phpmyadmin,则在选择要重命名的数据库后,可以转到"操作"选项卡。然后转到最后一节"复制数据库到"(或类似的内容),给出一个名称,然后选择下面的选项。在这种情况下,我猜您必须选择"结构和数据"和"复制前创建数据库"复选框,最后按该部分中的"执行"按钮。

    顺便说一下,我用的是西班牙语的phpmyadmin,所以我不知道这些部分的英文名称是什么。


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

    1
    2
    3
    4
    5
    6
    7
    select database

      goto operations tab

      in that rename Database to :

      type your new database name and click go

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

    数据库已重命名


    下面是一个单行bash片段,用于将所有表从一个架构移动到另一个架构:

    1
    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对旧模式具有读/写/删除权限,对新模式具有读/写/创建权限。


    我是这样做的:备份现有数据库。它将为您提供一个db.zip.tmp,然后在命令提示符中写入以下内容

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


    这是我为在Windows上重命名数据库而编写的批处理脚本:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    @echo off
    set olddb=olddbname
    set newdb=newdbname
    SET count=1
    SET act=mysql -uroot -e"select table_name from information_schema.tables where table_schema='%olddb%'"
    mysql -uroot -e"create database %newdb%"
    echo %act%
     FOR /f"tokens=*" %%G IN ('%act%') DO (
      REM echo %count%:%%G
      echo mysql -uroot -e"RENAME TABLE %olddb%.%%G to %newdb%.%%G"
      mysql -uroot -e"RENAME TABLE %olddb%.%%G to %newdb%.%%G"
      set /a count+=1
     )
    mysql -uroot -e"drop database %olddb%"

    你可以用两种方式做到。

  • 将表old_db.table_name重命名为new_db.table_name;
  • 转到Operations(操作)->在那里可以看到Table Options(表选项)选项卡。您可以在那里编辑表名。

  • 这适用于所有数据库,并通过使用maatkit mysql工具包重命名每个表来工作。

    使用mk find打印并重命名每个表。手册页有更多的选项和示例

    1
    mk-find --dblike OLD_DATABASE --print --exec"RENAME TABLE %D.%N TO NEW_DATABASE.%N"

    如果安装了MAATKIT(这很容易),那么这是最简单的方法。


    mysql建议使用ALTER DATABASE,删除RENAME DATABASE

    从13.1.32重命名数据库语法:

    1
    RENAME {DATABASE | SCHEMA} db_name TO new_db_name;

    这个声明是在MySQL5.1.7中添加的,但被发现是危险的,并在MySQL5.1.23中被删除。


    如果从具有多个数据库的转储文件开始,可以在转储上执行SED:

    1
    2
    3
    sed -i --"s|old_name_database1|new_name_database1|g" my_dump.sql
    sed -i --"s|old_name_database2|new_name_database2|g" my_dump.sql
    ...

    然后导入您的转储文件。只需确保没有名称冲突。


    如果使用层次视图(从其他视图提取数据的视图),则从mysqldump导入原始输出可能不起作用,因为mysqldump不关心视图的正确顺序。因此,我编写了一个脚本,该脚本将视图重新排序,以便在运行中更正顺序。

    就像这样:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    #!/usr/bin/env perl

    use List::MoreUtils 'first_index'; #apt package liblist-moreutils-perl
    use strict;
    use warnings;


    my $views_sql;

    while (<>) {
        $views_sql .= $_ if $views_sql or index($_, 'Final view structure') != -1;
        print $_ if !$views_sql;
    }

    my @views_regex_result = ($views_sql =~ /(\-\- Final view structure.+?
    \-\-

    .+?

    )/msg);
    my @views = (join("", @views_regex_result) =~ /\-\- Final view structure for view `(.+?)`/g);
    my $new_views_section ="";
    while (@views) {
        foreach my $view (@views_regex_result) {
            my $view_body = ($view =~ /\/\*.+?VIEW .+ AS (select .+)\*\/;/g )[0];
            my $found = 0;
            foreach my $view (@views) {
                if ($view_body =~ /(from|join)[ \(]+`$view`/) {
                    $found = $view;
                    last;
                }
            }
            if (!$found) {
                print $view;
                my $name_of_view_which_was_not_found = ($view =~ /\-\- Final view structure for view `(.+?)`/g)[0];
                my $index = first_index { $_ eq $name_of_view_which_was_not_found } @views;
                if ($index != -1) {
                    splice(@views, $index, 1);
                    splice(@views_regex_result, $index, 1);
                }
            }
        }
    }

    用途:mysqldump -u username -v olddatabase -p | ./mysqldump_view_reorder.pl | mysql -u username -p -D newdatabase


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

  • 使用mysqldump或任何数据库工具(如heidisql、mysql administrator等)备份文件

  • 在某些文本编辑器中打开备份文件(如back up file.sql)。

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

  • 4.还原已编辑的SQL文件


    TodoinTX的解决方案和用户757945的自适应解决方案在MySQL5.5.16上都不适合我,所以下面是我的自适应版本:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    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将在会后逗留。如果不使用这个函数,我就无法编写它。


    我发布了这个,如何使用MySQL更改数据库名称?今天,经过几天的刮头和拉毛。解决方案非常简单:将架构导出到.sql文件,打开该文件,然后在顶部的sql creat table部分更改数据库/架构名称。有三个或更多实例,如果将多表模式保存到文件中,则可能不在页面顶部。以这种方式编辑整个数据库是可能的,但我希望在大型数据库中,跟踪表属性或索引的所有实例可能会非常痛苦。


    i).无法直接更改现有数据库的名称但你可以通过以下步骤实现你的目标:1)。创建NeXDB。2)。使用NEDB。3)。创建表表名称(从olddb.tableu name中选择*)。

    通过上述操作,可以从olddb表中复制数据,并将其插入newdb表中。请给出相同的表名。

    ii)。将表old_db.table_name重命名为new_db.table_name;


    你们要为此开枪打我,很可能这不会每次都奏效,当然,这和所有的逻辑无关。但我刚尝试的是…停止mysql引擎,以root身份登录,然后简单地在文件系统级别重命名db…

    我在OSX上,只是把情况从Bedbf改为Bedbf。令我惊讶的是,它起了作用…

    我不建议在生产数据库上使用它。我只是做了个实验…

    祝你好运:—)


    这里已经有很多很好的答案了,但是我没有看到一个PHP版本。这将在大约一秒钟内复制一个800M数据库。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    $oldDbName ="oldDBName";
    $newDbName ="newDBName";
    $oldDB     = new mysqli("localhost","user","pass", $oldDbName);
    if($oldDB->connect_errno){
        echo"Failed to connect to MySQL: (" . $oldDB->connect_errno .")" . $oldDB->connect_error;
        exit;
    }
    $newDBQuery ="CREATE DATABASE IF NOT EXISTS {$newDbName}";
    $oldDB->query($newDBQuery);
    $newDB = new mysqli("localhost","user","pass");
    if($newDB->connect_errno){
        echo"Failed to connect to MySQL: (" . $newDB->connect_errno .")" . $newDB->connect_error;
        exit;
    }

    $tableQuery  ="SHOW TABLES";
    $tableResult = $oldDB->query($tableQuery);
    $renameQuery ="RENAME TABLE
    "
    ;
    while($table = $tableResult->fetch_array()){
        $tableName = $table["Tables_in_{$oldDbName}"];
        $renameQuery .="{$oldDbName}.{$tableName} TO {$newDbName}.{$tableName},";
    }
    $renameQuery = substr($renameQuery, 0, strlen($renameQuery) - 1);
    $newDB->query($renameQuery);

    最简单的是,打开mysql>>选择要更改名称的db>>点击"操作",然后在"重命名数据库为:"字段中输入新名称,然后点击"执行"按钮。

    简单!


    实际上,最简单的答案是导出旧数据库,然后将其导入到您创建的新数据库中,以替换旧数据库。当然,您应该使用phpmyadmin或命令行来执行此操作。

    重命名和篡改数据库是个坏主意!不要这样做。(除非你是"黑客类型"坐在你母亲的地下室,在黑暗中吃比萨饼,白天睡觉。)

    你最终会遇到比你想要的更多的问题和工作。

    所以,

  • 创建一个新的数据库并以正确的方式命名。
  • 转到phpmyadmin并打开要导出的数据库。
  • 导出它(选中选项,但您应该可以使用默认值。
  • 您将得到类似或类似的文件。
  • 此文件的扩展名为.sql

    --phpmyadmin SQL转储--版本3.2.4

    --网址:http://www.phpmyadmin.net

    --主机:本地主机--发电时间:2010年6月30日下午12:17--服务器版本:5.0.90--PHP版本:5.2.6

    设置sql_mode="no_auto_value_on_zero";

    /*!40101设置@old_character_set_client=@@character_set_client/;!40101集@old_character_set_results=@@character_set_results/;!40101设置@old_collation_connection=@@collation_connection/;!40101设置名称utf8*/;

    ——

    --数据库:mydatab_online

    ——

    --表user的表结构

    如果不存在则创建表user。(timestampint(15)非空默认值'0',ipvarchar(40)非空默认',filevarchar(100)非空默认',主键(timestamp)键ip(ip)密钥file(file))引擎=myisam默认字符集=latin1;

    ——

    --表user的转储数据

    插入user(timestampipfile值(1277911052,'999.236.177.116','')(127791194,'999.236.177.116','');

  • 这将是您的.sql文件。您刚导出的那个。

    在硬盘上找到它;通常在/temp中。选择具有正确名称的空数据库(阅读此内容的原因)。说:导入-执行

    通过将程序输入通常是configuration.php文件,将其连接到正确的数据库。刷新服务器(两个。为什么?因为我是一个Unix老手,我是这么说的。现在,你应该状态良好。如果您还有任何问题,请访问我的网站。


    简单的方法

    1
    ALTER DATABASE `oldName` MODIFY NAME = `newName`;

    或者可以使用联机SQL生成器


    如果您正在使用phpmyadmin,那么您只需转到xamp中的mysql文件夹,关闭phpmyadmin,只需重命名您刚才看到的作为数据库名称的文件夹,然后重新启动phpmyadmin。您可以看到该数据库已重命名。