Как быстро переименовать базу данных MySQL (изменить имя схемы)?

959

Руководство MySQL на MySQL покрывает это.

Обычно я просто выкидываю базу данных и импортирую ее с новым именем. Это не вариант для очень больших баз данных. По-видимому, RENAME {DATABASE | SCHEMA} db_name TO new_db_name; делает плохие вещи, существует только в нескольких версиях, и в целом это плохая идея .

Это должно работать с InnoDB , который хранит вещи совсем иначе, чем MyISAM .

Csaba
источник
3
Также на serverfault: serverfault.com/questions/195221/how-to-rename-a-mysql-database
Ив Мартин
5
Это утверждение RENAME DATABASE Syntax было добавлено в MySQL 5.1.7, но было признано опасным и было удалено в MySQL 5.1.23.
zloctb
11
Надеемся, что MySQL реализует новый рабочий RENAME DATABASEоператор, который не несет никаких опасностей, поскольку в настоящее время нет простого способа выполнить эту задачу. Нет очевидной причины, почему это было опасно в документации, поэтому они могли бы сделать замену. По крайней мере, люди размещают сообщения об ошибках на своем веб-сайте. Например, bugs.mysql.com/bug.php?id=58593 и bugs.mysql.com/bug.php?id=1698 .
Эдвард
ссылки теперь не работают ...
oldboy

Ответы:

833

Для InnoDB , кажется, работает следующее: создайте новую пустую базу данных, затем переименуйте каждую таблицу по очереди в новую базу данных:

RENAME TABLE old_db.table TO new_db.table;

Вам нужно будет настроить разрешения после этого.

Для сценариев в оболочке вы можете использовать одно из следующих:

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

ИЛИ

for table in `mysql -u root -ppassword -s -N -e "use old_db;show tables from old_db;"`; do mysql -u root -ppassword -s -N -e "use old_db;rename table old_db.$table to new_db.$table;"; done;

Ноты:

  • Между опцией -pи паролем нет пробела . Если в вашей базе данных нет пароля, удалите -u username -ppasswordдеталь.
  • Если у какой-либо таблицы есть триггер, ее нельзя переместить в другую базу данных с помощью вышеуказанного метода (приведет к Trigger in wrong schemaошибке). Если это так, используйте традиционный способ клонирования базы данных, а затем отбросьте старую:

    mysqldump old_db | mysql new_db

  • Если у вас есть хранимые процедуры, вы можете скопировать их впоследствии:

    mysqldump -R old_db | mysql new_db

Benoit Duffez
источник
26
Я только что сделал это с базой данных InnoDB с более чем 30 таблицами, используя настройку file_per_table, и хотя в некоторых таблицах было более 3 миллионов строк, это завершилось за <1 секунду. Просто кажется, что файлы перемещаются в хранилище, а не что-то более сложное ... +2, если это возможно :)
Дейв Рикс
87
«RENAME DATABASE был признан опасным и был удален в MySQL 5.1.23» - из dev.mysql.com/doc/refman/5.1/en/rename-database.html
Palani
13
Обратите внимание, что это не будет работать для просмотров. Вы не можете переименовать представления, чтобы заставить их переходить из базы данных в другую. Используйте DROP VIEWи CREATE VIEWвместо. Неуклюжий, да. Возможно, вы захотите сделать, mysqldumpчтобы переместить представления, после первого перемещения всех таблиц. Также обратите внимание, что SHOW TABLESбудут показаны таблицы и представления, так что будьте осторожны.
Туомассало
9
Также это не будет работать для любых таблиц с триггерами. Вам нужно найти, сбросить и удалить триггеры до перемещения таблицы, а затем импортировать сброшенные триггеры в целевую базу данных.
Олфан
5
Обновленная (т.е. рабочая) ссылка, документирующая, почему RENAME DATABASEбыла удалена: dev.mysql.com/worklog/task/?id=4030
alexis
443

Используйте эти несколько простых команд:

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

Или, чтобы уменьшить количество операций ввода / вывода, используйте следующее, предложенное @Pablo Marin-Garcia:

mysqladmin -u username -p create newdatabase
mysqldump -u username -v olddatabase -p | mysql -u username -p -D newdatabase
hendrasaputra
источник
86
Как сказал ОП, «это не вариант для очень больших баз данных».
Пилкроу
3
Не забудьте удалить оригинальную базу данных
Павел Радзивиловский
3
Блестящий ответ! Несколько предложений по дальнейшему улучшению, так как это, вероятно, гуглится всеми способностями: (1) Переместите фрагмент кода Пабло Марин-Гарсиа на верх, так как это кажется лучшим ответом (2) Поставьте -p<password>вместо -pвезде, чтобы операторы выполнялись без появления подсказки ,
Стив Чемберс
9
Используя версию по каналу, я получаю два запроса «Введите пароль:», например, так: Enter password: Enter password: кажется, что используется один пароль, но не оба. Я упускаю детали?
Райан
33
Я удивлен, что никто не упомянул об этом, но вы действительно должны добавить --routinesфлаг в команды mysqldump, чтобы гарантировать копирование хранимых процедур.
Карлос П
205

Я думаю, что решение проще и было предложено некоторыми разработчиками. У phpMyAdmin есть операция для этого.

В phpMyAdmin выберите базу данных, которую вы хотите выбрать. Во вкладках есть одна, которая называется Операции, перейдите в раздел переименования. Это все.

Он, как многие предлагали, создает новую базу данных с новым именем, сбрасывает все таблицы старой базы данных в новую базу данных и удаляет старую базу данных.

Введите описание изображения здесь

рафи
источник
76
Предполагая, что у вас даже есть php в вашей среде или вы используете phpmyadmin.
Крис
26
Довольно опасно, даже если у вас есть phpMyAdmin - сервер может потерпеть неудачу в середине процесса, оставив две базы данных в неизвестном состоянии, или это может занять очень много времени, что приведет к зависанию интерфейса или тайм-ауту PHP.
Мозбоз
20
Это правда @mozboz, но я делал это в течение 10 лет, и у меня никогда не было такой проблемы. То же самое, если вы запускаете команду через оболочку и ваш компьютер падает. Есть возможность, но что? От 1 до 1 квадриллиона?
Рафи
24
Скрипт через консоль также является внешним интерфейсом, который может зависать при тех же проблемах.
Грег
11
Тем не менее, консольные операции гораздо надежнее, чем PhpMyAdmin, особенно там, где задействованы большие базы данных, как в случае с OP. Лично я настоятельно рекомендую любой консольный метод, а не PMA, если у вас достаточно большая база данных. Излишне говорить, что для небольших баз данных PMA также хорош.
Теодор Санду
107

Вы можете использовать SQL для создания сценария SQL для передачи каждой таблицы в исходной базе данных в целевую базу данных.

Вы должны создать базу данных назначения перед запуском скрипта, сгенерированного из команды.

Вы можете использовать любой из этих двух сценариев (я изначально предложил первый, а кто-то «улучшил» мой ответ GROUP_CONCAT. Выберите, но я предпочитаю оригинал)

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

или

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

($ 1 и $ 2 - источник и цель соответственно)

Это сгенерирует команду SQL, которую вам нужно будет выполнить.

Обратите внимание, что GROUP_CONCATпо умолчанию установлен предел длины, который может быть превышен для баз данных с большим количеством таблиц. Вы можете изменить это ограничение, запустив SET SESSION group_concat_max_len = 100000000;(или другое большое число).

ErichBSchulz
источник
@BlakeFrederick Он не использует базу данных RENAME, так в чем же проблема?
Tuxayo
Это работает, если таблица имеет ссылочные ограничения? Я ожидаю, что нет.
дольмен
42

Эмуляция отсутствующей RENAME DATABASEкоманды в MySQL:

  1. Создать новую базу данных
  2. Создайте запросы на переименование с помощью:

    SELECT CONCAT('RENAME TABLE ',table_schema,'.',table_name,
        ' TO ','new_schema.',table_name,';')
    FROM information_schema.TABLES
    WHERE table_schema LIKE 'old_schema';
  3. Запустите этот вывод

  4. Удалить старую базу данных

Он был взят из эмуляции отсутствующей команды RENAME DATABASE в MySQL .

Marciano
источник
1
Отлично! Я проверил это с помощью таблиц InnoDB и MyISAM. Самое быстрое решение, которое я тестировал (переименование таблицы происходит практически мгновенно, без задержек)!
Филипп
Большой! Просто не забудьте исправить привилегии впоследствии.
Адам Фарина
пс. Лучше сделать это перед выполнением запросов на переименование, если вы работаете с работающей БД.
Адам Фарина
Это работает, если таблица имеет ссылочные ограничения? Я ожидаю, что нет.
дольмен
24

Три варианта:

  1. Создайте новую базу данных, выключите сервер, переместите файлы из одной папки базы данных в другую и перезапустите сервер. Обратите внимание, что это будет работать, только если ВСЕ ваши таблицы являются MyISAM.

  2. Создайте новую базу данных, используйте операторы CREATE TABLE ... LIKE, а затем используйте операторы INSERT ... SELECT * FROM.

  3. Используйте mysqldump и перезагрузите этот файл.

longneck
источник
+ для справки myisam. Я не мог понять, почему это не сработало для меня.
Кристиан Пейн
5
В вопросе говорится, что это должно работать для InnoDB, а не для MyISAM
D-Rock
@ D-Rock расскажет об этом Google, который привел сюда людей по названию.
jiggunjer
24

Простой способ

Перейдите в каталог базы данных:

cd /var/lib/mysql/

Выключите MySQL ... Это важно!

/etc/init.d/mysql stop

Хорошо, этот способ не работает для InnoDB или BDB-баз данных.

Переименовать базу данных:

mv old-name new-name

... или стол ...

cd database/

mv old-name.frm new-name.frm

mv old-name.MYD new-name.MYD

mv old-name.MYI new-name.MYI

Перезапустите MySQL

/etc/init.d/mysql start

Выполнено...

ОК, этот способ не работает с базами данных InnoDB или BDB. В этом случае вы должны сбросить базу данных и повторно импортировать ее.

DeeCee
источник
16
Переименование папок разбивает игрушки.
ViniciusPires
1
@Rahly, даже если для каждой таблицы задан один файл, это все равно опасно, таблицы, созданные до того, как был задан один файл на таблицу, будут иметь проблемы, если вы точно не знаете, что база данных создана после того, как был установлен этот флаг.
Цянь Чен
В целом, хотя большинство людей используют свои системы тем или иным способом, люди не будут случайно переключаться между тем, иметь или не иметь одну таблицу на файл. Кроме того, даже в вашем сценарии, если бы таблицы создавались до флага, они не существовали бы как отдельные файлы, поэтому перемещение не сработало бы и по-прежнему безопасно, без опасности. Помните, что база данных НЕ работает, когда происходит перемещение.
Рахли
Эквивалент для mysql, установленный с homebrew на 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

Вы можете использовать этот скрипт:

Справка: Как переименовать базу данных 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"

Работает:

$ sh rename_database.sh oldname newname
Grijesh Chauhan
источник
6
Осторожнее с этим. Если вы не входите в систему как пользователь root, у вас может быть ограниченное разрешение. Причинение переименования не удастся, но удачное завершение приведет к удалению базы данных. Хороший сценарий в противном случае.
Lex
3
Я добавил set -eв начало сценария, что приведет к прекращению выполнения при сбое и должно смягчить эту проблему.
Миккель,
19

Я только недавно нашел очень хороший способ сделать это, работает с MyISAM и InnoDB и работает очень быстро:

RENAME TABLE old_db.table TO new_db.table;

Я не помню, где я читал это, но заслуга идет кому-то еще, а не мне.

Амр Мостафа
источник
@ArkadijKuzhel так не думаю. Я думаю, что вы говорите о RENAME DATABASE.
Роб Грант
Это действительно помогло, я создал новую пустую базу данных, а затем использовал код, все таблицы были импортированы с нужными именами.
ИюльОрдинарное
3
Это страдает от той же проблемы, что и принятый ответ - «RENAME DATABASE был признан опасным и был удален в MySQL 5.1.23» - из dev.mysql.com/doc/refman/5.1/en/rename-database.html
Блейк Фредерик
16

Самый простой способ сделать полное переименование безошибочным (включая удаление старой базы данных в конце, так что это переименование, а не копия) :

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

шаги:

  1. Скопируйте строки в блокнот.
  2. Замените все ссылки на "olddbname", "newdbname", "mypassword" (+ опционально "root") вашими эквивалентами.
  3. Выполните один за другим в командной строке (введите «y» при появлении запроса).
Стив Чемберс
источник
Не добавляйте свой пароль в консоль, так как он небезопасен. Если вы уже сделали это, используйте для удаления историю -cw. Вместо этого оставьте пароль пустым и введите его после приглашения.
Томми С.
Это занимает ненормально долго, более 20 минут, не заканчивая. Это нормально отменить?
Сигу Магва
15

Это то, что я использую:

$ 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
источник
14
Не выполнимо для огромных баз данных.
Майкл
14

В настоящее время MySQL не поддерживает переименование базы данных через ее командный интерфейс, но вы можете переименовать базу данных, если у вас есть доступ к каталогу, в котором MySQL хранит свои базы данных. Для установок по умолчанию MySQL это обычно находится в каталоге данных в каталоге, где был установлен MySQL. Найдите в базе данных имя базы данных, которую вы хотите переименовать, и переименуйте ее. Переименование каталога может вызвать проблемы с разрешениями. Быть в курсе

Примечание: вы должны остановить MySQL, прежде чем вы сможете переименовать базу данных

Я бы порекомендовал создать новую базу данных (используя нужное имя) и экспортировать / импортировать нужные данные из старой в новую. Довольно просто

bryanpearson
источник
13

Когда вы переименовываете базу данных в PHPMyAdmin, она создает дамп, затем удаляет и заново создает базу данных с новым именем.

UnkwnTech
источник
4
Обратите внимание, что эта функция немного скрыта на вкладке «Операции», когда вы нажимаете на базу данных.
Марис Б.
13

Ну есть 2 метода:

Метод 1: Хорошо известный метод для переименования схемы базы данных - выгрузка схемы с использованием Mysqldump и восстановление ее в другой схеме, а затем удаление старой схемы (если необходимо).

Из оболочки

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

Хотя описанный выше метод прост, он требует много времени и пространства. Что делать, если схема больше 100 ГБ? Существуют методы, где вы можете объединить вышеперечисленные команды вместе, чтобы сэкономить место, однако это не сэкономит время.

Чтобы исправить такие ситуации, существует другой быстрый способ переименования схем, однако, при этом необходимо соблюдать осторожность.

Метод 2: MySQL имеет очень хорошую функцию для переименования таблиц, которая работает даже в разных схемах. Эта операция переименования является атомарной, и никто другой не может получить доступ к таблице во время ее переименования. Это займет короткое время, поскольку изменение имени таблицы или ее схемы - это только изменение метаданных. Вот процедурный подход к переименованию:

Создайте новую схему базы данных с нужным именем. Переименуйте таблицы из старой схемы в новую, используя команду MySQL «RENAME TABLE». Удалите старую схему базы данных. If there are views, triggers, functions, stored procedures in the schema, those will need to be recreated too, «RENAME TABLE» MySQL завершается ошибкой, если в таблицах существуют триггеры. Чтобы исправить это, мы можем сделать следующие вещи:

1) Dump the triggers, events and stored routines in a separate file. Это делается с помощью флагов -E, -R (в дополнение к -t -d, который выводит триггеры) в команду mysqldump. После сброса триггеров нам нужно будет удалить их из схемы, чтобы команда RENAME TABLE работала.

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

2) Сформировать список только «БАЗОВЫХ» таблиц. Их можно найти с помощью запроса к information_schema.TABLESтаблице.

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

3) Дамп представления в выходной файл. Представления могут быть найдены с помощью запроса к той же information_schema.TABLESтаблице.

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) Отбросьте триггеры на текущих таблицах в old_schema.

mysql> DROP TRIGGER <trigger_name>;
...

5) Восстановите вышеуказанные файлы дампа, как только все «базовые» таблицы, найденные на шаге №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

Сложности с вышеуказанными методами: нам может потребоваться обновить GRANTS для пользователей, чтобы они соответствовали правильному имени схемы. Они могут быть исправлены с помощью простого UPDATE для таблиц mysql.columns_priv, mysql.procs_priv, mysql.tables_priv, mysql.db, обновляющих имя old_schema до new_schema и вызывающих «Flush privileges;». Хотя «метод 2» кажется немного более сложным, чем «метод 1», он полностью подходит для сценариев. Простой скрипт bash для выполнения вышеуказанных шагов в правильной последовательности поможет сэкономить место и время при следующем переименовании схем базы данных.

Команда Percona Remote DBA написала сценарий «rename_db», который работает следующим образом:

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

Чтобы продемонстрировать использование этого скрипта, использовали образец схемы «emp», создали триггеры тестирования, сохранили подпрограммы в этой схеме. Попытается переименовать схему базы данных с помощью сценария, который занимает несколько секунд, в отличие от трудоемкого метода дампа / восстановления.

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| emp                |
| mysql              |
| performance_schema |
| test               |
+--------------------+


[root@dba ~]# time /tmp/rename_db localhost emp emp_test
create database emp_test DEFAULT CHARACTER SET latin1
drop trigger salary_trigger
rename table emp.__emp_new to emp_test.__emp_new
rename table emp._emp_new to emp_test._emp_new
rename table emp.departments to emp_test.departments
rename table emp.dept to emp_test.dept
rename table emp.dept_emp to emp_test.dept_emp
rename table emp.dept_manager to emp_test.dept_manager
rename table emp.emp to emp_test.emp
rename table emp.employees to emp_test.employees
rename table emp.salaries_temp to emp_test.salaries_temp
rename table emp.titles to emp_test.titles
loading views
loading triggers, routines and events
Dropping database emp

real    0m0.643s
user    0m0.053s
sys     0m0.131s


mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| emp_test           |
| mysql              |
| performance_schema |
| test               |
+--------------------+

Как видно из вышеприведенного вывода, схема базы данных «emp» была переименована в «emp_test» менее чем за секунду. Наконец, это скрипт из Percona, который используется выше для «метода 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
Сатиш Д
источник
А как насчет ссылочных ограничений?
дольмен
13

Шаги:

  1. Нажмите http: // localhost / phpmyadmin /
  2. Выберите свою БД
  3. Нажмите на вкладку Операции
  4. Там будет вкладка «Переименовать базу данных». Добавьте новое имя и установите флажок «Настроить привилегии».
  5. Нажмите на Go.

введите описание изображения здесь

Шубхам Джайн
источник
1
Решение phpMyAdmin обычно является плохим решением, поскольку некоторые среды имеют ограниченную среду.
Даниэль Антунес Пинто
Не «хорошее» решение, но, тем не менее, спасибо, это то, что я искал.
Jamie
1
Пожалуйста, проголосуйте, если это работает для вас .. это поможет .. спасибо
Shubham Jain
1
Это работает для меня, в среде phpMyAdmin, +1
Уильям
12

Для тех, кто является пользователями Mac, Sequel Pro имеет опцию Rename Database в меню Database. http://www.sequelpro.com/

герцог
источник
5
Остерегайтесь этой опции, если у вас есть какие-либо представления или триггеры в вашей базе данных. За этим пунктом меню находится скрипт, который создаст новую базу данных и переместит все таблицы. Это не будет работать для представлений или триггеров, поэтому они останутся в вашей старой базе данных. В результате две поврежденные базы данных нуждаются в исправлении.
Олфан
10

Большинство ответов здесь неверны по одной из двух причин:

  1. Вы не можете просто использовать RENAME TABLE, потому что могут быть представления и триггеры. Если есть триггеры, сбой RENAME TABLE
  2. Вы не можете использовать mysqldump, если хотите «быстро» (как это было задано в вопросе) переименовать большую базу данных

У Percona есть запись в блоге о том, как сделать это хорошо: https://www.percona.com/blog/2013/12/24/renaming-database-schema-mysql/

и сценарий, опубликованный (сделанный?) Саймоном Р. Джонсом, который делает то, что предлагается в этом посте. Я исправил ошибку, обнаруженную в скрипте. Вы можете видеть это здесь:

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

Вот копия этого:

#!/bin/bash
# Copyright 2013 Percona LLC and/or its affiliates
# @see https://www.percona.com/blog/2013/12/24/renaming-database-schema-mysql/
set -e
if [ -z "$3" ]; then
    echo "rename_db <server> <database> <new_database>"
    exit 1
fi
db_exists=`mysql -h $1 -e "show databases like '$3'" -sss`
if [ -n "$db_exists" ]; then
    echo "ERROR: New database already exists $3"
    exit 1
fi
TIMESTAMP=`date +%s`
character_set=`mysql -h $1 -e "SELECT default_character_set_name FROM information_schema.SCHEMATA WHERE schema_name = '$2'" -sss`
TABLES=`mysql -h $1 -e "select TABLE_NAME from information_schema.tables where table_schema='$2' and TABLE_TYPE='BASE TABLE'" -sss`
STATUS=$?
if [ "$STATUS" != 0 ] || [ -z "$TABLES" ]; then
    echo "Error retrieving tables from $2"
    exit 1
fi
echo "create database $3 DEFAULT CHARACTER SET $character_set"
mysql -h $1 -e "create database $3 DEFAULT CHARACTER SET $character_set"
TRIGGERS=`mysql -h $1 $2 -e "show triggers\G" | grep Trigger: | awk '{print $2}'`
VIEWS=`mysql -h $1 -e "select TABLE_NAME from information_schema.tables where table_schema='$2' and TABLE_TYPE='VIEW'" -sss`
if [ -n "$VIEWS" ]; then
    mysqldump -h $1 $2 $VIEWS > /tmp/${2}_views${TIMESTAMP}.dump
fi
mysqldump -h $1 $2 -d -t -R -E > /tmp/${2}_triggers${TIMESTAMP}.dump
for TRIGGER in $TRIGGERS; do
    echo "drop trigger $TRIGGER"
    mysql -h $1 $2 -e "drop trigger $TRIGGER"
done
for TABLE in $TABLES; do
    echo "rename table $2.$TABLE to $3.$TABLE"
    mysql -h $1 $2 -e "SET FOREIGN_KEY_CHECKS=0; rename table $2.$TABLE to $3.$TABLE"
done
if [ -n "$VIEWS" ]; then
    echo "loading views"
    mysql -h $1 $3 < /tmp/${2}_views${TIMESTAMP}.dump
fi
echo "loading triggers, routines and events"
mysql -h $1 $3 < /tmp/${2}_triggers${TIMESTAMP}.dump
TABLES=`mysql -h $1 -e "select TABLE_NAME from information_schema.tables where table_schema='$2' and TABLE_TYPE='BASE TABLE'" -sss`
if [ -z "$TABLES" ]; then
    echo "Dropping database $2"
    mysql -h $1 $2 -e "drop database $2"
fi
if [ `mysql -h $1 -e "select count(*) from mysql.columns_priv where db='$2'" -sss` -gt 0 ]; then
    COLUMNS_PRIV="    UPDATE mysql.columns_priv set db='$3' WHERE db='$2';"
fi
if [ `mysql -h $1 -e "select count(*) from mysql.procs_priv where db='$2'" -sss` -gt 0 ]; then
    PROCS_PRIV="    UPDATE mysql.procs_priv set db='$3' WHERE db='$2';"
fi
if [ `mysql -h $1 -e "select count(*) from mysql.tables_priv where db='$2'" -sss` -gt 0 ]; then
    TABLES_PRIV="    UPDATE mysql.tables_priv set db='$3' WHERE db='$2';"
fi
if [ `mysql -h $1 -e "select count(*) from mysql.db where db='$2'" -sss` -gt 0 ]; then
    DB_PRIV="    UPDATE mysql.db set db='$3' WHERE db='$2';"
fi
if [ -n "$COLUMNS_PRIV" ] || [ -n "$PROCS_PRIV" ] || [ -n "$TABLES_PRIV" ] || [ -n "$DB_PRIV" ]; then
    echo "IF YOU WANT TO RENAME the GRANTS YOU NEED TO RUN ALL OUTPUT BELOW:"
    if [ -n "$COLUMNS_PRIV" ]; then echo "$COLUMNS_PRIV"; fi
    if [ -n "$PROCS_PRIV" ]; then echo "$PROCS_PRIV"; fi
    if [ -n "$TABLES_PRIV" ]; then echo "$TABLES_PRIV"; fi
    if [ -n "$DB_PRIV" ]; then echo "$DB_PRIV"; fi
    echo "    flush privileges;"
fi

Сохраните его в файл с именем rename_dbи сделайте скрипт исполняемым, а chmod +x rename_dbзатем используйте его как./rename_db localhost old_db new_db

ryantm
источник
Мне нравится этот сценарий, он почти универсален. Однако он не смог обработать случай, когда есть несколько связанных видов, где определитель не является корневым.
ENargit
9

Можно переименовать все таблицы в базе данных, чтобы они были в другой базе данных без необходимости выполнять полный дамп и восстановление.

ПРОЦЕДУРА ОТМЕНЫ, ЕСЛИ СУЩЕСТВУЕТ mysql.rename_db;
РАЗДЕЛИТЕЛЬ ||
ПРОЦЕДУРА СОЗДАНИЯ mysql.rename_db (В VARCHAR old_db (100), В VARCHAR new_db (100))
НАЧАТЬ
SELECT CONCAT ('CREATE DATABASE', new_db, ';') `# создать новую базу данных`;
SELECT CONCAT ('RENAME TABLE `', old_db, '` .`', table_name, '`TO`', new_db, '`.`', table_name, '`;') `# изменить таблицу` FROM information_schema.tables WHERE table_schema = old_db;
SELECT CONCAT ('DROP DATABASE `', old_db, '`;') `# drop old database`;
END ||
РАЗДЕЛИТЕЛЬ;

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

Однако любые триггеры в целевой БД не будут счастливы. Сначала вам нужно будет удалить их, а затем переименовать.

mysql -uroot -e "call mysql.rename_db ('test', 'blah2');" | mysql -uroot
ОШИБКА 1435 (HY000) в строке 4: запуск в неверной схеме
TodoInTX
источник
Небольшая настройка, которая делает эту работу с MySQL 5.x mysql --batch-uroot -e "call mysql.rename_db('test', 'blah2');" | mysql -uroot Обратите внимание, вы должны использовать --batch, чтобы изменить форматирование на необработанное форматирование, которое выводит результаты с нулевым форматированием.
Майкл
8

Вот командный файл, который я написал, чтобы автоматизировать его из командной строки, но это для Windows / MS-DOS.

Синтаксис базы данных rename_mysqldb newdatabase -u [пользователь] -p [пароль]

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

Хранимая процедура TodoInTX для меня не совсем работает. Вот мой удар в этом:

- хранимая процедура rename_db: переименование базы данных моими средствами копирования таблиц.
- Предостережения: 
- Будет забивать любую существующую базу данных с тем же именем, что и «новое» имя базы данных.
- ТОЛЬКО копирует таблицы; хранимые процедуры и другие объекты базы данных не копируются.
- Томер Альтман (taltman@ai.sri.com)

разделитель //
ПРОЦЕДУРА ОТМЕНЫ, ЕСЛИ СУЩЕСТВУЕТ rename_db;
CREATE PROCEDURE rename_db (В VARCHAR old_db (100), В VARCHAR new_db (100))
НАЧАТЬ
    ОБЪЯВИТЬ current_table VARCHAR (100);
    ОБЪЯВИТЬ сделано INT DEFAULT 0;
    ОБЪЯВЛЯЙТЕ CURSOR old_tables CURSOR FOR: выберите имя_таблицы из information_schema.tables, где table_schema = old_db;
    ЗАЯВИТЕ ПРОДОЛЖАЕТЕ ОБРАЩАТЬСЯ ЗА НЕ НАЙДЕННЫЙ УСТАНОВЛЕНО выполнено = 1;

    SET @output = CONCAT ('DROP SCHEMA IF EXISTS', new_db, ';'); 
    ПОДГОТОВИТЬ STMT ОТ @output;
    EXECUTE stmt;

    SET @output = CONCAT ('СОЗДАТЬ СХЕМУ ЕСЛИ НЕ СУЩЕСТВУЕТ', new_db, ';');
    ПОДГОТОВИТЬ STMT ОТ @output;
    EXECUTE stmt;

    OPEN old_tables;
    ПОВТОРЕНИЕ
        FETCH old_tables INTO current_table;
        Если не сделано, то
        SET @output = CONCAT ('изменить таблицу', old_db, '.', Current_table, 'rename', new_db, '.', Current_table, ';');
        ПОДГОТОВИТЬ STMT ОТ @output;
        EXECUTE stmt;

        END IF;
    ДО КОНЦА, ПОВТОРЕННОГО;

    ЗАКРЫТЬ old_tables;

КОНЕЦ//
разделитель;
user757945
источник
Это будет работать только для таблиц, и только если в этих таблицах нет триггеров. Представления и триггеры не будут перемещены этим.
Олфан
7

Самый простой способ - использовать программное обеспечение HeidiSQL. Это бесплатно и с открытым исходным кодом. Он работает на Windows и на любом Linux с Wine (запускайте приложения Windows на Linux, BSD, Solaris и Mac OS X).

Чтобы загрузить HeidiSQL, перейдите по ссылке http://www.heidisql.com/download.php .

Чтобы скачать Wine, перейдите по ссылке http://www.winehq.org/ .

Чтобы переименовать базу данных в HeidiSQL, просто щелкните правой кнопкой мыши на имени базы данных и выберите «Изменить». Затем введите новое имя и нажмите «ОК».

Это так просто.

Fathah Rehman P
источник
1
Если он имеет хранимые процедуры, он не может быть переименован.
abksharma
@abksharma На самом деле вы получите Database "database_name" contains stored routine(s) which cannot be moved.триггеры сообщений (по крайней мере, для базы данных MariDB), которые считаются хранимыми процедурами. У меня не было никаких хранимых процедур, но я не мог переименовать базу данных, пока я не сбросил все триггеры.
Изогфиф
7

Для пользователей Mac вы можете использовать Sequel Pro(бесплатно), которые просто предоставляют возможность переименовать базы данных. Хотя это не удаляет старую БД.

После открытия соответствующей БД просто нажмите: Database->Rename database...

Роу Гавирел
источник
Иногда старая БД остается живой, но она пуста. Тем не менее, если он делает копию, вы можете сделать копию и удалить старую, это еще 2 простых шага.
Роу Гавирел
6

Я задал вопрос о сбое сервера, пытаясь обойти время простоя при восстановлении очень больших баз данных с помощью MySQL Proxy. У меня не было никакого успеха, но в конце концов я понял, что мне нужна функциональность RENAME DATABASE, потому что выгрузка / импорт не была возможной из-за размера нашей базы данных.

В MySQL встроена функциональность RENAME TABLE, поэтому в итоге я написал простой скрипт на Python, который сделает эту работу за меня. Я разместил его на GitHub на случай, если он будет полезен другим.

cclark
источник
2
RENAME DATABASE исключен из синтаксиса, а не RENAME TABLE.
Герцог
6

Для вашего удобства ниже приведен небольшой шелл-скрипт, который должен быть выполнен с двумя параметрами: db-name и new db-name.

Вам может потребоваться добавить параметры входа в mysql-строки, если вы не используете .my.cnf-файл в вашем домашнем каталоге. Пожалуйста, сделайте резервную копию перед выполнением этого скрипта.


#!/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
источник
1
Это также не будет работать для таблиц с прикрепленными триггерами или для представлений, которые нельзя переименовать в другие базы данных.
Олфан
6

Кажется, никто не упомянул об этом, но вот другой способ:

create database NewDatabaseName like OldDatabaseName;

Затем для каждой таблицы выполните:

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

тогда, если вы хотите,

drop database OldDatabaseName;

Преимущество этого подхода состоит в том, что вся передача выполняется на сервере с почти нулевым сетевым трафиком, поэтому он будет выполняться намного быстрее, чем дамп / восстановление.

Если у вас есть хранимые процедуры / представления / и т. Д., Вы можете также перенести их.

Tuncay Göncüoğlu
источник
2
Насколько я знаю, 5.x не поддерживает ключевое слово "like" в create databaseвыражении? Откуда ты это взял?
Драгас
Вот ссылка на create table likeсинтаксис: dev.mysql.com/doc/refman/5.7/en/create-table-like.html . Что касается создания базы данных, похоже, MySQL с тех пор отбросил это предложение.
Tuncay Göncüoğlu
4

Вот быстрый способ создания сценария переименования SQL, если у вас есть много таблиц для перемещения.

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
источник
Выглядит хорошо, но это не перемещает хранимые процедуры или представления.
Давидпричев
Вы, вероятно, должны добавить хеш-метки, чтобы обернуть вокруг имени таблицы и имени схемы
Funkodebat
4

ALTER DATABASEпредложенный способ обойти это MySQL и RENAME DATABASEотброшен.

С 13.1.32 СМЕНА БАЗЫ ДАННЫХ RENAME :

RENAME {DATABASE | SCHEMA} db_name TO new_db_name;

Этот оператор был добавлен в MySQL 5.1.7, но он был признан опасным и был удален в MySQL 5.1.23.

модные штаны
источник
7
У вас есть пример синтаксиса? Я не знаю ни одного способа использовать его alter databaseдля переименования базы данных, и документация, на которую вы ссылались, не предполагает, что это возможно.
Иордания
@ Джордан, мне тоже будет интересно. Я попробовал и попробовал и обнаружил, что это работает только с версией> 5.1, но я не могу обновить прямо сейчас.
Необычные штаны
5
-1: Для записи о предлагаемых способах, а затем приводить пример не предложенного способа, в то время как полностью отсутствует даже показать пример.
хакре
3
Это не верно. В документации MySQL по переименованию базы данных говорится, что rename_database предназначалась для очень специфической задачи переименования (не общего случая переименования БД), которая теперь обрабатывается с помощью alter database: «Чтобы выполнить задачу обновления имен базы данных с новой кодировкой, используйте ALTER DATABASE db_name UPGRADE. DATA DIRECTORY NAME вместо 'Вы не можете использовать это, чтобы переименовать базу данных, как хотите, в этой команде даже нет места для нового имени базы данных!
Канат Болазар
3

В MySQL Administrator сделайте следующее:

  1. Под Каталогами создайте новую схему базы данных.
  2. Перейдите в Резервное копирование и создайте резервную копию старой схемы.
  3. Выполнить резервное копирование.
  4. Перейдите к Восстановить и откройте файл, созданный в шаге 3.
  5. Выберите «Другая схема» в разделе «Целевая схема» и выберите новую схему базы данных.
  6. Начать восстановление.
  7. Проверьте новую схему и, если она выглядит хорошо, удалите старую.
Том
источник
MySQL Administrator не может обрабатывать большие базы данных, и в этом нет ничего быстрого
deadprogrammer
3

в phpmyadmin вы можете легко переименовать базу данных

select database 

  goto operations tab

  in that rename Database to :

  type your new database name and click go

попросить удалить старую таблицу и перезагрузить данные таблицы, нажмите OK в обоих

Ваша база данных переименована

murtaza.webdev
источник
3

Если вы используете phpMyAdmin, вы можете перейти на вкладку «Операции», выбрав базу данных, которую вы хотите переименовать. Затем перейдите к последнему разделу «Копировать базу данных» (или что-то в этом роде), введите имя и выберите параметры ниже. В этом случае, я думаю, вы должны установить флажки «структура и данные» и «создать базу данных перед копированием» и, наконец, нажать кнопку «Перейти» в этом разделе.

Кстати, я использую phpMyAdmin на испанском языке, поэтому я не уверен, какие названия разделов на английском языке.

Peter Mortensen
источник