¿Cómo cambio rápidamente el nombre de una base de datos MySQL (cambiar el nombre del esquema)?

959

El manual de MySQL en MySQL cubre esto.

Por lo general, simplemente vuelco la base de datos y la vuelvo a importar con un nuevo nombre. Esta no es una opción para bases de datos muy grandes. Aparentemente RENAME {DATABASE | SCHEMA} db_name TO new_db_name; hace cosas malas, existe solo en un puñado de versiones y es una mala idea en general .

Esto debe funcionar con InnoDB , que almacena cosas de manera muy diferente a MyISAM .

Csaba
fuente
55
Esta sintaxis RENAME DATABASE se agregó en MySQL 5.1.7, pero se descubrió que era peligrosa y se eliminó en MySQL 5.1.23.
zloctb
11
Con suerte, MySQL implementará una nueva RENAME DATABASEdeclaración de trabajo que no tiene ningún peligro, ya que no hay una manera fácil de hacer esta tarea actualmente. No hay una razón obvia por la que fuera peligroso en la documentación, por lo que deberían poder hacer un reemplazo. Al menos las personas han puesto errores de solicitud de funciones en su sitio web. Por ejemplo, bugs.mysql.com/bug.php?id=58593 y bugs.mysql.com/bug.php?id=1698 .
Edward
los enlaces ahora están rotos ...
oldboy

Respuestas:

833

Para InnoDB , lo siguiente parece funcionar: cree la nueva base de datos vacía, luego cambie el nombre de cada tabla a la nueva base de datos:

RENAME TABLE old_db.table TO new_db.table;

Deberá ajustar los permisos después de eso.

Para las secuencias de comandos en un shell, puede usar cualquiera de los siguientes:

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

O

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;

Notas:

  • No hay espacio entre la opción -py la contraseña. Si su base de datos no tiene contraseña, elimine la -u username -ppasswordparte.
  • Si alguna tabla tiene un activador, no se puede mover a otra base de datos utilizando el método anterior (dará como resultado un Trigger in wrong schemaerror). Si ese es el caso, use una forma tradicional para clonar una base de datos y luego descarte la antigua:

    mysqldump old_db | mysql new_db

  • Si tiene procedimientos almacenados, puede copiarlos después:

    mysqldump -R old_db | mysql new_db

Benoit Duffez
fuente
26
Acabo de hacer esto con una base de datos InnoDB con más de 30 tablas, usando la configuración file_per_table, y aunque algunas tablas tenían más de 3 millones de filas, se completó en <1 segundo. Simplemente parece mover los archivos en el almacenamiento, en lugar de hacer algo más complicado ... +2 si es posible :)
Dave Rix
87
"Se encontró que RENAME DATABASE era peligroso y se eliminó en MySQL 5.1.23" - de dev.mysql.com/doc/refman/5.1/en/rename-database.html
Palani
13
Tenga en cuenta que esto no funcionará para las vistas. No puede cambiar el nombre de las vistas para que salten de una base de datos a otra. Uso DROP VIEWy en su CREATE VIEWlugar. Torpe, si. Es posible que desee hacer una mysqldumppara mover las vistas, después de mover primero todas las tablas. También tenga en cuenta que SHOW TABLESmostrará tablas Y vistas, así que tenga cuidado.
tuomassalo 01 de
99
Además, esto no funcionará para ninguna tabla con disparadores. Debe buscar, volcar y soltar los desencadenantes antes de mover la tabla, luego importar los desencadenadores volcados al db objetivo.
Olfan
55
Enlace actualizado (es decir, de trabajo) que documenta por qué RENAME DATABASEse eliminó: dev.mysql.com/worklog/task/?id=4030
alexis
443

Use estos pocos comandos simples:

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

O para reducir las E / S, use lo siguiente como lo sugiere @Pablo Marin-Garcia:

mysqladmin -u username -p create newdatabase
mysqldump -u username -v olddatabase -p | mysql -u username -p -D newdatabase
hendrasaputra
fuente
86
Como dijo el OP, "[t] his no es una opción para bases de datos muy grandes".
Pilcrow
3
No te olvides de tirar la base de datos original
Pavel Radzivilovsky
3
Brillante respuesta! Un par de sugerencias para mejorar aún más, ya que probablemente todas las habilidades lo busquen en Google: (1) Mueva el fragmento de código de Pablo Marin-Garcia a la parte superior, ya que parece la mejor respuesta (2) Poner en -p<password>lugar de en -ptodas partes para que las declaraciones se ejecuten sin una pronta aparición .
Steve Chambers
99
Al usar la versión canalizada, recibo dos mensajes de "Ingresar contraseña:": Enter password: Enter password: Parece que toma una contraseña, pero no ambas. ¿Me estoy perdiendo un detalle?
Ryan
33
Me sorprende que nadie haya mencionado esto, pero también debería agregar la --routinesbandera a los comandos mysqldump, para asegurarse de que los procedimientos almacenados se copien.
Carlos P
205

Creo que la solución es más simple y fue sugerida por algunos desarrolladores. phpMyAdmin tiene una operación para esto.

Desde phpMyAdmin, seleccione la base de datos que desea seleccionar. En las pestañas hay una llamada Operaciones, vaya a la sección de cambio de nombre. Eso es todo.

Como muchos sugirieron, crea una nueva base de datos con el nuevo nombre, descarga todas las tablas de la base de datos anterior en la nueva base de datos y suelta la base de datos anterior.

Ingrese la descripción de la imagen aquí

raphie
fuente
76
Suponiendo que incluso tiene php en su entorno o usa phpmyadmin.
Chris
26
Bastante peligroso incluso si tiene phpMyAdmin: el back-end podría fallar a mitad del proceso y dejar los dos dbs en un estado desconocido, o podría llevar mucho tiempo, lo que provocaría que el front-end se bloqueara o PHP agotara el tiempo de espera.
mozboz
20
Eso es cierto @mozboz, pero lo he hecho durante 10 años y nunca tuve ese problema. Es lo mismo si ejecuta el comando a través de un shell y su computadora se bloquea. Hay una posibilidad pero ¿qué? 1 a 1 cuatrillón?
raphie
24
Un script a través de la consola también es un front-end que puede colgarse con los mismos problemas.
Greg
11
Sin embargo, las operaciones de la consola son mucho más confiables que PhpMyAdmin, especialmente cuando se trata de grandes bases de datos, como es el caso del OP. Personalmente, recomendaría cualquier método de consola en lugar de PMA si tiene una base de datos razonablemente grande. No hace falta decir que en bases de datos pequeñas, PMA es igual de bueno.
Teodor Sandu
107

Puede usar SQL para generar un script SQL para transferir cada tabla de su base de datos de origen a la base de datos de destino.

Debe crear la base de datos de destino antes de ejecutar el script generado a partir del comando.

Puede usar cualquiera de estos dos scripts (originalmente sugerí el primero y alguien "mejoró" mi respuesta para usar GROUP_CONCAT. Elija, pero prefiero el original):

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

o

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

($ 1 y $ 2 son fuente y destino respectivamente)

Esto generará un comando SQL que luego deberá ejecutar.

Tenga en cuenta que GROUP_CONCATtiene un límite de longitud predeterminado que se puede superar para las bases de datos con una gran cantidad de tablas. Puede alterar ese límite ejecutando SET SESSION group_concat_max_len = 100000000;(o algún otro gran número).

ErichBSchulz
fuente
@BlakeFrederick No utiliza RENAME DATABASE, ¿cuál es el problema?
tuxayo
¿Funciona esto si la tabla tiene restricciones referenciales? Espero que no
dolmen
42

Emulando el RENAME DATABASEcomando que falta en MySQL:

  1. Crea una nueva base de datos
  2. Cree las consultas de cambio de nombre con:

    SELECT CONCAT('RENAME TABLE ',table_schema,'.',table_name,
        ' TO ','new_schema.',table_name,';')
    FROM information_schema.TABLES
    WHERE table_schema LIKE 'old_schema';
    
  3. Ejecuta esa salida

  4. Eliminar base de datos anterior

Fue tomado de Emular el comando RENAME DATABASE que falta en MySQL .

Marciano
fuente
1
¡Perfecto! Probé esto con las tablas InnoDB y MyISAM. ¡La solución más rápida que probé (renombrar la tabla es casi instantánea, sin demora)!
Philipp
¡Excelente! Solo recuerda arreglar los privilegios después.
Adam Faryna
PD. Mejor hacerlo antes de ejecutar las consultas de cambio de nombre si está trabajando en DB en vivo.
Adam Faryna
¿Funciona esto si la tabla tiene restricciones referenciales? Espero que no
dolmen
24

Tres opciones:

  1. Cree la nueva base de datos, baje el servidor, mueva los archivos de una carpeta de la base de datos a la otra y reinicie el servidor. Tenga en cuenta que esto solo funcionará si TODAS sus tablas son MyISAM.

  2. Cree la nueva base de datos, use las declaraciones CREATE TABLE ... LIKE, y luego use las instrucciones INSERT ... SELECT * FROM.

  3. Use mysqldump y vuelva a cargar con ese archivo.

cuello largo
fuente
+ para la referencia de myisam. No podía entender por qué esto no me había funcionado.
Christian Payne
55
La pregunta establece que esto debe funcionar para InnoDB, no MyISAM
D-Rock
@ D-Rock le cuenta eso a Google, que trae gente aquí según el título.
jiggunjer
24

La forma simple

Cambie al directorio de la base de datos:

cd /var/lib/mysql/

Cierre MySQL ... ¡Esto es importante!

/etc/init.d/mysql stop

De acuerdo, esta forma no funciona para las bases de datos InnoDB o BDB.

Cambiar el nombre de la base de datos:

mv old-name new-name

... o la mesa ...

cd database/

mv old-name.frm new-name.frm

mv old-name.MYD new-name.MYD

mv old-name.MYI new-name.MYI

Reiniciar MySQL

/etc/init.d/mysql start

Hecho...

OK, de esta manera no funciona con las bases de datos InnoDB o BDB. En este caso, debe volcar la base de datos y volver a importarla.

DeeCee
fuente
16
Cambiar el nombre de las carpetas rompe los juguetes.
ViniciusPires
1
@Rahly, incluso si se establece un archivo por tabla, sigue siendo peligroso, las tablas creadas antes de que se establezca un archivo por tabla estarán en problemas, a menos que sepa con certeza que la base de datos se crea después de que se estableció ese indicador.
Qian Chen
En términos generales, sin embargo, la mayoría de las personas tendrán sus sistemas de una forma u otra, las personas no cambiarán aleatoriamente si tienen o no una tabla por archivo. Además, incluso en su escenario, si las tablas se crearon antes de la bandera, no existirían como archivos separados en primer lugar, por lo que el movimiento no funcionaría y todavía es seguro, no hay peligro. Recuerde, la base de datos NO se está ejecutando cuando se realiza el movimiento.
Rahly
El equivalente para mysql instalado con homebrew en OS X: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
coberlin
22

Puede usar este script de shell:

Referencia: ¿Cómo cambiar el nombre de una base de datos MySQL?

#!/bin/bash
set -e # terminate execution on command failure

mysqlconn="mysql -u root -proot"
olddb=$1
newdb=$2
$mysqlconn -e "CREATE DATABASE $newdb"
params=$($mysqlconn -N -e "SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES \
                           WHERE table_schema='$olddb'")
for name in $params; do
      $mysqlconn -e "RENAME TABLE $olddb.$name to $newdb.$name";
done;
$mysqlconn -e "DROP DATABASE $olddb"

Esta funcionando:

$ sh rename_database.sh oldname newname
Grijesh Chauhan
fuente
66
Cuidado con esto. Si no inicia sesión con el usuario root, es posible que tenga un permiso limitado. Hacer que el cambio de nombre falle pero la caída se realice correctamente, lo que da como resultado una base de datos descartada. Buen guión de lo contrario.
Lex
3
Agregué set -eal comienzo del script, lo que hará que la ejecución finalice en caso de falla y debería mitigar ese problema.
Mikkel
19

Recientemente me he encontrado con una forma muy agradable de hacerlo, funciona con MyISAM e InnoDB y es muy rápido:

RENAME TABLE old_db.table TO new_db.table;

No recuerdo dónde lo leí, pero el crédito va a alguien más, no a mí.

Amr Mostafa
fuente
@ArkadijKuzhel no lo creo. Creo que estás hablando de RENAME DATABASE.
Rob Grant
Esto realmente ayudó, creé una nueva base de datos en blanco y luego usé el código, todas las tablas se importaron con los nombres deseados.
Julio
3
Esto tiene el mismo problema que la respuesta aceptada: "Se encontró que RENAME DATABASE era peligroso y se eliminó en MySQL 5.1.23" - de dev.mysql.com/doc/refman/5.1/en/rename-database.html
Blake Frederick
16

Más simple forma de bala y toda prueba de hacer un completo cambio de nombre (incluida la eliminación de la antigua base de datos al final lo que es un cambio de nombre en lugar de una copia) :

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

Pasos:

  1. Copie las líneas en el Bloc de notas.
  2. Reemplace todas las referencias a "olddbname", "newdbname", "mypassword" (+ opcionalmente "root") con sus equivalentes.
  3. Ejecute uno por uno en la línea de comando (ingrese "y" cuando se le solicite).
Steve Chambers
fuente
Evite agregar su contraseña a la consola ya que no es segura. Si ya ha hecho esto, use el historial -cw para eliminarlo. En su lugar, deje la contraseña vacía e ingrésela después de la solicitud.
Tommie C.
Tarda anormalmente largo, más de 20 minutos sin terminar. ¿Está bien cancelar?
Sigu Magwa
15

Esto es lo que uso:

$ 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;
eaykin
fuente
14
No es factible para grandes bases de datos.
mikesl
14

MySQL no admite el cambio de nombre de una base de datos a través de su interfaz de comandos en este momento, pero puede cambiar el nombre de la base de datos si tiene acceso al directorio en el que MySQL almacena sus bases de datos. Para las instalaciones de MySQL predeterminadas, esto generalmente se encuentra en el directorio de Datos debajo del directorio donde se instaló MySQL. Localice el nombre de la base de datos que desea cambiar de nombre en el directorio Datos y cámbiele el nombre. Sin embargo, cambiar el nombre del directorio podría causar algunos problemas de permisos. Ten cuidado

Nota: debe detener MySQL antes de poder cambiar el nombre de la base de datos

Recomendaría crear una nueva base de datos (utilizando el nombre que desee) y exportar / importar los datos que necesita de la antigua a la nueva. Bastante simple.

Bryanpearson
fuente
13

Cuando cambia el nombre de una base de datos en PHPMyAdmin, crea un volcado, luego descarta y recrea la base de datos con el nuevo nombre.

UnkwnTech
fuente
44
Tenga en cuenta que esta característica está un poco oculta en la pestaña "Operaciones", cuando hace clic en la base de datos.
Maris B.
13

Bueno, hay 2 métodos:

Método 1: Un método bien conocido para renombrar el esquema de la base de datos es volcar el esquema usando Mysqldump y restaurarlo en otro esquema, y ​​luego descartar el esquema anterior (si es necesario).

De Shell

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

Aunque el método anterior es fácil, requiere mucho tiempo y espacio. ¿Qué pasa si el esquema es más de 100 GB? Existen métodos en los que puede canalizar los comandos anteriores para ahorrar espacio, sin embargo, no ahorrará tiempo.

Para remediar tales situaciones, hay otro método rápido para cambiar el nombre de los esquemas, sin embargo, se debe tener cuidado al hacerlo.

Método 2: MySQL tiene una muy buena característica para renombrar tablas que incluso funciona en diferentes esquemas. Esta operación de cambio de nombre es atómica y nadie más puede acceder a la tabla mientras se renombra. Esto lleva poco tiempo en completarse ya que cambiar el nombre de una tabla o su esquema es solo un cambio de metadatos. Aquí hay un enfoque de procedimiento para cambiar el nombre:

Cree el nuevo esquema de base de datos con el nombre deseado. Cambie el nombre de las tablas del antiguo esquema al nuevo esquema, utilizando el comando "RENAME TABLE" de MySQL. Descarte el antiguo esquema de la base de datos. If there are views, triggers, functions, stored procedures in the schema, those will need to be recreated too. La "RENAME TABLE" de MySQL falla si existen desencadenantes en las tablas. Para remediar esto, podemos hacer lo siguiente:

1) Dump the triggers, events and stored routines in a separate file. Esto se hace usando los indicadores -E, -R (además de -t -d que vuelca los disparadores) al comando mysqldump. Una vez que se descartan los desencadenantes, tendremos que eliminarlos del esquema para que funcione el comando RENAME TABLE.

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

2) Genere una lista de solo tablas "BASE". Estos se pueden encontrar utilizando una consulta en la information_schema.TABLEStabla.

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

3) Volcar las vistas en un archivo de salida. Las vistas se pueden encontrar usando una consulta en la misma information_schema.TABLEStabla.

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) Suelta los disparadores en las tablas actuales en old_schema.

mysql> DROP TRIGGER <trigger_name>;
...

5) Restaure los archivos de volcado anteriores una vez que todas las tablas "Base" encontradas en el paso # 2 cambien de nombre.

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

Complejos con los métodos anteriores: es posible que debamos actualizar las SUBVENCIONES para los usuarios de modo que coincidan con el nombre_esquema correcto. Esto podría solucionarse con una simple ACTUALIZACIÓN en las tablas mysql.columns_priv, mysql.procs_priv, mysql.tables_priv, mysql.db actualizando el nombre old_schema a new_schema y llamando a "Flush privileges;". Aunque el "método 2" parece un poco más complicado que el "método 1", esto es totalmente programable. Una secuencia de comandos bash simple para llevar a cabo los pasos anteriores en la secuencia adecuada puede ayudarlo a ahorrar espacio y tiempo mientras renombra los esquemas de la base de datos la próxima vez.

El equipo de Percona Remote DBA ha escrito un script llamado "rename_db" que funciona de la siguiente manera:

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

Para demostrar el uso de este script, usé un esquema de muestra "emp", creó disparadores de prueba, almacenó rutinas en ese esquema. Intentará cambiar el nombre del esquema de la base de datos utilizando el script, que tarda unos segundos en completarse en lugar del método de volcado / restauración que consume mucho tiempo.

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

Como puede ver en el resultado anterior, el esquema de la base de datos "emp" fue renombrado como "emp_test" en menos de un segundo. Por último, este es el script de Percona que se usa arriba para el "método 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
Sathish D
fuente
¿Qué pasa con las restricciones referenciales?
dolmen
13

Pasos:

  1. Presiona http: // localhost / phpmyadmin /
  2. Seleccione su base de datos
  3. Haga clic en la pestaña Operaciones
  4. Habrá una pestaña como "Cambiar nombre de base de datos a". Agregue un nuevo nombre y marque Ajustar privilegios.
  5. Haz clic en Ir.

ingrese la descripción de la imagen aquí

Shubham Jain
fuente
1
Una solución phpMyAdmin suele ser una solución deficiente ya que algunos entornos tienen un entorno restringido.
Daniel Antunes Pinto
No es una "buena" solución, pero no obstante, gracias a que era lo que estaba buscando.
Jamie
1
Por favor vote si funciona para usted ... ayudará ... gracias
Shubham Jain
1
Esto funciona para mí, en el entorno phpMyAdmin, +1
William
12

Para aquellos que son usuarios de Mac, Sequel Pro tiene una opción de Cambiar nombre de base de datos en el menú Base de datos. http://www.sequelpro.com/

Duque
fuente
55
Tenga cuidado con esta opción si tiene vistas o disparadores en su base de datos. Detrás de esta opción de menú hay un script que creará una nueva base de datos y moverá todas las tablas. Esto no funcionará para las vistas o los desencadenantes, por lo que se quedarán en su base de datos anterior. El resultado son dos bases de datos rotas que necesitan reparación.
Olfan
10

La mayoría de las respuestas aquí son incorrectas por una de dos razones:

  1. No puede simplemente usar RENAME TABLE, porque puede haber vistas y disparadores. Si hay disparadores, la TABLA DE NOMBRES falla
  2. No puede usar mysqldump si desea "cambiar rápidamente" (como se solicitó en la pregunta) cambiar el nombre de una gran base de datos

Percona tiene una publicación de blog sobre cómo hacerlo bien: https://www.percona.com/blog/2013/12/24/renaming-database-schema-mysql/

y guión publicado (hecho?) por Simon R Jones que hace lo que se sugiere en esa publicación Arregle un error que encontré en el script. Puedes verlo aqui:

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

Aquí hay una copia del mismo:

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

Guárdelo en un archivo llamado rename_dby haga que el script sea ejecutable, chmod +x rename_dbluego úselo como./rename_db localhost old_db new_db

ryantm
fuente
Me gusta este guión, es casi universal. Sin embargo, no pudo procesar un caso cuando hay varias VIEW encadenadas donde definer no es root.
ENargit
9

Es posible cambiar el nombre de todas las tablas dentro de una base de datos para que estén bajo otra base de datos sin tener que hacer un volcado completo y restaurar.

PROCEDIMIENTO DE GOTA SI EXISTE mysql.rename_db;
DELIMITADOR ||
PROCEDIMIENTO DE CREACIÓN mysql.rename_db (IN old_db VARCHAR (100), IN new_db VARCHAR (100))
EMPEZAR
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`;
FIN ||
DELIMITADOR

$ time mysql -uroot -e "llamar a mysql.rename_db ('db1', 'db2');" El | mysql -uroot

Sin embargo, cualquier desencadenante en el objetivo db no será feliz. Tendrá que soltarlos primero y luego recrearlos después del cambio de nombre.

mysql -uroot -e "llamar a mysql.rename_db ('prueba', 'blah2');" El | mysql -uroot
ERROR 1435 (HY000) en la línea 4: Disparador en esquema incorrecto
TodoInTX
fuente
pequeño ajuste que hace que esto funcione con mysql 5.x mysql --batch-uroot -e "call mysql.rename_db('test', 'blah2');" | mysql -uroot Aviso, debe usar --batch para cambiar el formato a formato sin formato que genera los resultados con formato cero.
mikesl
8

Aquí hay un archivo por lotes que escribí para automatizarlo desde la línea de comandos, pero para Windows / MS-DOS.

La sintaxis es rename_mysqldb database newdatabase -u [usuario] -p [contraseña]

:: ***************************************************************************
:: 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=
Johnny
fuente
7

El procedimiento almacenado de TodoInTX no funcionó para mí. Aquí está mi puñalada:

- procedimiento almacenado rename_db: Cambiar el nombre de una base de datos a mi medio de copiar tablas.
- Advertencias: 
- Bloqueará cualquier base de datos existente con el mismo nombre que el nombre de la 'nueva' base de datos.
- SOLO copia tablas; los procedimientos almacenados y otros objetos de la base de datos no se copian.
- Tomer Altman ([email protected])

delimitador //
PROCEDIMIENTO DE GOTA SI EXISTE rename_db;
PROCEDIMIENTO DE CREACIÓN rename_db (IN old_db VARCHAR (100), IN new_db VARCHAR (100))
EMPEZAR
    DECLARE current_table VARCHAR (100);
    DECLARAR hecho INT POR DEFECTO 0;
    DECLARE old_tables CURSOR PARA seleccione table_name de information_schema.tables donde table_schema = old_db;
    DECLARAR CONTINUAR MANEJADOR PARA SET NO ENCONTRADO done = 1;

    SET @output = CONCAT ('DROP SCHEMA IF EXISTS', new_db, ';'); 
    PREPARE stmt FROM @output;
    EJECUTAR stmt;

    SET @output = CONCAT ('CREAR ESQUEMA SI NO EXISTE', new_db, ';');
    PREPARE stmt FROM @output;
    EJECUTAR stmt;

    OPEN old_tables;
    REPETIR
        FETCH old_tables INTO current_table;
        SI NO HECHO LUEGO
        SET @output = CONCAT ('alter table', old_db, '.', Current_table, 'rename', new_db, '.', Current_table, ';');
        PREPARE stmt FROM @output;
        EJECUTAR stmt;

        TERMINARA SI;
    HASTA FINALIZAR REPETIR;

    CERRAR tablas_viejas;

FINAL//
delimitador
user757945
fuente
Esto funcionará solo para tablas, y solo si estas tablas no tienen ningún desencadenante. Las vistas y los disparadores no serán movidos por esto.
Olfan
7

El método más simple es usar el software HeidiSQL. Es gratis y de código abierto. Se ejecuta en Windows y en cualquier Linux con Wine (ejecuta aplicaciones de Windows en Linux, BSD, Solaris y Mac OS X).

Para descargar HeidiSQL, vaya a http://www.heidisql.com/download.php .

Para descargar Wine, vaya a http://www.winehq.org/ .

Para cambiar el nombre de una base de datos en HeidiSQL, simplemente haga clic derecho en el nombre de la base de datos y seleccione 'Editar'. Luego ingrese un nuevo nombre y presione 'OK'.

Es muy simple

Fathah Rehman P
fuente
1
Si tiene procedimientos almacenados, no se puede renombrar.
abksharma
@abksharma En realidad obtendrá mensajes Los Database "database_name" contains stored routine(s) which cannot be moved.disparadores (al menos para la base de datos MariDB) se cuentan como rutinas almacenadas. No tenía ningún procedimiento almacenado, pero no pude cambiar el nombre de la base de datos hasta que solté todos los desencadenantes.
izogfif
7

Para usuarios de mac, puede usar Sequel Pro(gratis), que solo ofrece la opción de cambiar el nombre de las Bases de datos. Aunque no elimina el antiguo DB.

una vez abierto el DB relevante simplemente haga clic en: Database->Rename database...

Roee Gavirel
fuente
A veces deja vivo el viejo DB pero está vacío. Aún así, si hace una copia, puede hacer la copia y eliminar la anterior, todavía son 2 pasos simples.
Roee Gavirel
6

Me hizo una pregunta en el servidor falla intentando rodear el tiempo de inactividad en la restauración de grandes bases de datos mediante el uso de MySQL Proxy. No tuve ningún éxito, pero al final me di cuenta de que lo que quería era la funcionalidad RENAME DATABASE porque dump / import no era una opción debido al tamaño de nuestra base de datos.

Hay una funcionalidad RENAME TABLE incorporada en MySQL, así que terminé escribiendo un script Python simple para hacer el trabajo por mí. Lo he publicado en GitHub en caso de que pueda ser útil para otros.

cclark
fuente
Sin embargo RENAME TABLE, tenga
Peter V. Mørch
2
RENAME DATABASE se eliminó de la sintaxis, no RENAME TABLE.
Duque
6

Para su conveniencia, a continuación hay un pequeño shellscript que debe ejecutarse con dos parámetros: db-name y new db-name.

Es posible que necesite agregar parámetros de inicio de sesión a las líneas mysql si no utiliza el archivo .my.cnf en su directorio de inicio. Haga una copia de seguridad antes de ejecutar este 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"
gerrit damen
fuente
1
Esto tampoco funcionará para tablas con desencadenantes adjuntos o para vistas que no se pueden renombrar en otras bases de datos.
Olfan
6

Parece que nadie mencionó esto, pero aquí hay otra manera:

create database NewDatabaseName like OldDatabaseName;

entonces para cada tabla haga:

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

entonces, si quieres,

drop database OldDatabaseName;

Este enfoque tendría la ventaja de hacer la transferencia completa en el servidor con tráfico de red casi cero, por lo que será mucho más rápido que un volcado / restauración.

Si tiene procedimientos almacenados / vistas / etc., es posible que también desee transferirlos.

Tuncay Göncüoğlu
fuente
2
Por lo que sé, 5.x no admite palabras clave "me gusta" en la create databasedeclaración. ¿De dónde sacaste eso?
Dragas
Aquí está el enlace para la create table likesintaxis: dev.mysql.com/doc/refman/5.7/en/create-table-like.html . En cuanto a crear una base de datos como, parece que MySQL eliminó esa cláusula desde entonces.
Tuncay Göncüoğlu
4

Aquí hay una forma rápida de generar el cambio de nombre del script sql, si tiene muchas tablas para mover.

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' ;
yantaq
fuente
Se ve bien, pero esto no mueve los procedimientos almacenados o las vistas.
davidpricedev
probablemente debería agregar marcas de hash para ajustar el nombre de la tabla y el nombre del esquema
Funkodebat
4

ALTER DATABASEes la forma propuesta de evitar esto por MySQL y RENAME DATABASEse descarta.

Desde 13.1.32 RENAME DATABASE Sintaxis :

RENAME {DATABASE | SCHEMA} db_name TO new_db_name;

Esta declaración se agregó en MySQL 5.1.7, pero se encontró que era peligrosa y se eliminó en MySQL 5.1.23.

fancyPants
fuente
77
¿Tienes alguna sintaxis de ejemplo? No conozco ninguna forma de alter databasecambiar el nombre de la base de datos, y la documentación a la que se vinculó no sugiere que sea posible.
Jordania
@ Jordan También me interesaría. Intenté y probé y descubrí que solo funciona con la versión> 5.1 pero que no puedo actualizar en este momento.
fancyPants
55
-1: Para escribir sobre las formas propuestas, luego dar un ejemplo de la forma no propuesta mientras faltan totalmente para incluso mostrar un ejemplo.
Hakre
3
Esto está mal. La documentación de la base de datos de cambio de nombre de MySQL dice que rename_database estaba destinado a una tarea de cambio de nombre muy específica (no es un caso general de cambio de nombre de DB), que ahora se maneja con alter database: 'Para realizar la tarea de actualizar los nombres de la base de datos con la nueva codificación, use ALTER DATABASE db_name UPGRADE NOMBRE DE DIRECTORIO DE DATOS en su lugar 'No puede usar esto para cambiar el nombre de la base de datos como lo desee, ¡ni siquiera hay lugar para el nuevo nombre de base de datos en este comando!
Kanat Bolazar
3

En MySQL Administrator, haga lo siguiente:

  1. En Catálogos, cree un nuevo esquema de base de datos.
  2. Vaya a Copia de seguridad y cree una copia de seguridad del esquema anterior.
  3. Ejecutar copia de seguridad.
  4. Vaya a Restaurar y abra el archivo creado en el paso 3.
  5. Seleccione 'Otro esquema' en Esquema de destino y seleccione el nuevo esquema de base de datos.
  6. Iniciar restauración.
  7. Verifique el nuevo esquema y, si se ve bien, elimine el anterior.
Tom
fuente
MySQL Administrator no puede manejar grandes bases de datos y no hay nada rápido al respecto
deadprogrammer
3

en phpmyadmin puede cambiar fácilmente el nombre de la base de datos

select database 

  goto operations tab

  in that rename Database to :

  type your new database name and click go

pida que abandone la tabla anterior y vuelva a cargar los datos de la tabla, haga clic en Aceptar en ambos

Su base de datos cambia de nombre

murtaza.webdev
fuente
3

Si está utilizando phpMyAdmin , puede ir a la pestaña "operaciones" una vez que haya seleccionado la base de datos que desea renombrar. Luego vaya a la última sección "copiar base de datos a" (o algo así), asigne un nombre y seleccione las opciones a continuación. En este caso, supongo que debe seleccionar las casillas de verificación "estructura y datos" y "crear base de datos antes de copiar" y, finalmente, presionar el botón "ir" en esa sección.

Por cierto, estoy usando phpMyAdmin en español, así que no estoy seguro de cuáles son los nombres de las secciones en inglés.

Peter Mortensen
fuente