Come rinominare rapidamente un database MySQL (cambiare il nome dello schema)?


959

Il manuale di MySQL su MySQL tratta questo.

Di solito ho appena scaricato il database e reimportato con un nuovo nome. Questa non è un'opzione per database molto grandi. ApparentementeRENAME {DATABASE | SCHEMA} db_name TO new_db_name; fa cose cattive, esiste solo in una manciata di versioni ed è una cattiva idea nel complesso .

Questo deve funzionare con InnoDB , che memorizza le cose in modo molto diverso da MyISAM .



5
Questa affermazione RENAME DATABASE Sintassi è stata aggiunta in MySQL 5.1.7 ma è risultata pericolosa ed è stata rimossa in MySQL 5.1.23.
zloctb,

11
Eventualmente MySQL implementerà una nuova RENAME DATABASEaffermazione funzionante che non presenta alcun pericolo, poiché al momento non esiste un modo semplice per eseguire questa operazione. Non vi è alcuna ragione ovvia per cui fosse pericoloso nella documentazione, quindi dovrebbero essere in grado di effettuare una sostituzione. Almeno le persone hanno inserito bug di richiesta di funzionalità sul proprio sito Web. Ad esempio, bugs.mysql.com/bug.php?id=58593 e bugs.mysql.com/bug.php?id=1698 .
Edward,

i collegamenti ora sono interrotti ...
oldboy

Risposte:


833

Per InnoDB , sembra funzionare quanto segue: creare il nuovo database vuoto, quindi rinominare ciascuna tabella a turno nel nuovo database:

RENAME TABLE old_db.table TO new_db.table;

Successivamente dovrai modificare le autorizzazioni.

Per gli script in una shell, è possibile utilizzare uno dei seguenti:

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;

Appunti:

  • Non c'è spazio tra l'opzione -pe la password. Se il database non ha password, rimuovere la -u username -ppasswordparte.
  • Se una tabella ha un trigger, non può essere spostata in un altro database utilizzando il metodo sopra (si verificherà un Trigger in wrong schemaerrore). In tal caso, utilizzare un modo tradizionale per clonare un database e quindi eliminare quello precedente:

    mysqldump old_db | mysql new_db

  • Se sono state memorizzate procedure, è possibile copiarle in seguito:

    mysqldump -R old_db | mysql new_db


26
L'ho appena fatto con un database InnoDB con oltre 30 tabelle, utilizzando l'impostazione file_per_table e anche se alcune tabelle erano 3+ milioni di righe, è stata completata in <1 secondo. Sembra solo spostare i file nella memoria, piuttosto che fare qualcosa di più complicato ... +2 se possibile :)
Dave Rix,

87
"RENAME DATABASE è stato ritenuto pericoloso ed è stato rimosso in MySQL 5.1.23" - da dev.mysql.com/doc/refman/5.1/en/rename-database.html
Palani

13
Si noti che questo non funzionerà per le viste. Non è possibile rinominare le viste per farle saltare da un database a un altro. Usa DROP VIEWe CREATE VIEWinvece. Goffo, sì. Potresti voler fare un mysqldumpper spostare le viste, dopo aver prima spostato tutte le tabelle. Si noti inoltre che SHOW TABLESmostrerà tabelle e viste, quindi attenzione.
tuomassalo,

9
Inoltre, questo non funzionerà per nessuna tabella con trigger. È necessario trovare, scaricare e rilasciare i trigger prima di spostare la tabella, quindi importare i trigger scaricati nel db di destinazione.
Olfan,

5
Link aggiornato (cioè funzionante) che documenta il perché RENAME DATABASE rimozione: dev.mysql.com/worklog/task/?id=4030
alexis

443

Usa questi pochi semplici comandi:

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

O per ridurre l'I / O, utilizzare quanto segue come suggerito da @Pablo Marin-Garcia:

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

86
Come ha detto l'OP, "[t] non è un'opzione per database molto grandi".
Pilcrow

3
Non dimenticare di DROP il database originale
Pavel Radzivilovsky,

3
Risposta brillante! Un paio di suggerimenti per migliorare ulteriormente in quanto questo è probabilmente googled da tutte le abilità: (1) Sposta il frammento di codice di Pablo Marin-Garcia in alto poiché sembra la risposta migliore (2) Metti -p<password>invece che -povunque, quindi le istruzioni vengono eseguite senza che venga visualizzato un prompt .
Steve Chambers,

9
Usando la versione piped ottengo due prompt "Enter password:" in questo modo: Enter password: Enter password: sembra prendere una password, ma non entrambe. Mi manca un dettaglio?
Ryan,

33
Sono sorpreso che nessuno l'abbia menzionato, ma dovresti davvero aggiungere la --routinesbandiera anche ai comandi mysqldump, per assicurarti che le procedure memorizzate vengano copiate.
Carlos P,

205

Penso che la soluzione sia più semplice ed è stata suggerita da alcuni sviluppatori. phpMyAdmin ha un'operazione per questo.

Da phpMyAdmin, selezionare il database che si desidera selezionare. Nelle schede c'è una chiamata Operazioni, vai alla sezione Rinomina. È tutto.

Come molti hanno suggerito, crea un nuovo database con il nuovo nome, scarica tutte le tabelle del vecchio database nel nuovo database e rilascia il vecchio database.

Inserisci qui la descrizione dell'immagine


76
Supponendo che tu abbia anche php nel tuo ambiente o usi phpmyadmin.
Chris,

26
Abbastanza pericoloso anche se si dispone di phpMyAdmin: il back-end potrebbe non riuscire a metà processo lasciando i due db in uno stato sconosciuto, oppure potrebbe richiedere molto tempo, portando alla sospensione del front-end o al timeout di PHP.
mozboz,

20
È vero @mozboz, ma l'ho fatto per 10 anni e non ho mai avuto questo problema. È lo stesso se si esegue il comando attraverso una shell e il computer si arresta in modo anomalo. C'è una possibilità ma cosa? 1 a 1 quadrilione?
raphie,

24
Uno script tramite console è anche un front-end che può bloccarsi con gli stessi problemi.
Greg,

11
Tuttavia, le operazioni della console sono molto più affidabili di PhpMyAdmin, specialmente quando sono coinvolti grandi database, come nel caso del PO. Personalmente suggerirei vivamente qualsiasi metodo console piuttosto che PMA se si dispone di un database abbastanza grande. Inutile dire che su piccoli database PMA è altrettanto buono.
Teodor Sandu,

107

È possibile utilizzare SQL per generare uno script SQL per trasferire ogni tabella nel database di origine nel database di destinazione.

È necessario creare il database di destinazione prima di eseguire lo script generato dal comando.

Puoi usare uno di questi due script (inizialmente avevo suggerito che il primo e qualcuno "migliorasse" la mia risposta da usare GROUP_CONCAT. Fai la tua scelta, ma preferisco l'originale):

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 e $ 2 sono rispettivamente sorgente e target)

Questo genererà un comando SQL che dovrai eseguire.

Si noti che GROUP_CONCATha un limite di lunghezza predefinito che può essere superato per i database con un numero elevato di tabelle. Puoi modificare quel limite eseguendo SET SESSION group_concat_max_len = 100000000;(o qualche altro numero grande).


@BlakeFrederick Non utilizza RENAME DATABASE, quindi qual è il problema?
tuxayo,

Funziona se la tabella ha vincoli referenziali? Non mi aspetto.
dolmen,

42

Emulazione del RENAME DATABASEcomando mancante in MySQL:

  1. Crea un nuovo database
  2. Crea le query di rinomina 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. Esegui quell'output

  4. Elimina il vecchio database

È stato preso dall'emulazione del comando RENAME DATABASE mancante in MySQL .


1
Perfetto! Ho provato questo con le tabelle InnoDB e MyISAM. La soluzione più veloce che ho provato (rinominare la tabella è quasi istantanea, nessun ritardo)!
Philipp,

Grande! Ricorda solo di fissare i privilegi in seguito.
Adam Faryna,

ps. Meglio farlo prima di eseguire le query di ridenominazione se si lavora su DB live.
Adam Faryna,

Funziona se la tabella ha vincoli referenziali? Non mi aspetto.
dolmen,

24

Tre opzioni:

  1. Creare il nuovo database, arrestare il server, spostare i file da una cartella di database all'altra e riavviare il server. Nota che funzionerà solo se TUTTE le tue tabelle sono MyISAM.

  2. Creare il nuovo database, utilizzare le istruzioni CREATE TABLE ... LIKE, quindi utilizzare le istruzioni INSERT ... SELECT * FROM.

  3. Usa mysqldump e ricarica con quel file.


+ per il riferimento myisam. Non riuscivo a capire perché questo non avesse funzionato per me.
Christian Payne,

5
La domanda afferma che questo deve funzionare per InnoDB, non per MyISAM
D-Rock,

@ D-Rock lo dico a Google, che porta qui le persone in base al titolo.
jiggunjer,

24

Il modo semplice

Passare alla directory del database:

cd /var/lib/mysql/

Chiudi MySQL ... Questo è importante!

/etc/init.d/mysql stop

Va bene, in questo modo non funziona con database InnoDB o BDB.

Rinomina database:

mv old-name new-name

... o il tavolo ...

cd database/

mv old-name.frm new-name.frm

mv old-name.MYD new-name.MYD

mv old-name.MYI new-name.MYI

Riavvia MySQL

/etc/init.d/mysql start

Fatto...

OK, in questo modo non funziona con i database InnoDB o BDB. In questo caso, è necessario scaricare il database e reimportarlo.


16
Rinominare le cartelle rompe i giocattoli.
ViniciusPires

1
@Rahly, anche se è impostato un file per tabella, è ancora pericoloso, le tabelle create prima dell'impostazione di un file per tabella saranno in difficoltà, a meno che non si sappia per certo che il database viene creato dopo l'impostazione di quel flag.
Qian Chen,

In generale, però, la maggior parte delle persone avrà i propri sistemi in un modo o nell'altro, le persone non si faranno casualmente capovolgere sull'avere o meno una tabella per file. Inoltre, anche nel tuo scenario, se le tabelle fossero state create prima della bandiera, non esisterebbero come file separati in primo luogo, quindi la mossa non funzionerebbe ed è ancora sicura, nessun pericolo. Ricordare che il database NON è in esecuzione quando si sta eseguendo lo spostamento.
Rahly,

L'equivalente per mysql installato con homebrew su 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

Puoi usare questo script di shell:

Riferimento: come rinominare un database 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"

Sta funzionando:

$ sh rename_database.sh oldname newname

6
Attento a questo. Se non esegui l'accesso con l'utente root, potresti avere autorizzazioni limitate. Causare la ridenominazione non riesce ma la caduta ha esito positivo con conseguente eliminazione del database. Bella sceneggiatura altrimenti.
Lex

3
Ho aggiunto set -eall'inizio dello script, che causerà l'interruzione dell'esecuzione in caso di errore e dovrebbe mitigare quel problema.
Mikkel,

19

Solo recentemente ho trovato un modo molto carino per farlo, funziona con MyISAM e InnoDB ed è molto veloce:

RENAME TABLE old_db.table TO new_db.table;

Non ricordo dove l'ho letto, ma il merito va a qualcun altro, non a me.


@ArkadijKuzhel non la pensa così. Penso che tu stia parlando di RENAME DATABASE.
Rob Grant,

Questo mi ha davvero aiutato, ho creato un nuovo database vuoto e quindi ho usato il codice, tutte le tabelle sono state importate con i nomi desiderati.
LuglioOrdinario,

3
Questo soffre dello stesso problema della risposta accettata - "RENAME DATABASE è stato trovato pericoloso ed è stato rimosso in MySQL 5.1.23" - da dev.mysql.com/doc/refman/5.1/en/rename-database.html
Blake Frederick,

16

Il modo più semplice ea prova di proiettile di fare una ridenominazione completa (inclusa la cancellazione del vecchio database alla fine, quindi è una ridenominazione piuttosto che una copia) :

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

passi:

  1. Copia le righe nel Blocco note.
  2. Sostituisci tutti i riferimenti a "olddbname", "newdbname", "mypassword" (+ facoltativamente "root") con i tuoi equivalenti.
  3. Eseguire uno per uno sulla riga di comando (immettendo "y" quando richiesto).

Evita di aggiungere la password alla console poiché non è sicura. Se lo hai già fatto, usa la cronologia -cw per rimuoverlo. Lascia invece vuota la password e inseriscila dopo il prompt.
Tommie C.,

Ci vuole un tempo insolitamente lungo, più di 20 minuti senza finire. Va bene cancellare?
Sigu Magwa,

15

Questo è quello che 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;

14
Non fattibile per enormi database.
mikesl,

14

MySQL al momento non supporta la ridenominazione di un database attraverso la sua interfaccia di comando, ma puoi rinominare il database se hai accesso alla directory in cui MySQL memorizza i suoi database. Per le installazioni predefinite di MySQL, ciò si trova di solito nella directory Data nella directory in cui è stato installato MySQL. Individua il nome del database che desideri rinominare nella directory Dati e rinominalo. Rinominare la directory potrebbe causare alcuni problemi di autorizzazione. Sii consapevole.

Nota: è necessario arrestare MySQL prima di poter rinominare il database

Consiglierei di creare un nuovo database (usando il nome desiderato) ed esportare / importare i dati necessari dal vecchio al nuovo. Abbastanza semplice.


13

Quando si rinomina un database in PHPMyAdmin, questo crea un dump, quindi rilascia e ricrea il database con il nuovo nome.


4
Si noti che questa funzione è un po 'nascosta nella scheda "Operazioni", quando si fa clic sul database.
Maris B.

13

Bene ci sono 2 metodi:

Metodo 1: un metodo ben noto per rinominare lo schema del database consiste nello scaricare lo schema usando Mysqldump e ripristinarlo in un altro schema, quindi rilasciare il vecchio schema (se necessario).

Da Shell

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

Sebbene il metodo sopra descritto sia semplice, richiede tempo e spazio. Cosa succede se lo schema supera i 100 GB?Esistono metodi in cui è possibile reindirizzare i comandi precedenti per risparmiare spazio, tuttavia non si risparmia tempo.

Per porre rimedio a tali situazioni, esiste un altro metodo rapido per rinominare gli schemi, tuttavia è necessario prestare attenzione mentre lo si fa.

Metodo 2: MySQL ha un'ottima funzionalità per rinominare le tabelle che funziona anche su schemi diversi. Questa operazione di ridenominazione è atomica e nessun altro può accedere alla tabella mentre viene rinominato. Questa operazione richiede poco tempo poiché la modifica del nome di una tabella o del suo schema è solo una modifica dei metadati. Ecco un approccio procedurale nel fare la ridenominazione:

Creare il nuovo schema del database con il nome desiderato. Rinomina le tabelle dal vecchio schema al nuovo schema, usando il comando "RENAME TABLE" di MySQL. Elimina il vecchio schema del database. If there are views, triggers, functions, stored procedures in the schema, those will need to be recreated too. "RENAME TABLE" di MySQL ha esito negativo se sono presenti trigger nelle tabelle. Per porre rimedio a ciò possiamo fare le seguenti cose:

1) Dump the triggers, events and stored routines in a separate file. Questo è stato fatto usando i flag -E, -R (oltre a -t -d che scarica i trigger) al comando mysqldump. Una volta scaricati i trigger, dovremo eliminarli dallo schema, affinché il comando RENAME TABLE funzioni.

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

2) Generare un elenco di sole tabelle "BASE". Questi possono essere trovati usando una query sulla information_schema.TABLEStabella.

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

3) Scarica le viste in un file di uscita. Le viste possono essere trovate usando una query sulla stessa information_schema.TABLEStabella.

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) Rilascia i trigger sulle tabelle correnti in old_schema.

mysql> DROP TRIGGER <trigger_name>;
...

5) Ripristinare i file di dump di cui sopra dopo aver rinominato tutte le tabelle "Base" trovate nel passaggio 2.

mysql> RENAME TABLE <old_schema>.table_name TO <new_schema>.table_name;
...
$ mysql <new_schema> < views.out
$ mysql <new_schema> < stored_routines_triggers_events.out

Intrecci con i metodi di cui sopra: potrebbe essere necessario aggiornare i GRANTS per gli utenti in modo che corrispondano al nome_schema corretto. Questi potrebbero essere risolti con un semplice AGGIORNAMENTO sulle tabelle mysql.columns_priv, mysql.procs_priv, mysql.tables_priv, mysql.db aggiornando il nome old_schema in new_schema e chiamando "Flush privileges;". Anche se il "metodo 2" sembra un po 'più complicato del "metodo 1", questo è totalmente programmabile. Un semplice script bash per eseguire i passaggi precedenti nella sequenza corretta, può aiutarti a risparmiare spazio e tempo durante la ridenominazione degli schemi di database la prossima volta.

Il team DBA di Percona Remote ha scritto uno script chiamato "rename_db" che funziona nel modo seguente:

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

Per dimostrare l'uso di questo script, è stato utilizzato uno schema di esempio "emp", creato trigger di test, routine memorizzate su quello schema. Tenterà di rinominare lo schema del database utilizzando lo script, che richiede alcuni secondi per il completamento rispetto al metodo di dump / ripristino che richiede tempo.

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

Come puoi vedere nell'output sopra, lo schema del database "emp" è stato rinominato in "emp_test" in meno di un secondo. Infine, questo è lo script di Percona che viene usato sopra per "metodo 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

Che dire dei vincoli referenziali?
dolmen,

13

Passaggi:

  1. Hit http: // localhost / phpmyadmin /
  2. Seleziona il tuo DB
  3. Fare clic sulla scheda Operazioni
  4. Ci sarà una scheda come "Rinomina database in". Aggiungi un nuovo nome e seleziona Regola privilegi.
  5. Clicca su Vai.

inserisci qui la descrizione dell'immagine


1
Una soluzione phpMyAdmin è di solito una soluzione scadente poiché alcuni ambienti hanno un ambiente limitato.
Daniel Antunes Pinto,

Non è una "buona" soluzione, ma grazie comunque perché era quello che stavo cercando.
Jamie,

1
Si prega di votare se funziona per te .. ti aiuterà .. grazie
Shubham Jain,

1
Questo funziona per me, nell'ambiente phpMyAdmin, +1
William

12

Per coloro che sono utenti Mac, Sequel Pro ha un'opzione Rinomina database nel menu Database. http://www.sequelpro.com/


5
Fai attenzione a questa opzione se hai viste o trigger nel tuo database. Dietro questa opzione di menu è presente uno script che crea un nuovo database e sposta tutte le tabelle. Questo non funzionerà per le viste o i trigger, quindi verranno lasciati indietro nel vecchio database. Il risultato sono due database rotti che devono essere riparati.
Olfan,

10

La maggior parte delle risposte qui sono errate per uno dei due motivi:

  1. Non puoi semplicemente usare RENAME TABLE, perché potrebbero esserci visualizzazioni e trigger. Se sono presenti trigger, RENAME TABLE ha esito negativo
  2. Non puoi usare mysqldump se vuoi "rapidamente" (come richiesto nella domanda) rinominare un grande database

Percona ha un post sul blog su come farlo bene: https://www.percona.com/blog/2013/12/24/renaming-database-schema-mysql/

e la sceneggiatura pubblicata (realizzata?) da Simon R Jones che fa ciò che viene suggerito in quel post. Ho corretto un bug che ho trovato nello script. Potete vederlo qui:

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

Eccone una copia:

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

Salvalo in un file chiamato rename_dbe rendi eseguibile lo script, chmod +x rename_dbquindi usalo come./rename_db localhost old_db new_db


Mi piace questa sceneggiatura, è quasi universale. Tuttavia, non è stato possibile elaborare un caso in cui vi sono diverse VISUALIZZAZIONI concatenate in cui definer non è root.
ENargit,

9

È possibile rinominare tutte le tabelle all'interno di un database in modo che si trovino in un altro database senza dover eseguire un dump e un ripristino completi.

PROCEDURA DROP SE ESISTE mysql.rename_db;
DELIMITATORE ||
CREATE PROCEDURE mysql.rename_db (IN old_db VARCHAR (100), IN new_db VARCHAR (100))
INIZIO
SELECT CONCAT ('CREATE DATABASE', new_db, ';') `# crea nuovo database`;
SELEZIONA CONCAT ('RENAME TABLE' ', old_db,' `.` ', table_name,' 'TO`', new_db, '`.``, table_name,'`; ') `# alter table` FROM information_schema.tables DOVE table_schema = old_db;
SELEZIONA CONCAT ('DROP DATABASE `', old_db, '`;') `# drop old database`;
FINE ||
DELIMITATORE;

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

Tuttavia, qualsiasi trigger nel db target non sarà felice. Dovrai prima rilasciarli, quindi ricrearli dopo la ridenominazione.

mysql -uroot -e "chiama mysql.rename_db ('test', 'blah2');" | mysql -uroot
ERRORE 1435 (HY000) alla riga 4: trigger nello schema errato

piccola modifica che rende questo lavoro w / mysql 5.x mysql --batch-uroot -e "call mysql.rename_db('test', 'blah2');" | mysql -uroot Notate, dovete usare --batch per cambiare la formattazione in formattazione grezza che produce risultati con formattazione zero.
mikesl,

8

Ecco un file batch che ho scritto per automatizzarlo dalla riga di comando, ma per Windows / MS-DOS.

La sintassi è rename_mysqldb database newdatabase -u [utente] -p [password]

:: ***************************************************************************
:: FILE: RENAME_MYSQLDB.BAT
:: ***************************************************************************
:: DESCRIPTION
:: This is a Windows /MS-DOS batch file that automates renaming a MySQL database 
:: by using MySQLDump, MySQLAdmin, and MySQL to perform the required tasks.
:: The MySQL\bin folder needs to be in your environment path or the working directory.
::
:: WARNING: The script will delete the original database, but only if it successfully
:: created the new copy. However, read the disclaimer below before using.
::
:: DISCLAIMER
:: This script is provided without any express or implied warranties whatsoever.
:: The user must assume the risk of using the script.
::
:: You are free to use, modify, and distribute this script without exception.
:: ***************************************************************************

:INITIALIZE
@ECHO OFF
IF [%2]==[] GOTO HELP
IF [%3]==[] (SET RDB_ARGS=--user=root) ELSE (SET RDB_ARGS=%3 %4 %5 %6 %7 %8 %9)
SET RDB_OLDDB=%1
SET RDB_NEWDB=%2
SET RDB_DUMPFILE=%RDB_OLDDB%_dump.sql
GOTO START

:START
SET RDB_STEP=1
ECHO Dumping "%RDB_OLDDB%"...
mysqldump %RDB_ARGS% %RDB_OLDDB% > %RDB_DUMPFILE%
IF %ERRORLEVEL% NEQ 0 GOTO ERROR_ABORT
SET RDB_STEP=2
ECHO Creating database "%RDB_NEWDB%"...
mysqladmin %RDB_ARGS% create %RDB_NEWDB%
IF %ERRORLEVEL% NEQ 0 GOTO ERROR_ABORT
SET RDB_STEP=3
ECHO Loading dump into "%RDB_NEWDB%"...
mysql %RDB_ARGS% %RDB_NEWDB% < %RDB_DUMPFILE%
IF %ERRORLEVEL% NEQ 0 GOTO ERROR_ABORT
SET RDB_STEP=4
ECHO Dropping database "%RDB_OLDDB%"...
mysqladmin %RDB_ARGS% drop %RDB_OLDDB% --force
IF %ERRORLEVEL% NEQ 0 GOTO ERROR_ABORT
SET RDB_STEP=5
ECHO Deleting dump...
DEL %RDB_DUMPFILE%
IF %ERRORLEVEL% NEQ 0 GOTO ERROR_ABORT
ECHO Renamed database "%RDB_OLDDB%" to "%RDB_NEWDB%".
GOTO END

:ERROR_ABORT
IF %RDB_STEP% GEQ 3 mysqladmin %RDB_ARGS% drop %NEWDB% --force
IF %RDB_STEP% GEQ 1 IF EXIST %RDB_DUMPFILE% DEL %RDB_DUMPFILE%
ECHO Unable to rename database "%RDB_OLDDB%" to "%RDB_NEWDB%".
GOTO END

:HELP
ECHO Renames a MySQL database.
ECHO Usage: %0 database new_database [OPTIONS]
ECHO Options: Any valid options shared by MySQL, MySQLAdmin and MySQLDump.
ECHO          --user=root is used if no options are specified.
GOTO END    

:END
SET RDB_OLDDB=
SET RDB_NEWDB=
SET RDB_ARGS=
SET RDB_DUMP=
SET RDB_STEP=

7

La procedura memorizzata di TodoInTX non ha funzionato abbastanza per me. Ecco la mia pugnalata:

- stored procedure rename_db: rinominare un database come mezzo per copiare la tabella.
- Avvertenze: 
- Bloccerà qualsiasi database esistente con lo stesso nome del "nuovo" nome del database.
- Copia SOLO le tabelle; le stored procedure e altri oggetti del database non vengono copiati.
- Tomer Altman (taltman@ai.sri.com)

delimitatore //
PROCEDURA DROP SE ESISTE rename_db;
CREATE PROCEDURE rename_db (IN old_db VARCHAR (100), IN new_db VARCHAR (100))
INIZIO
    DECLARE current_table VARCHAR (100);
    DECLARE fatto INT DEFAULT 0;
    DECLARE old_tables CURSORE PER selezionare table_name da information_schema.tables dove table_schema = old_db;
    DICHIARA CONTINUA HANDLER PER SET NON TROVATO fatto = 1;

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

    SET @output = CONCAT ('CREATE SCHEMA SE NON ESISTE', new_db, ';');
    PREPARE stmt FROM @output;
    EXECUTE stmt;

    OPEN old_tables;
    RIPETERE
        FETCH old_tables INTO current_table;
        SE NON fatto POI
        SET @output = CONCAT ('alter table', old_db, '.', Current_table, 'rename', new_db, '.', Current_table, ';');
        PREPARE stmt FROM @output;
        EXECUTE stmt;

        FINISCI SE;
    FINO A FINE RIPETIZIONE;

    CHIUDI old_tables;

FINE//
delimitatore;

Funzionerà solo per le tabelle e solo se queste tabelle non hanno trigger. Le viste e i trigger non verranno spostati da questo.
Olfan,

7

Il metodo più semplice è utilizzare il software HeidiSQL. È gratuito e open source. Funziona su Windows e su qualsiasi Linux con Wine (esegui applicazioni Windows su Linux, BSD, Solaris e Mac OS X).

Per scaricare HeidiSQL, vai a http://www.heidisql.com/download.php .

Per scaricare Wine, vai a http://www.winehq.org/ .

Per rinominare un database in HeidiSQL, basta fare clic destro sul nome del database e selezionare 'Modifica'. Quindi inserire un nuovo nome e premere 'OK'.

È così semplice


1
Se ha stored procedure, non può essere rinominato.
abksharma,

@abksharma In realtà riceverai un messaggio I Database "database_name" contains stored routine(s) which cannot be moved.trigger (almeno per il database MariDB) vengono conteggiati come routine memorizzate. Non avevo alcuna stored procedure, ma non ero in grado di rinominare il database fino a quando non ho eliminato tutti i trigger.
izogfif,

7

Per gli utenti Mac, è possibile utilizzare Sequel Pro(gratuitamente), che fornisce solo l'opzione per rinominare i database. Sebbene non elimini il vecchio DB.

una volta aperto il relativo DB è sufficiente fare clic su: Database->Rename database...


A volte lascia in vita il vecchio DB ma è vuoto. Tuttavia, se ne fa una copia, puoi fare la copia ed eliminare quella vecchia, sono ancora 2 semplici passaggi.
Roee Gavirel,

6

Ho posto una domanda su Server Fault cercando di evitare i tempi di inattività durante il ripristino di database di grandi dimensioni utilizzando MySQL Proxy. Non ho avuto alcun successo, ma alla fine ho capito che cosa volevo era la funzionalità RENAME DATABASE perché il dump / import non era un'opzione a causa delle dimensioni del nostro database.

Esiste una funzionalità RENAME TABLE integrata in MySQL, quindi ho finito per scrivere un semplice script Python per fare il lavoro per me. L'ho pubblicato su GitHub nel caso in cui potesse essere utile ad altri.



2
RENAME DATABASE è stato eliminato dalla sintassi, non RENAME TABLE.
Duca il

6

Per comodità, di seguito è riportato un piccolo shellscript che deve essere eseguito con due parametri: nome-db e nuovo nome-db.

Potrebbe essere necessario aggiungere parametri di accesso alle righe mysql se non si utilizza il file .my.cnf nella directory home. Effettuare un backup prima di eseguire questo 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"

1
Anche questo non funzionerà per le tabelle con trigger collegati o per le viste che non possono essere rinominate in altri database.
Olfan,

6

Sembra che nessuno ne abbia parlato, ma ecco un altro modo:

create database NewDatabaseName like OldDatabaseName;

quindi per ogni tabella fare:

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

quindi, se vuoi,

drop database OldDatabaseName;

Questo approccio avrebbe il vantaggio di eseguire l'intero trasferimento su server con traffico di rete pressoché nullo, quindi andrà molto più veloce di un dump / ripristino.

Se si dispone di stored procedure / viste / ecc., È possibile che si desideri trasferire anche queste.


2
Per quanto ne so 5.x non supporta la parola chiave "like" nell'istruzione create database? Da dove l'hai preso?
Dragas,

Ecco il link per la create table likesintassi: dev.mysql.com/doc/refman/5.7/en/create-table-like.html . Per quanto riguarda la creazione di database come, sembra che MySQL abbia abbandonato quella clausola da allora.
Tuncay Göncüoğlu,

4

Ecco un modo rapido per generare rinominare lo script sql, se hai molte tabelle da spostare.

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

Sembra buono, ma questo non sposta le stored procedure o le visualizzazioni.
davidpricedev,

dovresti probabilmente aggiungere degli hash mark per racchiudere il nome della tabella e il nome dello schema
Funkodebat

4

ALTER DATABASEè il modo proposto per aggirare questo da MySQL e RENAME DATABASEviene eliminato.

Dalla 13.1.32 Sintassi DATABASE RENAME :

RENAME {DATABASE | SCHEMA} db_name TO new_db_name;

Questa affermazione è stata aggiunta in MySQL 5.1.7, ma è risultata pericolosa ed è stata rimossa in MySQL 5.1.23.


7
Hai qualche sintassi di esempio? Non conosco alcun modo per utilizzare alter databaseper rinominare il database stesso e la documentazione a cui ti sei collegato non suggerisce che sia possibile.
Giordania,

@Jordan Anche io sarei interessato. Ho provato e provato e ho scoperto che funziona solo con la versione> 5.1 ma non riesco ad aggiornare in questo momento.
fancyPants

5
-1: per scrivere sui modi proposti, quindi dare un esempio del modo non proposto mentre manca del tutto per mostrare anche l'esempio.
Hakre,

3
Questo è sbagliato. La documentazione del database di rinomina di MySQL afferma che rename_database era destinato a un'attività di ridenominazione molto specifica (non un caso generale di ridenominazione di DB), che ora viene gestito con alter database: 'Per eseguire l'attività di aggiornamento dei nomi di database con la nuova codifica, utilizzare ALTER DATABASE db_name UPGRADE DATA DIRECTORY NAME invece 'Non puoi usarlo per rinominare il database come desideri, non c'è nemmeno posto per il nuovo nome db in questo comando!
Kanat Bolazar,

3

In MySQL Administrator procedi come segue:

  1. In Cataloghi, creare un nuovo schema di database.
  2. Vai a Backup e crea un backup del vecchio schema.
  3. Eseguire il backup.
  4. Vai a Ripristina e apri il file creato nel passaggio 3.
  5. Selezionare "Un altro schema" in Schema di destinazione e selezionare il nuovo schema del database.
  6. Inizia il ripristino.
  7. Verifica il nuovo schema e, se sembra buono, elimina quello vecchio.

L'amministratore di MySQL non è in grado di gestire database di grandi dimensioni e non c'è nulla di rapido al riguardo
deadprogrammer,

3

in phpmyadmin puoi facilmente rinominare il database

select database 

  goto operations tab

  in that rename Database to :

  type your new database name and click go

chiedere di eliminare la vecchia tabella e ricaricare i dati della tabella fare clic su OK in entrambi

Il tuo database è stato rinominato


3

Se stai usando phpMyAdmin è possibile accedere alla scheda "Operazioni" dopo aver selezionato il database che si desidera rinominare. Quindi vai all'ultima sezione "copia database" (o qualcosa del genere), dai un nome e seleziona le opzioni di seguito. In questo caso, suppongo che tu debba selezionare le caselle di controllo "struttura e dati" e "crea database prima di copiare" e, infine, premi il pulsante "vai" in quella sezione.

A proposito, sto usando phpMyAdmin in spagnolo, quindi non sono sicuro di come i nomi delle sezioni siano in inglese.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.