Comment renommer rapidement une base de données MySQL (changer le nom du schéma)?

959

Le manuel MySQL de MySQL couvre cela.

Habituellement, je vide simplement la base de données et la réimporte avec un nouveau nom. Ce n'est pas une option pour les très grandes bases de données. Apparemment, RENAME {DATABASE | SCHEMA} db_name TO new_db_name; fait de mauvaises choses, n'existe que dans une poignée de versions et est une mauvaise idée dans l'ensemble .

Cela doit fonctionner avec InnoDB , qui stocke les choses très différemment de MyISAM .

Csaba
la source
5
Cette instruction RENAME DATABASE Syntax a été ajoutée dans MySQL 5.1.7 mais s'est avérée dangereuse et a été supprimée dans MySQL 5.1.23.
zloctb
11
Espérons que MySQL implémentera une nouvelle RENAME DATABASEdéclaration de travail qui ne présente aucun danger, car il n'y a pas de moyen facile de faire cette tâche actuellement. Il n'y a aucune raison évidente pour laquelle cela était dangereux dans la documentation , ils devraient donc pouvoir effectuer un remplacement. Au moins, les gens ont mis des bogues de demande de fonctionnalité sur leur site Web. Par exemple, bugs.mysql.com/bug.php?id=58593 et bugs.mysql.com/bug.php?id=1698 .
Edward
les liens sont maintenant rompus ...
oldboy

Réponses:

833

Pour InnoDB , les éléments suivants semblent fonctionner: créez la nouvelle base de données vide, puis renommez chaque table tour à tour en nouvelle base de données:

RENAME TABLE old_db.table TO new_db.table;

Vous devrez ensuite ajuster les autorisations.

Pour les scripts dans un shell, vous pouvez utiliser l'une des méthodes suivantes:

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

OU

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;

Remarques:

  • Il n'y a pas d'espace entre l'option -pet le mot de passe. Si votre base de données n'a pas de mot de passe, supprimez la -u username -ppasswordpièce.
  • Si une table a un déclencheur, il ne peut pas être déplacé vers une autre base de données en utilisant la méthode ci-dessus (cela entraînera une Trigger in wrong schemaerreur). Si tel est le cas, utilisez une méthode traditionnelle pour cloner une base de données, puis supprimez l'ancienne:

    mysqldump old_db | mysql new_db

  • Si vous avez des procédures stockées, vous pouvez les copier par la suite:

    mysqldump -R old_db | mysql new_db

Benoit Duffez
la source
26
Je viens de le faire avec une base de données InnoDB avec plus de 30 tables, en utilisant le paramètre file_per_table, et même si certaines tables comptaient plus de 3 millions de lignes, elles se sont terminées en <1 seconde. Il semble simplement déplacer les fichiers sur le stockage, plutôt que de faire quelque chose de plus compliqué ... +2 si possible :)
Dave Rix
87
"RENAME DATABASE s'est avéré dangereux et a été supprimé dans MySQL 5.1.23" - de dev.mysql.com/doc/refman/5.1/en/rename-database.html
Palani
13
Veuillez noter que cela ne fonctionnera pas pour les vues. Vous ne pouvez pas renommer des vues pour les faire passer d'une base de données à une autre. Utilisez DROP VIEWet à la CREATE VIEWplace. Maladroit, oui. Vous voudrez peut-être faire un mysqldumppour déplacer les vues, après avoir d'abord déplacé toutes les tables. Notez également que SHOW TABLESles tables et les vues seront affichées, alors méfiez-vous.
tuomassalo
9
Cela ne fonctionnera pas non plus pour les tables avec déclencheurs. Vous devez rechercher, sauvegarder et supprimer des déclencheurs avant de déplacer la table, puis importer les déclencheurs sauvegardés dans la base de données cible.
Olfan
5
Lien mis à jour (c'est-à-dire fonctionnel) documentant les raisons de la RENAME DATABASEsuppression: dev.mysql.com/worklog/task/?id=4030
alexis
443

Utilisez ces quelques commandes simples:

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

Ou pour réduire les E / S, utilisez ce qui suit comme suggéré par @Pablo Marin-Garcia:

mysqladmin -u username -p create newdatabase
mysqldump -u username -v olddatabase -p | mysql -u username -p -D newdatabase
hendrasaputra
la source
86
Comme l'OP l'a dit, "[t] ce n'est pas une option pour les très grandes bases de données".
pilcrow
3
N'oubliez pas de SUPPRIMER la base de données d'origine
Pavel Radzivilovsky
3
Réponse brillante! Quelques suggestions pour améliorer davantage car cela est probablement googlé par toutes les capacités: (1) Déplacez le fragment de code de Pablo Marin-Garcia vers le haut car il semble que la meilleure réponse (2) Mettez à la -p<password>place de -ppartout pour que les instructions s'exécutent sans qu'une invite n'apparaisse .
Steve Chambers
9
En utilisant la version pipée, j'obtiens deux invites "Entrez le mot de passe:" comme ceci: Enter password: Enter password: Il semble prendre un mot de passe, mais pas les deux. Suis-je en train de manquer un détail?
Ryan
33
Je suis surpris que personne n'ait mentionné cela, mais vous devriez vraiment ajouter le --routinesdrapeau aux commandes mysqldump, pour vous assurer que les procédures stockées sont copiées.
Carlos P
205

Je pense que la solution est plus simple et a été suggérée par certains développeurs. phpMyAdmin a une opération pour cela.

Dans phpMyAdmin, sélectionnez la base de données que vous souhaitez sélectionner. Dans les onglets, il y en a un appelé Opérations, accédez à la section Renommer. C'est tout.

Comme beaucoup l'ont suggéré, il crée une nouvelle base de données avec le nouveau nom, vide toutes les tables de l'ancienne base de données dans la nouvelle base de données et supprime l'ancienne base de données.

Entrez la description de l'image ici

raphie
la source
76
En supposant que vous ayez même php sur votre environnement ou utilisez phpmyadmin.
Chris
26
Assez dangereux même si vous avez phpMyAdmin - le back-end pourrait échouer au milieu du processus en laissant les deux dbs dans un état inconnu, ou cela pourrait prendre très longtemps, conduisant à la suspension du front-end ou au dépassement du délai de PHP.
mozboz
20
C'est vrai @mozboz, mais je fais ça depuis 10 ans et je n'ai jamais eu ce problème. Est la même chose si vous exécutez la commande via un shell et que votre ordinateur tombe en panne. Il y a une possibilité mais quoi? 1 à 1 quadrillion?
raphie
24
Un script via la console est également un frontal qui peut se bloquer avec les mêmes problèmes.
Greg
11
Pourtant, les opérations sur console sont beaucoup plus fiables que PhpMyAdmin, en particulier lorsque de grandes bases de données sont impliquées, ce qui est le cas du PO. Personnellement, je suggérerais fortement toute méthode de console plutôt que PMA si vous avez une base de données assez grande. Inutile de dire que sur les petites bases de données, le PMA est tout aussi bon.
Teodor Sandu
107

Vous pouvez utiliser SQL pour générer un script SQL pour transférer chaque table de votre base de données source vers la base de données de destination.

Vous devez créer la base de données de destination avant d'exécuter le script généré à partir de la commande.

Vous pouvez utiliser l'un de ces deux scripts (à l'origine, j'ai suggéré l'ancien et quelqu'un "amélioré" ma réponse à utiliser GROUP_CONCAT. Faites votre choix, mais je préfère l'original):

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

ou

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

(1 $ et 2 $ sont respectivement source et cible)

Cela générera une commande SQL que vous devrez ensuite exécuter.

Notez qu'il GROUP_CONCATa une limite de longueur par défaut qui peut être dépassée pour les bases de données avec un grand nombre de tables. Vous pouvez modifier cette limite en exécutant SET SESSION group_concat_max_len = 100000000;(ou un autre grand nombre).

ErichBSchulz
la source
@BlakeFrederick Il n'utilise pas RENAME DATABASE alors quel est le problème?
tuxayo
Est-ce que cela fonctionne si la table a des contraintes référentielles? Je ne m'attends pas.
dolmen
42

Émuler la RENAME DATABASEcommande manquante dans MySQL:

  1. Créer une nouvelle base de données
  2. Créez les requêtes de renommage avec:

    SELECT CONCAT('RENAME TABLE ',table_schema,'.',table_name,
        ' TO ','new_schema.',table_name,';')
    FROM information_schema.TABLES
    WHERE table_schema LIKE 'old_schema';
  3. Exécutez cette sortie

  4. Supprimer l'ancienne base de données

Il provient de l' émulation de la commande RENAME DATABASE manquante dans MySQL .

Marciano
la source
1
Parfait! J'ai testé cela avec les tables InnoDB et MyISAM. La solution la plus rapide que j'ai testée (renommer la table est presque instantanée, sans délai)!
Philipp
Génial! N'oubliez pas de fixer les privilèges par la suite.
Adam Faryna
ps. Mieux vaut le faire avant d'exécuter les requêtes de renommage si vous travaillez sur une base de données en direct.
Adam Faryna
Est-ce que cela fonctionne si la table a des contraintes référentielles? Je ne m'attends pas.
dolmen
24

Trois options:

  1. Créez la nouvelle base de données, arrêtez le serveur, déplacez les fichiers d'un dossier de base de données vers l'autre et redémarrez le serveur. Notez que cela ne fonctionnera que si TOUTES vos tables sont MyISAM.

  2. Créez la nouvelle base de données, utilisez les instructions CREATE TABLE ... LIKE, puis utilisez les instructions INSERT ... SELECT * FROM.

  3. Utilisez mysqldump et rechargez avec ce fichier.

longneck
la source
+ pour la référence myisam. Je ne pouvais pas comprendre pourquoi cela n'avait pas fonctionné pour moi.
Christian Payne
5
La question stipule que cela doit fonctionner pour InnoDB, pas MyISAM
D-Rock
@ D-Rock dit cela à Google, qui amène les gens ici en fonction du titre.
jiggunjer
24

La manière simple

Accédez au répertoire de la base de données:

cd /var/lib/mysql/

Arrêtez MySQL ... C'est important!

/etc/init.d/mysql stop

D'accord, cette méthode ne fonctionne pas pour les bases de données InnoDB ou BDB.

Renommer la base de données:

mv old-name new-name

... ou la table ...

cd database/

mv old-name.frm new-name.frm

mv old-name.MYD new-name.MYD

mv old-name.MYI new-name.MYI

Redémarrez MySQL

/etc/init.d/mysql start

Terminé...

OK, cette méthode ne fonctionne pas avec les bases de données InnoDB ou BDB. Dans ce cas, vous devez vider la base de données et la réimporter.

DeeCee
la source
16
Renommer les dossiers casse les jouets.
ViniciusPires
1
@Rahly, même si un fichier par table est défini, c'est toujours dangereux, les tables créées avant la définition d'un fichier par table seront en difficulté, sauf si vous savez avec certitude que la base de données est créée après la définition de cet indicateur.
Qian Chen
De manière générale, cependant, la plupart des gens vont avoir leurs systèmes dans un sens ou dans l'autre, les gens ne vont pas basculer au hasard pour savoir s'ils doivent ou non avoir une table par fichier. De plus, même dans votre scénario, si les tables ont été créées avant le drapeau, elles n'existeraient pas en tant que fichiers séparés, donc le mouvement ne fonctionnerait pas et c'est toujours sûr, pas de danger. N'oubliez pas que la base de données ne fonctionne PAS lorsque le déménagement a lieu.
Rahly
L'équivalent pour mysql installé avec homebrew sur 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

Vous pouvez utiliser ce script shell:

Référence: Comment renommer une base de données 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"

Ça marche:

$ sh rename_database.sh oldname newname
Grijesh Chauhan
la source
6
Attention à ça. Si vous ne vous connectez pas avec l'utilisateur root, vous pouvez avoir une autorisation limitée. Causer l'échec du changement de nom mais la réussite de la suppression entraînant la suppression d'une base de données. Joli script sinon.
Lex
3
J'ai ajouté set -eau début du script, ce qui entraînera la fin de l'exécution en cas d'échec et devrait atténuer ce problème.
Mikkel le
19

Je n'ai rencontré que récemment une très belle façon de le faire, fonctionne avec MyISAM et InnoDB et est très rapide:

RENAME TABLE old_db.table TO new_db.table;

Je ne me souviens pas où je l'ai lu mais le mérite revient à quelqu'un d'autre pas à moi.

Amr Mostafa
la source
@ArkadijKuzhel ne le pense pas. Je pense que vous parlez de RENAME DATABASE.
Rob Grant
Cela a vraiment aidé, j'ai créé une nouvelle base de données vierge, puis j'ai utilisé le code, toutes les tables ont été importées avec les noms souhaités.
JuilletOrdinaire
3
Cela souffre du même problème que la réponse acceptée - "RENOMMER LA BASE DE DONNÉES a été jugée dangereuse et a été supprimée dans MySQL 5.1.23" - de dev.mysql.com/doc/refman/5.1/en/rename-database.html
Blake Frederick
16

Manière la plus simple et infaillible de faire un changement de nom complet (y compris la suppression de l'ancienne base de données à la fin pour qu'il s'agisse d'un changement de nom plutôt que d'une copie) :

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

Pas:

  1. Copiez les lignes dans le Bloc-notes.
  2. Remplacez toutes les références à "olddbname", "newdbname", "mypassword" (+ éventuellement "root") par vos équivalents.
  3. Exécutez-les un par un sur la ligne de commande (saisissez "y" lorsque vous y êtes invité).
Steve Chambers
la source
Évitez d'ajouter votre mot de passe à la console car elle n'est pas sécurisée. Si vous l'avez déjà fait, utilisez history -cw pour le supprimer. Au lieu de cela, laissez le mot de passe vide et entrez-le après l'invite.
Tommie C.19
Cela prend anormalement longtemps, plus de 20 minutes sans finir. Peut-on annuler?
Sigu Magwa
15

Voici ce que j'utilise:

$ 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
la source
14
Non faisable pour les énormes bases de données.
mikesl
14

MySQL ne prend pas en charge le changement de nom d'une base de données via son interface de commande pour le moment, mais vous pouvez renommer la base de données si vous avez accès au répertoire dans lequel MySQL stocke ses bases de données. Pour les installations MySQL par défaut, cela se trouve généralement dans le répertoire Data sous le répertoire où MySQL a été installé. Recherchez le nom de la base de données que vous souhaitez renommer sous le répertoire Data et renommez-le. Le fait de renommer le répertoire pourrait cependant entraîner des problèmes d'autorisations. Être conscient.

Remarque: Vous devez arrêter MySQL avant de pouvoir renommer la base de données

Je recommanderais de créer une nouvelle base de données (en utilisant le nom que vous voulez) et d'exporter / importer les données dont vous avez besoin de l'ancien vers le nouveau. Assez simple.

bryanpearson
la source
13

Lorsque vous renommez une base de données dans PHPMyAdmin, il crée un vidage, puis supprime et recrée la base de données avec le nouveau nom.

UnkwnTech
la source
4
Notez que cette fonctionnalité est un peu cachée sous l'onglet "Opérations", lorsque vous cliquez sur la base de données.
Maris B.
13

Eh bien, il existe 2 méthodes:

Méthode 1: Une méthode bien connue pour renommer le schéma de base de données consiste à vider le schéma à l'aide de Mysqldump et à le restaurer dans un autre schéma, puis à supprimer l'ancien schéma (si nécessaire).

De Shell

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

Bien que la méthode ci-dessus soit facile, elle prend du temps et de l'espace. Et si le schéma est supérieur à 100 Go? Il existe des méthodes où vous pouvez diriger les commandes ci-dessus ensemble pour économiser de l'espace, mais cela ne fera pas gagner de temps.

Pour remédier à de telles situations, il existe une autre méthode rapide pour renommer les schémas, cependant, une certaine prudence doit être prise lors de cette opération.

Méthode 2: MySQL a une très bonne fonctionnalité pour renommer des tables qui fonctionne même sur différents schémas. Cette opération de renommage est atomique et personne d'autre ne peut accéder à la table pendant qu'elle est renommée. Cela prend un peu de temps car le changement du nom d'une table ou de son schéma n'est qu'un changement de métadonnées. Voici l'approche procédurale pour effectuer le changement de nom:

Créez le nouveau schéma de base de données avec le nom souhaité. Renommez les tables de l'ancien schéma au nouveau schéma, en utilisant la commande «RENAME TABLE» de MySQL. Supprimez l'ancien schéma de base de données. If there are views, triggers, functions, stored procedures in the schema, those will need to be recreated too. «RENAME TABLE» de MySQL échoue s'il existe des déclencheurs sur les tables. Pour y remédier, nous pouvons procéder comme suit:

1) Dump the triggers, events and stored routines in a separate file. Cela se fait en utilisant les drapeaux -E, -R (en plus de -t -d qui vide les déclencheurs) à la commande mysqldump. Une fois les déclencheurs vidés, nous devrons les supprimer du schéma pour que la commande RENAME TABLE fonctionne.

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

2) Générez une liste de tables «BASE» uniquement. Ceux-ci peuvent être trouvés en utilisant une requête sur information_schema.TABLEStable.

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

3) Videz les vues dans un fichier de sortie. Les vues peuvent être trouvées en utilisant une requête sur la même information_schema.TABLEStable.

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) Déposez les déclencheurs sur les tables en cours dans l'ancien_schéma.

mysql> DROP TRIGGER <trigger_name>;
...

5) Restaurez les fichiers de vidage ci-dessus une fois que toutes les tables «Base» trouvées à l'étape # 2 ont été renommées.

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

Intricités avec les méthodes ci-dessus: Il se peut que nous devions mettre à jour les SUBVENTIONS pour les utilisateurs afin qu'ils correspondent au nom de schéma correct. Ceux-ci pourraient être corrigés avec une simple MISE À JOUR sur mysql.columns_priv, mysql.procs_priv, mysql.tables_priv, les tables mysql.db mettant à jour le nom old_schema en new_schema et appelant «Privilèges de vidage;». Bien que la «méthode 2» semble un peu plus compliquée que la «méthode 1», elle est totalement scriptable. Un simple script bash pour exécuter les étapes ci-dessus dans le bon ordre peut vous aider à économiser de l'espace et du temps tout en renommant les schémas de base de données la prochaine fois.

L'équipe Percona Remote DBA a écrit un script appelé «rename_db» qui fonctionne de la manière suivante:

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

Pour démontrer l'utilisation de ce script, utilisé un exemple de schéma «emp», créé des déclencheurs de test, des routines stockées sur ce schéma. Essaiera de renommer le schéma de la base de données à l'aide du script, ce qui prend quelques secondes à terminer, contrairement à la méthode de vidage / restauration longue.

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

Comme vous pouvez le voir dans la sortie ci-dessus, le schéma de base de données «emp» a été renommé «emp_test» en moins d'une seconde. Enfin, il s'agit du script de Percona utilisé ci-dessus pour la «méthode 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
la source
Qu'en est-il des contraintes référentielles?
dolmen
13

Pas :

  1. Appuyez sur http: // localhost / phpmyadmin /
  2. Sélectionnez votre DB
  3. Cliquez sur l'onglet Opérations
  4. Il y aura un onglet "Renommer la base de données en". Ajoutez un nouveau nom et cochez Ajuster les privilèges.
  5. Cliquez sur Go.

entrez la description de l'image ici

Shubham Jain
la source
1
Une solution phpMyAdmin est généralement une mauvaise solution car certains environnements ont un environnement restreint.
Daniel Antunes Pinto
Pas une "bonne" solution mais merci quand même car c'est ce que je cherchais.
jamie
1
Veuillez voter si cela fonctionne pour vous .. cela vous aidera .. merci
Shubham Jain
1
Cela fonctionne pour moi, dans l'environnement phpMyAdmin, +1
William
12

Pour ceux qui sont des utilisateurs de Mac, Sequel Pro a une option Renommer la base de données dans le menu Base de données. http://www.sequelpro.com/

Duc
la source
5
Méfiez-vous de cette option si vous avez des vues ou des déclencheurs dans votre base de données. Derrière cette option de menu se trouve un script qui va créer une nouvelle base de données et déplacer toutes les tables. Cela ne fonctionnera pas pour les vues ou les déclencheurs, ils seront donc laissés dans votre ancienne base de données. Le résultat est deux bases de données cassées à réparer.
Olfan
10

La plupart des réponses ici sont fausses pour l'une des deux raisons:

  1. Vous ne pouvez pas simplement utiliser RENAME TABLE, car il peut y avoir des vues et des déclencheurs. S'il y a des déclencheurs, RENAME TABLE échoue
  2. Vous ne pouvez pas utiliser mysqldump si vous voulez "rapidement" (comme demandé dans la question) renommer une grande base de données

Percona a un article de blog sur la façon de bien le faire: https://www.percona.com/blog/2013/12/24/renaming-database-schema-mysql/

et script posté (fait?) par Simon R Jones qui fait ce qui est suggéré dans ce post. J'ai corrigé un bug que j'ai trouvé dans le script. Tu peux le voir ici:

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

En voici une copie:

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

Enregistrez-le dans un fichier appelé rename_dbet rendez le script exécutable avec chmod +x rename_dbpuis utilisez-le comme./rename_db localhost old_db new_db

ryantm
la source
J'aime ce script, il est presque universel. Cependant, il n'a pas réussi à traiter un cas lorsqu'il existe plusieurs VUES chaînées où definer n'est pas root.
ENargit
9

Il est possible de renommer toutes les tables d'une base de données pour qu'elles se trouvent sous une autre base de données sans avoir à effectuer un vidage et une restauration complets.

DROP PROCEDURE IF EXISTS mysql.rename_db;
DELIMITER ||
CREATE PROCEDURE mysql.rename_db (IN old_db VARCHAR (100), IN new_db VARCHAR (100))
COMMENCER
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 ||
DELIMITER;

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

Cependant, tous les déclencheurs dans la base de données cible ne seront pas satisfaits. Vous devrez d'abord les supprimer puis les recréer après le changement de nom.

mysql -uroot -e "appeler mysql.rename_db ('test', 'blah2');" | mysql -uroot
ERREUR 1435 (HY000) à la ligne 4: déclenchement dans un schéma incorrect
TodoInTX
la source
petit ajustement qui fait que cela fonctionne avec mysql 5.x mysql --batch-uroot -e "call mysql.rename_db('test', 'blah2');" | mysql -uroot Remarquez, vous devez utiliser --batch pour changer le formatage en formatage brut qui produit les résultats avec un formatage nul.
mikesl
8

Voici un fichier batch que j'ai écrit pour l'automatiser à partir de la ligne de commande, mais pour Windows / MS-DOS.

La syntaxe est la base de données rename_mysqldb newdatabase -u [utilisateur] -p [mot de passe]

:: ***************************************************************************
:: 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
la source
7

La procédure stockée de TodoInTX ne fonctionnait pas tout à fait pour moi. Voici mon coup de couteau:

- procédure stockée rename_db: renommer une base de données mes moyens de copie de table.
- Mises en garde: 
- Clobbera toute base de données existante portant le même nom que le «nouveau» nom de base de données.
- Copie UNIQUEMENT les tableaux; les procédures stockées et autres objets de base de données ne sont pas copiés.
- Tomer Altman ([email protected])

délimiteur //
DROP PROCEDURE IF EXISTS rename_db;
CREATE PROCEDURE rename_db (IN old_db VARCHAR (100), IN new_db VARCHAR (100))
COMMENCER
    DECLARE current_table VARCHAR (100);
    DECLARE done INT DEFAULT 0;
    DECLARE old_tables CURSOR FOR sélectionnez table_name dans information_schema.tables où table_schema = old_db;
    DECLARE CONTINUER LE MANIPULATEUR POUR ENSEMBLE NON TROUVE 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;
    RÉPÉTER
        FETCH old_tables INTO current_table;
        SI NON FAIT ALORS
        SET @output = CONCAT ('alter table', old_db, '.', Current_table, 'rename', new_db, '.', Current_table, ';');
        PREPARE stmt FROM @output;
        EXECUTE stmt;

        FIN SI;
    JUSQU'À FAIRE FIN RÉPÉTER;

    CLOSE old_tables;

FIN//
délimiteur;
user757945
la source
Cela ne fonctionnera que pour les tables, et uniquement si ces tables n'ont pas de déclencheurs. Les vues et les déclencheurs ne seront pas déplacés par cela.
Olfan
7

La méthode la plus simple consiste à utiliser le logiciel HeidiSQL. C'est gratuit et open source. Il fonctionne sur Windows et sur n'importe quel Linux avec Wine (exécutez des applications Windows sur Linux, BSD, Solaris et Mac OS X).

Pour télécharger HeidiSQL, allez à http://www.heidisql.com/download.php .

Pour télécharger Wine, rendez-vous sur http://www.winehq.org/ .

Pour renommer une base de données dans HeidiSQL, faites un clic droit sur le nom de la base de données et sélectionnez «Modifier». Saisissez ensuite un nouveau nom et appuyez sur «OK».

C'est tellement simple.

Fathah Rehman P
la source
1
S'il a des procédures stockées, il ne peut pas être renommé.
abksharma
@abksharma En fait, vous obtiendrez des Database "database_name" contains stored routine(s) which cannot be moved.déclencheurs de message (au moins pour la base de données MariDB) sont comptés comme des routines stockées. Je n'avais aucune procédure stockée, mais je n'ai pas pu renommer la base de données tant que je n'ai pas supprimé tous les déclencheurs.
izogfif
7

Pour les utilisateurs de Mac, vous pouvez utiliser Sequel Pro(gratuit), qui fournit simplement l'option de renommer les bases de données. Bien qu'il ne supprime pas l'ancienne base de données.

une fois ouvert la base de données pertinente, cliquez simplement sur: Database->Rename database...

Roee Gavirel
la source
Elle laisse parfois l'ancienne DB en vie mais elle est vide. Pourtant, s'il fait une copie, vous pouvez faire la copie et supprimer l'ancienne, c'est toujours 2 étapes simples.
Roee Gavirel
6

J'ai posé une question sur la défaillance du serveur en essayant de contourner les temps d'arrêt lors de la restauration de très grandes bases de données à l'aide de MySQL Proxy. Je n'ai pas eu de succès, mais j'ai finalement réalisé que je voulais la fonctionnalité RENAME DATABASE car le vidage / import n'était pas une option en raison de la taille de notre base de données.

Il y a une fonctionnalité RENAME TABLE intégrée à MySQL, j'ai donc fini par écrire un simple script Python pour faire le travail pour moi. Je l'ai posté sur GitHub au cas où il pourrait être utile à d'autres.

cclark
la source
2
RENAME DATABASE a été supprimé de la syntaxe, pas RENAME TABLE.
Duke
6

Pour votre commodité, voici un petit shellscript qui doit être exécuté avec deux paramètres: nom-db et nouveau nom-db.

Vous devrez peut-être ajouter des paramètres de connexion aux lignes mysql si vous n'utilisez pas le fichier .my.cnf dans votre répertoire personnel. Veuillez faire une sauvegarde avant d'exécuter ce 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
la source
1
Cela ne fonctionnera pas non plus pour les tables auxquelles sont associés des déclencheurs ou pour les vues qui ne peuvent pas être renommées dans d'autres bases de données.
Olfan
6

Il semble que personne ne l'ait mentionné, mais voici une autre façon:

create database NewDatabaseName like OldDatabaseName;

puis pour chaque table:

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

alors, si vous voulez,

drop database OldDatabaseName;

Cette approche aurait l'avantage de faire l'intégralité du transfert sur le serveur avec un trafic réseau proche de zéro, donc cela ira beaucoup plus vite qu'une sauvegarde / restauration.

Si vous avez des procédures / vues / etc stockées, vous pouvez également les transférer.

Tuncay Göncüoğlu
la source
2
Pour autant que je sache, 5.x ne prend pas en charge le mot clé "like" dans la create databasedéclaration? D'où tenez-vous cela?
Dragas
Voici le lien pour la create table likesyntaxe: dev.mysql.com/doc/refman/5.7/en/create-table-like.html . En ce qui concerne la création de bases de données, il semble que MySQL ait supprimé cette clause depuis.
Tuncay Göncüoğlu
4

Voici un moyen rapide de générer le changement de nom du script sql, si vous avez plusieurs tables à déplacer.

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
la source
Semble bon, mais cela ne déplace pas les procédures stockées ou les vues.
davidpricedev
vous devriez probablement ajouter des marques de hachage pour entourer le nom de la table et le nom du schéma
Funkodebat
4

ALTER DATABASEest la solution proposée par MySQL et RENAME DATABASEest supprimée.

Depuis 13.1.32 RENAME DATABASE Syntaxe :

RENAME {DATABASE | SCHEMA} db_name TO new_db_name;

Cette déclaration a été ajoutée dans MySQL 5.1.7, mais elle s'est avérée dangereuse et a été supprimée dans MySQL 5.1.23.

fantaisie
la source
7
Avez-vous un exemple de syntaxe? Je ne connais aucun moyen d'utiliser alter databasepour renommer la base de données elle-même, et la documentation à laquelle vous avez lié ne suggère pas que c'est possible.
Jordan
@Jordan Je serais également intéressé. J'ai essayé et essayé et découvert que cela ne fonctionne qu'avec la version> 5.1 mais je ne peux pas mettre à jour pour le moment.
fancyPants
5
-1: Pour écrire sur les voies proposées, puis donner un exemple de la voie non proposée tout en manquant totalement pour montrer l'exemple.
hakre
3
C'est faux. La documentation MySQL rename database indique que rename_database était destiné à une tâche de changement de nom très spécifique (pas un cas général de changement de nom de base de données), qui est désormais gérée avec alter database: 'Pour effectuer la tâche de mise à niveau des noms de base de données avec le nouvel encodage, utilisez ALTER DATABASE db_name UPGRADE NOM DU RÉPERTOIRE DE DONNÉES à la place 'Vous ne pouvez pas l'utiliser pour renommer la base de données comme vous le souhaitez, il n'y a même pas de place pour le nouveau nom de base de données dans cette commande!
Kanat Bolazar
3

Dans l'administrateur MySQL, procédez comme suit:

  1. Sous Catalogues, créez un nouveau schéma de base de données.
  2. Accédez à Sauvegarde et créez une sauvegarde de l'ancien schéma.
  3. Exécutez la sauvegarde.
  4. Accédez à Restaurer et ouvrez le fichier créé à l'étape 3.
  5. Sélectionnez 'Another Schema' sous Target Schema et sélectionnez le nouveau schéma de base de données.
  6. Démarrez la restauration.
  7. Vérifiez le nouveau schéma et, s'il semble bon, supprimez l'ancien.
À M
la source
L'administrateur MySQL ne peut pas gérer les grandes bases de données et il n'y a rien de rapide à ce sujet
deadprogrammer
3

dans phpmyadmin, vous pouvez facilement renommer la base de données

select database 

  goto operations tab

  in that rename Database to :

  type your new database name and click go

demander de supprimer l'ancienne table et de recharger les données de la table, cliquez sur OK dans les deux

Votre base de données est renommée

murtaza.webdev
la source
3

Si vous utilisez phpMyAdmin, vous pouvez accéder à l'onglet "opérations" une fois que vous avez sélectionné la base de données que vous souhaitez renommer. Ensuite, allez dans la dernière section "copier la base de données vers" (ou quelque chose comme ça), donnez un nom et sélectionnez les options ci-dessous. Dans ce cas, je suppose que vous devez cocher les cases "structure et données" et "créer une base de données avant de copier" et, enfin, appuyer sur le bouton "aller" dans cette section.

Soit dit en passant, j'utilise phpMyAdmin en espagnol, donc je ne suis pas sûr du nom des sections en anglais.

Peter Mortensen
la source