如何快速重命名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非常不同。

  • 也有serverfault:serverfault.com /问题/ 195221 /如何对rename的MySQL数据库zwnj &;& #号为8203去武器;
  • 这句话语法rename数据库是MySQL,但她在5.1.7被发现是危险和不removed在5.1.23 MySQL。
  • hopefully MySQL会执行一个新的工作RENAME DATABASEstatement,那不会有任何dangers S,As,有好的简单的方式来做这个任务的目前。有好的obvious原因为什么它是危险的文件,他们应该能做一个替代。至少有人把基于特征的请求错误是他们的网站。例如,bugs.mysql.com / bug.php???????id = 58593和bugs.mysql.com / bug.php???????id = 1698年)。
  • 链接是破碎的,现在…………………


对于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

  • 如果您的数据库很大,但没有那么多表(或者您愿意编写一个脚本来循环所有表),那么这是一个很好的选择,也是一种可行的方法。此外,在innodb中,它只是一个逻辑重命名,而在myisam中,根据文件系统的不同,它将是一个逻辑重命名或磁盘上的真实副本数据。
  • 我刚刚用一个包含30多个表的InnoDB数据库完成了这项工作,使用了file_per_table设置,即使有些表的行数超过了300万,它还是在不到1秒的时间内完成的。它似乎只是移动存储中的文件,而不是做任何更复杂的事情…+2如果可能的话:)
  • "Rename数据库被发现是危险的,已在MySQL5.1.23中删除"-来自dev.mysql.com/doc/refman/5.1/en/rename-database.html
  • 请注意,这对视图不起作用。不能重命名视图以使它们从数据库跳到另一个数据库。用DROP VIEWCREATE VIEW代替。是的,笨拙的。在首先移动所有表之后,您可能需要执行mysqldump来移动视图。还要注意,SHOW TABLES将显示表和视图,因此要小心。
  • 此外,这对于任何具有触发器的表都不起作用。在移动表之前,需要查找、转储和除去触发器,然后将转储的触发器导入目标数据库。
  • 这里有很多事情要注意。签出phpmyadmin的重命名数据库的源
  • 虽然对于大型数据库来说,mysqldump不是一个好的选择,但它支持默认的触发器,以及-R--routines参数(如答案中所述)和表支持(默认情况下)的过程。但它似乎不支持视图。
  • 更新(即工作)链接,记录删除RENAME DATABASE的原因:dev.mysql.com/worklog/task/?ID=4030
  • 谢谢你的建议。请注意,如果不希望提示您输入missin分号,则应在show tables命令后添加";"。
  • 或者如果安装了mysql实用程序:mysqldbcopy --source=username@localhost:port --destination=username@localhost:port old_db:new_db,然后删除旧的数据库。
  • 获取用以下select 'RENAME TABLE ' , concat(TABLE_SCHEMA,'.',TABLE_NAME) , concat(' TO .',TABLE_NAME) from information_schema.tables WHERE TABLE_SCHEMA = '' order by TABLE_NAME重命名的脚本
  • 在phpmyadmin中,我使用了operations/rename数据库。它速度惊人,几乎是瞬间的(1-2秒),所以我假设它使用的是RENAME TABLE策略。MySQL 5.6。
  • 使用此shell脚本后,请不要忘记在控制台中使用命令history -cw,因为您不希望密码以明文形式出现在控制台历史记录中。
  • 请有人解释一下操作员回答"之后需要调整权限"时的含义好吗?
  • @thomasbrew:这意味着您需要执行类似于use mysql; update db set db='new_db' where db = 'old_db'; flush priviledges;的SQL。


使用以下几个简单命令:

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

  • 正如操作人员所说,"对于非常大的数据库来说,HIS不是一个选项。"
  • 不要忘记删除原始数据库
  • 精彩的回答!有几个建议需要进一步改进,因为这可能是所有能力的谷歌搜索:(1)移动pablo marin garcia的代码片段到顶部,因为它似乎是最好的答案(2)把-p而不是-p放在任何地方,所以语句运行时不会出现提示。
  • 使用piped版本,我得到两个"enter password":提示如下:Enter password: Enter password:,它似乎需要一个密码,但不能同时使用两个密码。我是否遗漏了一个细节?
  • 我很惊讶没有人提到这一点,但您确实应该在mysqldump命令中添加--routines标志,以确保跨存储过程进行复制。
  • 我倾向于使用sqlyog-gui。1)创建具有所需名称的新数据库,然后使用"复制到不同主机/db"功能复制旧数据库。2)将数据库导出为sqldump,然后使用"工具"菜单中的"执行SQL脚本"选项导入
  • 这个解决方案是首选的,因为不必遍历所有表是非常方便的。虽然有人说这对"大型"数据库来说不是最好的,但是没有人从数量上描述这意味着什么。我的建议是先这样试试。你的数据库可能不是你认为的那个庞然大物。最坏的情况可能是磁盘满了,所以您应该准备好处理这个问题。


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

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

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

Enter image description here

  • 假设您的环境中甚至有PHP,或者使用phpmyadmin。
  • 即使有phpmyadmin,也相当危险-后端可能在进程中失败,导致两个DBS处于未知状态,或者可能需要很长时间,导致前端挂起或php超时。
  • 这是真的@mozboz,但我已经做了10年了,从来没有遇到过这个问题。如果通过shell运行该命令而计算机崩溃,则情况相同。有可能,但怎么办?1到1万亿?
  • 通过控制台的脚本也是一个前端,可以挂起同样的问题。
  • 然而,控制台操作要比phpmyadmin可靠得多,特别是在涉及大型数据库的情况下,这是OP的情况。我个人强烈建议任何控制台方法,而不是PMA,如果你有一个相当大的数据库。不用说,在小型数据库中,PMA也一样好。
  • 通过使用GNU屏幕运行控制台操作,还可以防止网络挂断和掉线。
  • 对于这些不同的问题,似乎有两个明显的解决方案。1-始终首先在开发环境中进行测试。2-您可以复制到新名称,而不是重命名。您始终可以回滚到原始数据库。
  • @Ayexem这是完全正确的,无论您使用的环境或工具是什么,都需要备份或复制数据,而不管您计划执行什么过程。根据数据量恢复数据通常很快。同意。
  • 这个答案很好。尤其是当我所做的只是测试一些书籍练习时。在php和phpmyadmin中。我把数据库命名错误…并创建了一些表……现在我要做的就是重新命名数据库。还有…工作完成了。
  • phpmyadmin是一个严格的工具。我希望他们通过日志记录和遇到错误时的重新滚动来实现这个功能,作为一个适当的ACID事务。不过,我还没有检查过。
  • 不适用于分区
  • 我使用phpmyadmin对许多不同大小的数据库进行了这样的处理。迄今为止,我从未失败过。警告:我们只使用myisam,在我们的任何系统中都没有innodb表(好吧,一些很小的异常)。
  • 我在./libraries/operations.lib.php 361中得到错误"notice"。未定义的变量:SQL_查询。backtrace./db_operations.php_69:pma_createdbeforecopy()"


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

  • @blakefrederick它不使用重命名数据库,那么问题是什么?
  • 这正是我要找的,谢谢。


在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中缺失的重命名数据库命令中提取的。

    • 很完美!我用innodb和myisam表测试了这个。我测试的最快的解决方案(重命名表几乎是即时的,没有延迟)!


    三种选择:

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

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

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

    • +用于myisam参考。我不明白为什么这对我不起作用。
    • 问题是这必须对InnoDB有效,而不是Myisam


    简单的方法

    更改到数据库目录:

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

    • 这不适用于InnoDB
    • 如果将innodb设置为每个表一个文件,那么它将与innodb一起工作。
    • 重命名文件夹会破坏玩具。
    • @Rahly,即使为每个表设置了一个文件,它仍然是危险的,在为每个表设置了一个文件之前创建的表将有问题,除非您确定数据库是在设置该标志之后创建的。
    • 不过,一般来说,大多数人将以一种方式或另一种方式拥有自己的系统,人们不会随机地在每个文件是否有一个表上切换。此外,即使在您的场景中,如果表是在标记之前创建的,那么它们最初也不会作为单独的文件存在,因此移动不会工作,而且仍然安全,没有危险。请记住,移动发生时数据库没有运行。
    • 与在OS X上安装自制的MySQL的等效项:launchctl unload -w ~/Library/LaunchAgents/homebrew.mxcl.mysql.plist cd /usr/local/var/mysql mv old-name new-name launchctl load -w ~/Library/LaunchAgents/homebrew.mxcl.mysql.plist


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

    1
    RENAME TABLE old_db.table TO new_db.table;

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

    • @阿卡迪库泽尔不这么认为。我想你是在说重命名数据库。
    • 这真的很有帮助,我创建了一个新的空白数据库,然后使用代码,所有表都以所需的名称导入。
    • 这与公认的答案"rename database was found to be dangerous and was removed in mysql 5.1.23"(重命名数据库被发现是危险的,并已在mysql 5.1.23中删除)存在相同的问题,该问题来自dev.mysql.com/doc/refman/5.1/en/rename-database.html


    您可以使用此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

    • 小心点。如果您没有使用根用户登录,您可能拥有有限的权限。导致重命名失败,但删除成功将导致删除数据库。否则脚本不错。
    • 我在脚本的开头添加了set -e,这将导致在失败时终止执行,并应减轻该问题。


    这是我使用的:

    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")。
    • 也许这个解决方案会导致用户权限问题。
    • 避免将密码添加到控制台,因为它不安全。如果您已经这样做了,那么就使用history-cw来删除它。相反,将密码留空,并在提示后输入。
    • 这花了不正常的时间,超过20分钟还没有结束。可以取消吗?


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

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

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

    • 如果您有innodb表,这将不起作用。


    在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

    • 小的调整使这个工作w/mysql 5.x mysql --batch-uroot -e"call mysql.rename_db('test', 'blah2');" | mysql -uroot注意,您必须使用--batch将格式改为原始格式,它输出结果w/zero格式。


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

  • 不能只使用重命名表,因为可能存在视图和触发器。如果有触发器,则重命名表失败
  • 如果要"快速"(如问题所要求)重命名一个大数据库,则不能使用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 (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 ;

    • 谢谢,工作!
    • 这只对表有效,并且仅当这些表没有任何触发器时才有效。视图和触发器不会由此移动。


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

    • phpmyadmin解决方案通常是一个糟糕的解决方案,因为某些环境限制了环境。
    • 这不是一个"好"的解决方案,但还是非常感谢,因为这正是我想要的。
    • 如果对你有用的话,请投票。会有帮助的。谢谢


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

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

    • 尽管关于RENAME TABLE,请记住这个语句是在mysql 5.1.7中添加的,但是被发现是危险的,并且在mysql 5.1.23中被删除了。
    • 重命名数据库已从语法中删除,而不是从重命名表中删除。


    最简单的方法是使用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,那么您也可能希望传输它们。

    • 据我所知,5.x在create database语句中不支持"like"关键字?你从哪儿弄来的?
    • 这里是create table like语法的链接:dev.mysql.com/doc/refman/5.7/en/create-table-like.html。至于createddatabase之类的,MySQL似乎从那以后就放弃了这个子句。


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

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

    • 在我的例子中,它不是在重命名数据库,而是在创建副本…
    • 它有时会让旧数据库保持活动状态,但它是空的。但是,如果它制作了一个副本,您可以制作副本并删除旧的副本,这仍然是两个简单的步骤。


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

  • 在目录下,创建一个新的数据库模式。
  • 转到备份并创建的备份旧的模式。
  • 执行备份。
  • 转到还原并打开文件在步骤3中创建。
  • 在目标下选择"另一个架构"架构并选择新数据库图式。
  • 开始恢复。
  • 验证新架构,如果它看起来好的,删除旧的。
    • MySQL管理员不能处理大数据库,而且没有什么快速的方法


    如果您使用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中被删除。

    • 你有什么语法示例吗?我不知道使用alter database重命名数据库本身的任何方法,并且您链接到的文档并不表示可以这样做。
    • @乔丹,我也会感兴趣的。我试了试,发现它只适用于5.1以上的版本,但现在无法更新。
    • -1:写推荐的方式,然后给出一个不推荐的方式的例子,而完全没有给出例子。
    • 这是错误的。mysql rename database文档说rename_database是为一个非常具体的重命名任务(而不是数据库重命名的一般情况)而设计的,这个任务现在由alter database处理:"要用新的编码来执行数据库名称升级的任务,请使用alter database db_name upgrade dat a directory name,而不能使用它来重命名数据。"尽管您希望这样做,但这个命令中甚至没有新的数据库名称的位置!


    如果从具有多个数据库的转储文件开始,可以在转储上执行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>>点击"操作",然后在"重命名数据库为:"字段中输入新名称,然后点击"执行"按钮。

    简单!

    • 显然,您指的是一些GUI管理工具。如果你说的话会有帮助的。
    • 我认为这是一个很好的解决办法。尽管我的问题是如何将外部数据库添加到phpmyadmin中。我的意思是如何在一个phpmyadmin站点中管理多个mysql实例。


    实际上,最简单的答案是导出旧数据库,然后将其导入到您创建的新数据库中,以替换旧数据库。当然,您应该使用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生成器

    • MySQL中没有修改名称


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