Як швидко перейменувати базу даних MySQL (змінити ім'я схеми)?


959

Посібник по MySQL на MySQL охоплює це.

Зазвичай я просто скидаю базу даних і знову імпортую її з новою назвою. Це не варіант для дуже великих баз даних. Мабуть RENAME {DATABASE | SCHEMA} db_name TO new_db_name; , погані речі існують лише у кількох версіях, і загалом це погана ідея .

Для цього потрібно працювати з InnoDB , який зберігає речі зовсім інакше, ніж MyISAM .


3
Також на сервері за замовчуванням: serverfault.com/questions/195221/how-to-rename-a-mysql-database
Ів Мартін

5
Ця заява RENAME DATABASE Syntax була додана в MySQL 5.1.7, але виявилася небезпечною і була видалена в MySQL 5.1.23.
злоктб

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


26
Я щойно робив це з базою даних InnoDB з 30+ таблицями, використовуючи налаштування file_per_table, і хоча деякі таблиці складали 3+ мільйонів рядків, вона заповнюється за <1 секунду. Це просто здається перемістити файли на сховище, а не робити щось складніше ... + якщо це можливо :)
Дейв Рікс


13
Зверніть увагу, що для переглядів це не допоможе. Ви не можете перейменовувати представлення даних, щоб змусити їх переходити з бази даних до іншої. Використовуйте DROP VIEWі CREATE VIEWзамість цього. Незграбний, так. Можливо, ви захочете зробити a, mysqldumpщоб перемістити представлення даних, попередньо перемістивши всі таблиці. Також зауважте, що SHOW TABLESбудуть показані таблиці та види, тому будьте обережні.
tuomassalo

9
Також це не буде працювати для будь-яких таблиць з тригерами. Перед переміщенням таблиці потрібно знайти, скинути і скинути триггери, а потім імпортувати скинуті тригери в цільовий db.
Ольфан

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

86
Як сказав ОП, "[t] його не є варіантом для дуже великих баз даних".
стовп

3
Не забудьте скинути оригінальну базу даних
Павло Радзивиловський

3
Блискуча відповідь! Кілька пропозицій щодо подальшого вдосконалення, оскільки це, ймовірно, гуглить усіма здібностями: (1) Перенесіть фрагмент коду Пабло Марін-Гарсія до вершини, оскільки це здається найкращою відповіддю (2) Поставте -p<password>замість -pусюди, щоб висловлювання запускалися без підказки. .
Стів Чемберс

9
Використовуючи трубопровідну версію, я отримую два підказки "Введіть пароль:" Так: Enter password: Enter password: Здається, він бере один пароль, але не обидва. Я пропускаю деталь?
Райан

33
Я здивований, що ніхто про це не згадував, але ви дійсно повинні також додати --routinesпрапор до команд mysqldump, щоб гарантувати копіювання збережених процедур.
Карлос П

205

Я думаю, що рішення простіше і було запропоновано деякими розробниками. phpMyAdmin для цього має операцію.

Від phpMyAdmin виберіть базу даних, яку потрібно вибрати. На вкладках є одна з операцій, перейдіть до розділу перейменування. Це все.

Це робить, як багато хто запропонував, створити нову базу даних з новою назвою, скинути всі таблиці старої бази даних у нову базу даних та скинути стару базу даних.

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


76
Якщо припустити, що у вас навіть є php у вашому оточенні або ви використовуєте phpmyadmin.
Кріс

26
Досить небезпечно, навіть якщо у вас phpMyAdmin - задній кінець може провалити середину процесу, залишаючи два dbs у невідомому стані, або це може зайняти дуже багато часу, що призведе до вивішування переднього або PHP.
мозбоз

20
Це правда @mozboz, але я це робив протягом 10 років і ніколи не мав такої проблеми. Це те саме, якщо ваша команда виконує команду через оболонку, а комп'ютер виходить з ладу. Є можливість, але що? 1 на 1 квадрильйон?
raphie

24
Сценарій через консоль - це також передня панель, яка може зависати з тими ж проблемами.
Грег

11
Однак консольні операції набагато надійніші, ніж PhpMyAdmin, особливо там, де задіяні великі бази даних, що стосується ОП. Особисто я б настійно пропонував будь-який консольний метод, а не 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;(або якусь іншу велику кількість).


@BlakeFrederick Він не використовує DENABASE 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 .


1
Ідеально! Я перевірив це за допомогою таблиць InnoDB та MyISAM. Найшвидше рішення, яке я протестував (перейменування таблиці майже миттєве, без затримок)!
Філіп

Чудово! Просто пам’ятайте, щоб потім виправити привілеї.
Адам Фарина

пс. Краще зробіть це, перш ніж запускати запити перейменувати, якщо ви працюєте в реальній БД.
Адам Фарина

Чи працює це, якщо таблиця має референтні обмеження? Я очікую, що ні.
дольмен

24

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

  1. Створіть нову базу даних, збийте сервер, перемістіть файли з однієї папки бази даних в іншу та перезавантажте сервер. Зауважте, що це буде працювати лише в тому випадку, якщо ВСІ ваші таблиці є MyISAM.

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

  3. Використовуйте mysqldump і перезавантажте цей файл.


+ для посилання на 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. У цьому випадку вам доведеться скинути базу даних та повторно імпортувати її.


16
Перейменування папок розбиває іграшки.
ViniciusPires

1
@Rahly, навіть якщо встановлено один файл на таблицю, це все ще небезпечно, таблиці, створені до встановлення одного файлу на таблицю, будуть мати проблеми, якщо ви точно не знаєте, що база даних буде створена після встановлення цього прапора.
Qian Chen

Взагалі кажучи, більшість людей матимуть свої системи так чи інакше, люди не збираються випадковим чином перевертати, мати чи не мати одну таблицю на файл. До того ж, навіть у вашому сценарії, якби таблиці були створені перед прапором, вони не існували б в першу чергу як окремі файли, тому переміщення не працювало б і все-таки було безпечним, без небезпеки. Пам'ятайте, що база даних НЕ працює, коли відбувається переміщення.
Рахлі

Еквівалент для mysql, встановленого з домашньою мовою на 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

6
Обережно з цим. Якщо ви не входите з користувачем root, ви можете мати обмежений дозвіл. Причиняти помилку перейменування, але успіх краплі призводить до випадання бази даних. Хороший сценарій інакше.
Лекс

3
Я додав set -eдо початку скрипту, який призведе до припинення виконання при відмові і повинен пом'якшити цю проблему.
Міккель

19

Я нещодавно натрапив на дуже приємний спосіб це зробити, працює з MyISAM та InnoDB і дуже швидко:

RENAME TABLE old_db.table TO new_db.table;

Я не пам’ятаю, де я це читав, але кредит належить комусь іншому, а не мені.


@ArkadijKuzhel не думаю так. Я думаю, ви говорите про RENAME DATABASE.
Роб Грант

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

3
Це страждає від тієї самої проблеми, що і прийнята відповідь - "ВЗНАЙТИ БАЗУ ДАНАБАЗИ небезпечно і було видалено в MySQL 5.1.23" - з dev.mysql.com/doc/refman/5.1/uk/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. Замість цього залиште пароль порожнім і введіть його після підказки.
Tommie C.

Це триває ненормально довго, більше 20 хвилин, не закінчуючи. Чи добре це скасовувати?
Sigu Magwa

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;

14
Не підходить для величезних баз даних.
mikesl

14

На даний момент MySQL не підтримує перейменування бази даних через свій командний інтерфейс, але ви можете перейменувати базу даних, якщо у вас є доступ до каталогу, в якому MySQL зберігає свої бази даних. Для встановлення MySQL за замовчуванням це зазвичай знаходиться в каталозі даних під каталогом, де був встановлений MySQL. Знайдіть ім’я бази даних, яку ви хочете перейменувати, у каталозі Дані та перейменуйте її. Хоча перейменування каталогу може спричинити деякі проблеми з дозволом. Бережись.

Примітка. Перш ніж перейменувати базу даних, потрібно зупинити MySQL

Я рекомендую створити нову базу даних (використовуючи потрібне ім’я) та експортувати / імпортувати потрібні вам дані від старої до нової. Досить просто.


13

Коли ви перейменовуєте базу даних у PHPMyAdmin, вона створює дамп, потім скидає та відтворює базу даних з новим іменем.


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. Відкиньте стару схему бази даних. 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) Створіть список лише таблиць "BASE". Їх можна знайти за допомогою запиту на 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

Складності з вищезазначеними методами: нам може знадобитися оновити ГРАНТИ для користувачів таким чином, щоб вони відповідали правильній схемі_назви. Вони можуть бути виправлені за допомогою простого ОНОВЛЕННЯ на таблицях mysql.column_priv, mysql.procs_priv, mysql.tables_priv, mysql.db, оновлення імені old_schema до new_schema та виклик "Flush privileges;". Хоча "метод 2" здається дещо складнішим, ніж "метод 1", це абсолютно можливо. Простий скрипт bash для виконання вищезазначених кроків у належній послідовності може допомогти вам заощадити місце та час під час перейменування схем бази даних наступного разу.

Команда Perbana 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 має опцію Перейменування бази даних у меню База даних. 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


Мені подобається цей сценарій, він майже універсальний. Однак це не вдалося обробити випадок, коли є кілька прикованих VIEW, де defer не є root.
ENargit

9

Можна перейменовувати всі таблиці в базі даних, щоб вони знаходилися під іншою базою даних, не потребуючи повного скидання та відновлення.

ПРОЦЕДУРА ДРОПУВАННЯ ЯКЩО ВИНАЄТЬ mysql.rename_db;
DELIMITER ||
СТВОРИТИ ПРОЦЕДУРУ mysql.rename_db (IN old_db VARCHAR (100), IN new_db VARCHAR (100))
ПОЧАТОК
SELECT CONCAT ('CREATE DATABASE', new_db, ';') `# create new database`;
ВИБІР CONCAT ('ТАБЛИЦЯ ОЗНАЧЕННЯ' ', old_db,' '.' ', Ім'я таблиці,' `` ``, new_db, `` .` ', ім'я таблиці,' `; ')` # змінити таблицю` ВІД інформації_schema.tables WHERE table_schema = old_db;
SELECT CONCAT ('DROP DATABASE' ', old_db,' `; ')` # drop old database';
КІНЦЬ ||
DELIMITER;

$ time mysql -uroot -e "виклик mysql.rename_db ('db1', 'db2');" | mysql -uroot

Однак будь-які тригери в цільовому db не будуть задоволені. Спочатку їх потрібно буде скинути, а потім відтворити після перейменування.

mysql -uroot -e "виклик mysql.rename_db ('тест', 'blah2');" | mysql -uroot
ПОМИЛКА 1435 (HY000) у рядку 4: Тригер в неправильній схемі

невелика настройка, яка робить цю роботу w / mysql 5.x mysql --batch-uroot -e "call mysql.rename_db('test', 'blah2');" | mysql -uroot Зауважте, що вам потрібно використовувати --batch для зміни форматування на необроблене форматування, яке виводить результати без форматування.
mikesl

8

Ось пакетний файл, який я написав, щоб автоматизувати його з командного рядка, але це для Windows / MS-DOS.

Синтаксис - це перейменувати_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)

роздільник //
ПРОЦЕДУРА ДРОПУВАННЯ ЯКЩО ВИНАЄТЬ перейменувати_db;
СТВОРИТИСЯ ПРОЦЕДУРА rename_db (IN old_db VARCHAR (100), IN new_db VARCHAR (100))
ПОЧАТОК
    DECLARE current_table VARCHAR (100);
    ВІДКЛЮЧИТИ зроблено INT DEFAULT 0;
    ДЕКЛАРУВАТИ old_tables КУРС ДЛЯ вибору імені таблиці з information_schema.tables де table_schema = old_db;
    ЗАЯВЛЯЙТЕ ПРОДОВЖДЕННУ ВІДКЛЮЧИТЕЛЯ ДЛЯ НЕ ЗНАЧЕНОГО НАСТРОЙКА зроблено = 1;

    SET @output = CONCAT ('DROP SCHEMA IF EXISTS', new_db, ';'); 
    ПІДГОТОВИТИ stmt ВІД @output;
    ВИКОНАТИ stmt;

    SET @output = CONCAT ('СТВОРИТИ СХЕМУ, ЯКЩО НЕ ІСНУЄ', new_db, ';');
    ПІДГОТОВИТИ stmt ВІД @output;
    ВИКОНАТИ stmt;

    ВІДКРИТИ старі_таблиці;
    ПОВТОРИТИ
        ПОЛУЧИТИ old_tables INTO current_table;
        ЯКЩО НЕ робив ЦЕ
        SET @output = CONCAT ('таблиця змін', old_db, '.', Current_table, 'перейменувати', new_db, '.', Current_table, ';');
        ПІДГОТОВИТИ stmt ВІД @output;
        ВИКОНАТИ stmt;

        КІНЦЯ ЯКЩО;
    ДОКОНЧЕНО ЗАКОНЧИЙ ПОВТОРЕННЯ;

    ЗАКРИТТИ old_tables;

КІН //
роздільник;

Це буде працювати лише для таблиць, і лише якщо ці таблиці не мають жодних тригерів. Погляди та тригери цим чином не буде переміщено.
Ольфан

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, просто клацніть правою кнопкою миші ім’я бази даних та оберіть «Редагувати». Потім введіть нове ім’я та натисніть «ОК».

Це так просто.


1
Якщо він має збережені процедури, його не можна перейменувати.
абксарма

@abksharma Насправді ви отримаєте повідомлення Database "database_name" contains stored routine(s) which cannot be moved.Тригери (принаймні для бази даних MariDB) зараховуються як збережені процедури. Я не мав жодних збережених процедур, але не зміг перейменувати базу даних, поки я не скинув усі тригери.
izogfif

7

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

щойно відкрийте відповідну БД, просто натисніть: Database->Rename database...


Іноді старий БД залишає живим, але він порожній. І все-таки, якщо вона робить копію, ви можете зробити копію та видалити стару, це все-таки 2 прості дії.
Roee Gavirel

6

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

Існує функція RENAME TABLE, вбудована в MySQL, тому я закінчив писати простий скрипт Python, щоб зробити роботу для мене. Я розмістив його на GitHub на випадок, якщо це може бути корисним для інших.



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"

1
Це також не буде працювати для таблиць із доданими тригерами або для представлень, які не можуть бути перейменовані в інші бази даних.
Ольфан

6

Здається, ніхто про це не згадував, але ось інший спосіб:

create database NewDatabaseName like OldDatabaseName;

то для кожної таблиці виконайте:

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

тоді, якщо ви хочете,

drop database OldDatabaseName;

Цей підхід мав би перевагу робити всю передачу на сервері з майже нульовим мережевим трафіком, тому він пройде набагато швидше, ніж дамп / відновлення.

Якщо у вас є збережені процедури / представлення / тощо, ви можете також передати їх.


2
Наскільки я знаю, 5.x не підтримує в create databaseоператорі ключове слово "like" ? Звідки ти це взяв?
Драгас

Ось посилання на 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' ;

Виглядає добре, але це не переміщує збережені процедури чи представлення даних.
davidpricedev

вам, мабуть, слід додати хеш-позначки, щоб обернутись назвою таблиці та назвою схеми
Funkodebat

4

ALTER DATABASEє запропонованим способом навколо цього MySQL і RENAME DATABASEвідпадає.

З 13.1.32 RENAME DATABASE синтаксис :

RENAME {DATABASE | SCHEMA} db_name TO new_db_name;

Ця заява була додана в MySQL 5.1.7, але вона виявилася небезпечною і була видалена в MySQL 5.1.23.


7
Чи є у вас приклад синтаксису? Я не знаю жодного способу використання alter databaseдля перейменування самої бази даних, а документація, з якою ви пов’язані, не говорить про те, що це можливо.
Йорданія

@Jordan Я також зацікавився. Я спробував і спробував і з’ясував, що він працює лише з версією> 5.1, але наразі не можу оновити.
fancyPants

5
-1: Написати про запропоновані способи, потім навести приклад не запропонованого способу, повністю відсутній, щоб навіть показати приклад.
хакре

3
Це неправильно. Документація бази даних перейменування MySQL говорить, що rename_database призначена для дуже конкретного завдання з перейменування (не загального випадку перейменування БД), яке зараз обробляється базою даних alter: 'Для виконання завдання оновлення імен баз даних за допомогою нового кодування використовуйте ALTER DATABASE db_name UPGRADE НАЗАД ДИРЕКТОРІЯ ДАНИХ замість цього: "Ви не можете використовувати це для перейменування бази даних за своїм бажанням. У цій команді немає навіть місця для нового імені db!
Канат Болазар

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

Попросіть скинути стару таблицю та перезавантажити дані таблиці, натисніть кнопку ОК в обох

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


3

Якщо ви використовуєте phpMyAdmin ви можете перейти на вкладку "Операції", як тільки ви вибрали базу даних, яку хочете перейменувати. Потім перейдіть до останнього розділу "Скопіювати базу даних у" (або щось подібне), дайте ім'я та виберіть параметри нижче. У цьому випадку я думаю, ви повинні встановити прапорець "структура та дані" та "створити базу даних перед копіюванням" і, нарешті, натиснути кнопку "йти" у цьому розділі.

До речі, я використовую phpMyAdmin іспанською мовою, тому я не впевнений, які назви розділів є англійською.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.