Nun, es gibt 2 Methoden:
Methode 1: Eine bekannte Methode zum Umbenennen des Datenbankschemas besteht darin, das Schema mit Mysqldump zu sichern, es in einem anderen Schema wiederherzustellen und dann das alte Schema zu löschen (falls erforderlich).
Von Shell
mysqldump emp > emp.out
mysql -e "CREATE DATABASE employees;"
mysql employees < emp.out
mysql -e "DROP DATABASE emp;"
Obwohl die obige Methode einfach ist, ist sie zeit- und platzaufwendig. Was ist, wenn das Schema mehr als 100 GB umfasst?Es gibt Methoden, mit denen Sie die oben genannten Befehle zusammenfügen können, um Platz zu sparen. Dies spart jedoch keine Zeit.
Um solche Situationen zu beheben, gibt es eine andere schnelle Methode zum Umbenennen von Schemas. Dabei muss jedoch einige Sorgfalt angewendet werden.
Methode 2: MySQL bietet eine sehr gute Funktion zum Umbenennen von Tabellen, die sogar in verschiedenen Schemas funktioniert. Diese Umbenennungsoperation ist atomar und niemand anderes kann auf die Tabelle zugreifen, während sie umbenannt wird. Dies dauert nur kurze Zeit, da das Ändern des Namens oder des Schemas einer Tabelle nur eine Änderung der Metadaten ist. Hier ist ein prozeduraler Ansatz beim Umbenennen:
Erstellen Sie das neue Datenbankschema mit dem gewünschten Namen. Benennen Sie die Tabellen mit dem MySQL-Befehl "RENAME TABLE" vom alten in das neue Schema um. Löschen Sie das alte Datenbankschema.
If there are views, triggers, functions, stored procedures in the schema, those will need to be recreated too
. MySQLs "RENAME TABLE" schlägt fehl, wenn Trigger in den Tabellen vorhanden sind. Um dies zu beheben, können wir folgende Dinge tun:
1) Dump the triggers, events and stored routines in a separate file.
Dies erfolgt mit -E, -R-Flags (zusätzlich zu -t -d, das die Trigger ausgibt) für den Befehl mysqldump. Sobald die Trigger ausgegeben wurden, müssen sie aus dem Schema entfernt werden, damit der Befehl RENAME TABLE funktioniert.
$ mysqldump <old_schema_name> -d -t -R -E > stored_routines_triggers_events.out
2) Erstellen Sie eine Liste mit nur "BASE" -Tabellen. Diese können mithilfe einer Abfrage in der information_schema.TABLES
Tabelle gefunden werden.
mysql> select TABLE_NAME from information_schema.tables where
table_schema='<old_schema_name>' and TABLE_TYPE='BASE TABLE';
3) Speichern Sie die Ansichten in einer Out-Datei. Ansichten können mithilfe einer Abfrage in derselben information_schema.TABLES
Tabelle gefunden werden.
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) Löschen Sie die Trigger in den aktuellen Tabellen im old_schema.
mysql> DROP TRIGGER <trigger_name>;
...
5) Stellen Sie die obigen Speicherauszugsdateien wieder her, sobald alle in Schritt 2 gefundenen "Basistabellen" umbenannt wurden.
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
Komplikationen mit den oben genannten Methoden: Möglicherweise müssen wir die GRANTS für Benutzer so aktualisieren, dass sie mit dem richtigen Schemanamen übereinstimmen. Diese können mit einem einfachen UPDATE für die Tabellen mysql.columns_priv, mysql.procs_priv, mysql.tables_priv und mysql.db behoben werden, indem der Name des alten Schemas auf new_schema aktualisiert und "Flush privileges;" aufgerufen wird. Obwohl "Methode 2" etwas komplizierter erscheint als "Methode 1", ist dies vollständig skriptfähig. Ein einfaches Bash-Skript, mit dem Sie die oben genannten Schritte in der richtigen Reihenfolge ausführen können, kann Ihnen helfen, beim nächsten Umbenennen von Datenbankschemata Platz und Zeit zu sparen.
Das Percona Remote DBA-Team hat ein Skript namens "rename_db" geschrieben, das folgendermaßen funktioniert:
[root@dba~]# /tmp/rename_db
rename_db <server> <database> <new_database>
Um die Verwendung dieses Skripts zu demonstrieren, wurde ein Beispielschema "emp" verwendet, Testauslöser erstellt und Routinen in diesem Schema gespeichert. Versucht, das Datenbankschema mithilfe des Skripts umzubenennen. Der Vorgang dauert einige Sekunden, im Gegensatz zur zeitaufwändigen Dump / Restore-Methode.
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 |
+--------------------+
Wie Sie in der obigen Ausgabe sehen können, wurde das Datenbankschema "emp" in weniger als einer Sekunde in "emp_test" umbenannt. Schließlich ist dies das Skript von Percona, das oben für "Methode 2" verwendet wird.
#!/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