Como renomeio rapidamente um banco de dados MySQL (alterar o nome do esquema)?

959

O manual do MySQL no MySQL cobre isso.

Normalmente, apenas despejo o banco de dados e reimporto-o com um novo nome. Esta não é uma opção para bancos de dados muito grandes. Aparentemente, RENAME {DATABASE | SCHEMA} db_name TO new_db_name; faz coisas ruins, existe apenas em algumas versões e é uma má idéia em geral .

Isso precisa funcionar com o InnoDB , que armazena as coisas de maneira muito diferente do MyISAM .

Csaba
fonte
5
Esta declaração RENAME DATABASE Sintaxe foi adicionada no MySQL 5.1.7, mas foi considerada perigosa e foi removida no MySQL 5.1.23.
zloctb
11
Espero que o MySQL implemente uma nova RENAME DATABASEdeclaração de trabalho que não tenha nenhum perigo, pois não há uma maneira fácil de executar essa tarefa atualmente. Não há motivo óbvio para que isso tenha sido perigoso na documentação para que eles possam fazer uma substituição. Pelo menos as pessoas colocaram erros de solicitação de recurso em seu site. Por exemplo, bugs.mysql.com/bug.php?id=58593 e bugs.mysql.com/bug.php?id=1698 .
Edward
links são agora quebrado ...
Oldboy

Respostas:

833

Para o InnoDB , o seguinte parece funcionar: crie o novo banco de dados vazio e renomeie cada tabela para o novo banco de dados:

RENAME TABLE old_db.table TO new_db.table;

Você precisará ajustar as permissões depois disso.

Para scripts em um shell, você pode usar um dos seguintes:

mysql -u username -ppassword old_db -sNe 'show tables' | while read table; \ 
    do mysql -u username -ppassword -sNe "rename table old_db.$table to new_db.$table"; done

OU

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

Notas:

  • Não há espaço entre a opção -pe a senha. Se o seu banco de dados não tiver senha, remova a -u username -ppasswordpeça.
  • Se alguma tabela tiver um gatilho, ela não poderá ser movida para outro banco de dados usando o método acima (resultará em Trigger in wrong schemaerro). Se for esse o caso, use uma maneira tradicional de clonar um banco de dados e solte o antigo:

    mysqldump old_db | mysql new_db

  • Se você tiver procedimentos armazenados, poderá copiá-los depois:

    mysqldump -R old_db | mysql new_db

Benoit Duffez
fonte
26
Acabei de fazer isso com um banco de dados InnoDB com mais de 30 tabelas, usando a configuração file_per_table, e mesmo que algumas tabelas tenham mais de 3 milhões de linhas, ele foi concluído em <1 segundo. Parece apenas para mover os arquivos no armazenamento, em vez de fazer algo mais complicado ... +2 se possível :)
Dave Rix
87
"DATABASE RENAME foi encontrado para ser perigoso e foi removido no MySQL 5.1.23" - de dev.mysql.com/doc/refman/5.1/en/rename-database.html
Palani
13
Observe que isso não funcionará para visualizações. Você não pode renomear vistas para fazê-las saltar de um banco de dados para outro. Use DROP VIEWe em CREATE VIEWvez disso. Desajeitado, sim. Você pode fazer um mysqldumppara mover as visualizações, depois de mover todas as tabelas pela primeira vez. Observe também que SHOW TABLESmostrará tabelas E visualizações, portanto, tenha cuidado.
Tuomassalo #
9
Além disso, isso não funcionará para nenhuma tabela com gatilhos. Você precisa encontrar, despejar e soltar gatilhos antes de mover a tabela e depois importar os gatilhos despejados no banco de dados de destino.
precisa saber é
5
Actualizado (ie de trabalho) ligação documentar porque RENAME DATABASEfoi removido: dev.mysql.com/worklog/task/?id=4030
alexis
443

Use estes poucos comandos simples:

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

Ou, para reduzir a E / S, use o seguinte, conforme sugerido por @Pablo Marin-Garcia:

mysqladmin -u username -p create newdatabase
mysqldump -u username -v olddatabase -p | mysql -u username -p -D newdatabase
hendrasaputra
fonte
86
Como o OP disse, "[este] não é uma opção para bancos de dados muito grandes".
pilcrow
3
Não esqueça de deixar o banco de dados original de DROP
Pavel Radzivilovsky, 11/11/10
3
Resposta brilhante! Algumas sugestões para melhorar ainda mais, pois isso provavelmente está sendo pesquisei por todas as habilidades: (1) Mova fragmento de código de Pablo Marin-Garcia ao topo como parece a melhor resposta (2) Coloque -p<password>em vez de -pem toda parte assim as declarações executado sem um prompt aparecer .
Steve Chambers
9
Usando a versão canalizada, recebo duas solicitações "Digite a senha:", assim: Enter password: Enter password: Parece ter uma senha, mas não as duas. Estou faltando um detalhe?
Ryan
33
Estou surpreso que ninguém tenha mencionado isso, mas você também deve adicionar a --routinesflag aos comandos do mysqldump, para garantir que os procedimentos armazenados sejam copiados.
Carlos P
205

Eu acho que a solução é mais simples e foi sugerida por alguns desenvolvedores. O phpMyAdmin possui uma operação para isso.

No phpMyAdmin, selecione o banco de dados que você deseja selecionar. Nas guias existe uma chamada Operações, vá para a seção Renomear. Isso é tudo.

Como muitos sugeriram, ele cria um novo banco de dados com o novo nome, despeja todas as tabelas do banco de dados antigo no novo banco de dados e descarta o banco de dados antigo.

Digite a descrição da imagem aqui

raphie
fonte
76
Supondo que você tenha php no seu ambiente ou use phpmyadmin.
Chris
26
Bastante perigoso, mesmo se você tiver o phpMyAdmin - o back-end pode falhar no meio do processo, deixando os dois dbs em um estado desconhecido, ou pode demorar muito tempo, levando à interrupção do front-end ou ao tempo limite do PHP.
mozboz
20
Isso é verdade @mozboz, mas eu faço isso há 10 anos e nunca tive esse problema. É o mesmo se você estiver executando o comando através de um shell e o computador travar. Existe uma possibilidade, mas o que? 1 a 1 quadrilhão?
Raphie 22/09/12
24
Um script via console também é um front-end que pode travar com os mesmos problemas.
Greg Greg
11
No entanto, as operações do console são muito mais confiáveis ​​do que o PhpMyAdmin, especialmente quando grandes bancos de dados estão envolvidos, o que é o caso do OP. Pessoalmente, sugiro fortemente qualquer método de console, em vez de PMA, se você tiver um banco de dados razoavelmente grande. Escusado será dizer que, em pequenos bancos de dados, o PMA é igualmente bom.
Teodor Sandu
107

Você pode usar o SQL para gerar um script SQL para transferir cada tabela no banco de dados de origem para o banco de dados de destino.

Você deve criar o banco de dados de destino antes de executar o script gerado a partir do comando.

Você pode usar um desses dois scripts (sugeri originalmente o primeiro e alguém "melhorou" minha resposta para usar GROUP_CONCAT. Faça a sua escolha, mas prefiro o original):

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

ou

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

($ 1 e $ 2 são origem e destino, respectivamente)

Isso irá gerar um comando SQL que você precisará executar.

Observe que GROUP_CONCATtem um limite de tamanho padrão que pode ser excedido para bancos de dados com um grande número de tabelas. Você pode alterar esse limite executando SET SESSION group_concat_max_len = 100000000;(ou outro número grande).

ErichBSchulz
fonte
@BlakeFrederick Ele não usa RENAME DATABASE, então qual é o problema?
Tuxayo 17/08/16
Isso funciona se a tabela tiver restrições referenciais? Eu espero que não.
dólmen
42

Emulando o RENAME DATABASEcomando ausente no MySQL:

  1. Crie um novo banco de dados
  2. Crie as consultas de renomeação com:

    SELECT CONCAT('RENAME TABLE ',table_schema,'.',table_name,
        ' TO ','new_schema.',table_name,';')
    FROM information_schema.TABLES
    WHERE table_schema LIKE 'old_schema';
  3. Execute essa saída

  4. Excluir banco de dados antigo

Foi extraído de Emulating The Missing RENAME DATABASE Command no MySQL .

Marciano
fonte
1
Perfeito! Eu testei isso com as tabelas InnoDB e MyISAM. A solução mais rápida que testei (renomear a tabela é quase instantânea, sem demora)!
Philipp
Ótimo! Lembre-se de corrigir privilégios depois.
Adam Faryna 30/08/19
ps. É melhor fazer isso antes de executar as consultas de renomeação se estiver trabalhando no banco de dados ativo.
Adam Faryna 30/08/19
Isso funciona se a tabela tiver restrições referenciais? Eu espero que não.
dólmen
24

Três opções:

  1. Crie o novo banco de dados, desative o servidor, mova os arquivos de uma pasta para o outro e reinicie o servidor. Observe que isso só funcionará se TODAS as suas tabelas forem MyISAM.

  2. Crie o novo banco de dados, use as instruções CREATE TABLE ... LIKE e, em seguida, use as instruções INSERT ... SELECT * FROM.

  3. Use o mysqldump e recarregue com esse arquivo.

longneck
fonte
+ para a referência myisam. Eu não conseguia descobrir por que isso não funcionou para mim.
Christian Payne
5
Os questão afirma que este trabalho obrigatório para InnoDB, não MyISAM
D-Rock
A @ D-Rock diz isso ao Google, que traz pessoas para cá com base no título.
jiggunjer 4/04
24

A maneira simples

Mude para o diretório do banco de dados:

cd /var/lib/mysql/

Encerre o MySQL ... Isso é importante!

/etc/init.d/mysql stop

Ok, esse caminho não funciona para bancos de dados InnoDB ou BDB.

Renomeie o banco de dados:

mv old-name new-name

... ou a mesa ...

cd database/

mv old-name.frm new-name.frm

mv old-name.MYD new-name.MYD

mv old-name.MYI new-name.MYI

Reinicie o MySQL

/etc/init.d/mysql start

Feito...

OK, dessa maneira não funciona com os bancos de dados InnoDB ou BDB. Nesse caso, você precisa despejar o banco de dados e importá-lo novamente.

DeeCee
fonte
16
Renomear pastas quebra brinquedos.
ViniciusPires
1
@Rahly, mesmo que um arquivo por tabela esteja definido, ainda é perigoso, as tabelas criadas antes da definição de um arquivo por tabela apresentarão problemas, a menos que você tenha certeza de que o banco de dados foi criado após a definição do sinalizador.
Qian Chen
De um modo geral, no entanto, a maioria das pessoas terá seus sistemas de uma maneira ou de outra, as pessoas não estarão aleatoriamente se quiserem ter ou não uma tabela por arquivo. Além disso, mesmo no seu cenário, se as tabelas fossem criadas antes da sinalização, elas não existiriam como arquivos separados em primeiro lugar, para que a mudança não funcionasse e ainda seja segura, sem perigo. Lembre-se de que o banco de dados NÃO está sendo executado quando a movimentação está ocorrendo.
Rahly
O equivalente para mysql instalado com homebrew no 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

Você pode usar este script de shell:

Referência: Como renomear um banco de dados 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"

Está funcionando:

$ sh rename_database.sh oldname newname
Grijesh Chauhan
fonte
6
Cuidado com isso. Se você não estiver efetuando login com o usuário root, poderá ter permissão limitada. Fazendo com que a renomeação falhe, mas a queda tenha êxito, resultando em um banco de dados descartado. Bom roteiro de outra maneira.
Lex
3
Eu adicionei set -eao início do script, o que fará com que a execução seja encerrada em caso de falha e deve atenuar esse problema.
Mikkel
19

Só recentemente me deparei com uma maneira muito legal de fazer isso, trabalha com MyISAM e InnoDB e é muito rápido:

RENAME TABLE old_db.table TO new_db.table;

Não me lembro de onde li, mas o crédito é para outra pessoa, não para mim.

Amr Mostafa
fonte
@ArkadijKuzhel não pensa assim. Acho que você está falando sobre RENAME DATABASE.
Rob Grant
Isso realmente ajudou, criei um novo banco de dados em branco e usei o código, todas as tabelas foram importadas com os nomes desejados.
JulyOrdinary
3
Esta sofre do mesmo problema como a resposta aceita - "DATABASE RENAME foi encontrado para ser perigoso e foi removido no MySQL 5.1.23" - de dev.mysql.com/doc/refman/5.1/en/rename-database.html
Blake Frederick
16

A maneira mais simples de fazer uma renomeação completa à prova de balas e ilusões (incluindo descartar o banco de dados antigo no final, para que seja uma renomeação em vez de uma cópia) :

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

Passos:

  1. Copie as linhas no bloco de notas.
  2. Substitua todas as referências a "olddbname", "newdbname", "mypassword" (+ opcionalmente "root") pelos seus equivalentes.
  3. Execute um por um na linha de comando (digite "y" quando solicitado).
Steve Chambers
fonte
Evite adicionar sua senha ao console, pois não é seguro. Se você já fez isso, use o histórico -cw para remover. Em vez disso, deixe a senha vazia e digite-a após o prompt.
21417 Tommie C.
Está demorando demais, mais de 20 minutos sem terminar. Está tudo bem em cancelar?
Sigu Magwa 10/09/18
15

Isto é o que eu 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;
eaykin
fonte
14
Não é possível para grandes bancos de dados.
precisa saber é o seguinte
14

O MySQL não suporta a renomeação de um banco de dados através de sua interface de comando no momento, mas você pode renomear o banco de dados se tiver acesso ao diretório em que o MySQL armazena seus bancos de dados. Para instalações padrão do MySQL, isso geralmente está no diretório Data, no diretório em que o MySQL foi instalado. Localize o nome do banco de dados que você deseja renomear no diretório Data e renomeie-o. Renomear o diretório pode causar alguns problemas de permissão. Estar ciente.

Nota: Você deve parar o MySQL antes de renomear o banco de dados

Eu recomendaria criar um novo banco de dados (usando o nome desejado) e exportar / importar os dados necessários do antigo para o novo. Bem simples.

bryanpearson
fonte
13

Quando você renomeia um banco de dados no PHPMyAdmin, ele cria um dump, elimina e recria o banco de dados com o novo nome.

UnkwnTech
fonte
4
Observe que esse recurso está um pouco oculto na guia "Operações", quando você clica no banco de dados.
Maris B.
13

Bem, existem 2 métodos:

Método 1: Um método conhecido para renomear o esquema do banco de dados é despejar o esquema usando o Mysqldump, restaurá-lo em outro esquema e, em seguida, descartar o esquema antigo (se necessário).

De Shell

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

Embora o método acima seja fácil, consome tempo e espaço. E se o esquema tiver mais de 100 GB? Existem métodos em que você pode canalizar os comandos acima juntos para economizar espaço, mas isso não economizará tempo.

Para remediar essas situações, existe outro método rápido para renomear esquemas, no entanto, é preciso tomar alguns cuidados ao fazê-lo.

Método 2: O MySQL possui um recurso muito bom para renomear tabelas que até funciona em diferentes esquemas. Essa operação de renomeação é atômica e ninguém mais pode acessar a tabela enquanto ela está sendo renomeada. Isso demora um pouco para ser concluído, pois alterar o nome de uma tabela ou seu esquema é apenas uma alteração de metadados. Aqui está uma abordagem processual ao renomear:

Crie o novo esquema do banco de dados com o nome desejado. Renomeie as tabelas do esquema antigo para o novo esquema, usando o comando “RENAME TABLE” do MySQL. Solte o esquema antigo do banco de dados. If there are views, triggers, functions, stored procedures in the schema, those will need to be recreated too. “RENAME TABLE” do MySQL falhará se houver gatilhos nas tabelas. Para remediar isso, podemos fazer o seguinte:

1) Dump the triggers, events and stored routines in a separate file. Isso foi feito usando os sinalizadores -E, -R (além de -t -d, que despeja os gatilhos) no comando mysqldump. Depois que os gatilhos forem despejados, precisaremos removê-los do esquema, para que o comando RENAME TABLE funcione.

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

2) Gere uma lista apenas das tabelas "BASE". Estes podem ser encontrados usando uma consulta na information_schema.TABLEStabela.

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

3) Despejar as visualizações em um arquivo de saída. As visualizações podem ser encontradas usando uma consulta na mesma information_schema.TABLEStabela.

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) Solte os gatilhos nas tabelas atuais no old_schema.

mysql> DROP TRIGGER <trigger_name>;
...

5) Restaure os arquivos de despejo acima depois que todas as tabelas "Base" encontradas na etapa 2 forem renomeadas.

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

Complexidades com os métodos acima: Talvez seja necessário atualizar os GRANTS para os usuários para que eles correspondam ao schema_name correto. Isso poderia ser corrigido com uma simples atualização de tabelas mysql.columns_priv, mysql.procs_priv, mysql.tables_priv, mysql.db, atualizando o nome old_schema para new_schema e chamando “Flush privilégios;”. Embora o "método 2" pareça um pouco mais complicado que o "método 1", isso é totalmente programável. Um script simples do bash para executar as etapas acima na sequência correta pode ajudar a economizar espaço e tempo e renomear os esquemas do banco de dados da próxima vez.

A equipe do DBA remoto da Percona escreveu um script chamado "rename_db" que funciona da seguinte maneira:

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

Para demonstrar o uso desse script, usou um esquema de exemplo "emp", criou gatilhos de teste, rotinas armazenadas nesse esquema. Tentará renomear o esquema do banco de dados usando o script, que leva alguns segundos para ser concluído, em vez do método de despejo / restauração demorado.

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

Como você pode ver na saída acima, o esquema do banco de dados "emp" foi renomeado para "emp_test" em menos de um segundo. Por fim, este é o script da Percona usado acima para o "método 2".

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

Passos :

  1. Clique em http: // localhost / phpmyadmin /
  2. Selecione seu DB
  3. Clique na guia Operações
  4. Haverá uma guia como "Renomear banco de dados para". Adicione um novo nome e marque Ajustar privilégios.
  5. Clique em Ir.

insira a descrição da imagem aqui

Shubham Jain
fonte
1
Uma solução phpMyAdmin geralmente é uma solução ruim, pois alguns ambientes têm ambiente restrito.
Daniel Antunes Pinto
Não é uma solução "boa", mas, apesar disso, agradeço o que eu estava procurando.
131319 jamie
1
Por favor, votar-se se é obras para você .. ele vai ajudar .. obrigado
Shubham Jain
1
Isso funciona para mim, no ambiente phpMyAdmin, +1
William
12

Para quem é usuário de Mac, o Sequel Pro tem uma opção Renomear banco de dados no menu Banco de dados. http://www.sequelpro.com/

Duque
fonte
5
Cuidado com esta opção se você tiver visualizações ou gatilhos no seu banco de dados. Por trás dessa opção de menu, há um script que criará um novo banco de dados e moverá todas as tabelas. Isso não funcionará para visualizações ou gatilhos; portanto, eles serão deixados para trás no seu banco de dados antigo. O resultado são dois bancos de dados corrompidos que precisam ser corrigidos.
precisa saber é
10

A maioria das respostas aqui está errada por um de dois motivos:

  1. Você não pode simplesmente usar RENAME TABLE, porque pode haver visualizações e gatilhos. Se houver gatilhos, RENAME TABLE falhará
  2. Você não pode usar o mysqldump se desejar "rapidamente" (conforme solicitado na pergunta) renomear um grande banco de dados

A Percona tem um post sobre como fazer isso bem: https://www.percona.com/blog/2013/12/24/renaming-database-schema-mysql/

e script postado (feito?) por Simon R Jones que faz o que é sugerido nesse post. Corrigi um bug que encontrei no script. Você pode vê-lo aqui:

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

Aqui está uma cópia:

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

Salve-o em um arquivo chamado rename_dbe torne o script executável chmod +x rename_dbe use-o como./rename_db localhost old_db new_db

ryantm
fonte
Eu gosto desse script, é quase universal. No entanto, ele falhou ao processar um caso quando existem várias VIEWs encadeadas em que o definidor não é raiz.
ENargit
9

É possível renomear todas as tabelas em um banco de dados para estar em outro banco de dados sem precisar executar um despejo e restauração completos.

PROCEDIMENTO DE QUEDA SE EXISTE mysql.rename_db;
DELIMITER ||
CRIAR PROCEDIMENTO mysql.rename_db (IN old_db VARCHAR (100), IN new_db VARCHAR (100))
INÍCIO
SELECT CONCAT ('CREATE DATABASE', new_db, ';') `# cria novo banco de dados`;
SELECT CONCAT ('RENAME TABLE' ', old_db,' '.`', table_name, '' TO `', new_db,' '.`', table_name, ''; ')` # alter table` FROM information_schema.tables WHERE table_schema = old_db;
SELECT CONCAT ('DROP DATABASE' ', old_db,' `; ')` # descarte o banco de dados antigo`;
FIM ||
DELIMITER;

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

No entanto, quaisquer gatilhos no banco de dados alvo não serão felizes. Você precisará descartá-los primeiro e depois recriá-los após a renomeação.

mysql -uroot -e "chama mysql.rename_db ('teste', 'blah2');" | mysql -uroot
ERRO 1435 (HY000) na linha 4: Disparador no esquema errado
TodoInTX
fonte
pequenos ajustes que tornam este trabalho com o mysql 5.x mysql --batch-uroot -e "call mysql.rename_db('test', 'blah2');" | mysql -uroot Observe, você deve usar --batch para alterar a formatação para a formatação bruta, que gera os resultados com formatação zero.
mikesl
8

Aqui está um arquivo em lotes que eu escrevi para automatizá-lo na linha de comando, mas para Windows / MS-DOS.

Sintaxe é renomear_mysqldb banco de dados newdatabase -u [user] -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=
Johnny
fonte
7

O procedimento armazenado do TodoInTX não funcionou muito bem para mim. Aqui está minha facada:

- procedimento armazenado rename_db: renomeia um banco de dados como meio de cópia de tabela.
-- Ressalvas: 
- Derrubará qualquer banco de dados existente com o mesmo nome que o 'novo' nome do banco de dados.
- SOMENTE copia tabelas; procedimentos armazenados e outros objetos de banco de dados não são copiados.
- Tomer Altman ([email protected])

delimitador //
PROCEDIMENTO DE QUEDA SE EXISTE rename_db;
CRIAR PROCEDIMENTO rename_db (IN old_db VARCHAR (100), IN new_db VARCHAR (100))
INÍCIO
    DECLARAR tabela_ atual VARCHAR (100);
    DECLARE feito INT DEFAULT 0;
    DECLARAR old_tables CURSOR FOR selecione table_name em information_schema.tables em que table_schema = old_db;
    DECLARAR CONTINUAR MANUSEIO POR CONJUNTO NÃO ENCONTRADO done = 1;

    SET @output = CONCAT ('DROP SCHEMA SE EXISTS', novo_db, ';'); 
    PREPARE stmt FROM @output;
    EXECUTAR stmt;

    SET @output = CONCAT ('CREATE SCHEMA SE NÃO EXISTE', new_db, ';');
    PREPARE stmt FROM @output;
    EXECUTAR stmt;

    ABRIR tabelas_ antigas;
    REPETIR
        FETCH old_tables INTO tabela atual;
        SE NÃO for feito ENTÃO
        SET @output = CONCAT ('alter table', old_db, '.', Tabela atual, 'renomear', novo_db, '.', Tabela atual, ';');
        PREPARE stmt FROM @output;
        EXECUTAR stmt;

        FIM SE;
    ATÉ feito END REPEAT;

    CLOSE old_tables;

FIM//
delimitador;
user757945
fonte
Isso funcionará apenas para tabelas e somente se essas tabelas não tiverem nenhum gatilho. Exibições e gatilhos não serão movidos por isso.
Olfan
7

O método mais simples é usar o software HeidiSQL. É gratuito e de código aberto. É executado no Windows e em qualquer Linux com Wine (execute aplicativos do Windows no Linux, BSD, Solaris e Mac OS X).

Para baixar o HeidiSQL, vá para http://www.heidisql.com/download.php .

Para baixar o Wine, vá para http://www.winehq.org/ .

Para renomear um banco de dados no HeidiSQL, clique com o botão direito do mouse no nome do banco de dados e selecione 'Editar'. Em seguida, insira um novo nome e pressione 'OK'.

É tão simples.

Fathah Rehman P
fonte
1
Se tiver procedimentos armazenados, não poderá ser renomeado.
abksharma 28/09/16
@abksharma Na verdade, você receberá a mensagem Database "database_name" contains stored routine(s) which cannot be moved.Triggers (pelo menos para o banco de dados MariDB) são contados como rotinas armazenadas. Eu não tinha nenhum procedimento armazenado, mas não consegui renomear o banco de dados até eu soltar todos os gatilhos.
izogfif 11/02
7

Para usuários de mac, você pode usar Sequel Pro(gratuito), que fornece a opção de renomear bancos de dados. Embora não exclua o banco de dados antigo.

Depois de abrir o banco de dados relevante, basta clicar em: Database->Rename database...

Roee Gavirel
fonte
Às vezes, deixa o banco de dados antigo vivo, mas está vazio. Ainda assim, se ele faz uma cópia, você pode fazer a cópia e excluir a antiga, ainda são 2 etapas simples.
Roee Gavirel
6

Fiz uma pergunta sobre a falha do servidor, tentando evitar o tempo de inatividade ao restaurar bancos de dados muito grandes usando o MySQL Proxy. Não tive sucesso, mas percebi no final o que eu queria era a funcionalidade RENAME DATABASE porque despejo / importação não era uma opção devido ao tamanho do nosso banco de dados.

Há uma funcionalidade RENAME TABLE embutida no MySQL, então acabei escrevendo um script Python simples para fazer o trabalho por mim. Eu o publiquei no GitHub , caso possa ser útil para outras pessoas.

cclark
fonte
2
RENAME DATABASE foi eliminado da sintaxe, não RENAME TABLE.
Duke
6

Para sua comodidade, abaixo está um pequeno shellscript que deve ser executado com dois parâmetros: db-name e new db-name.

Você pode precisar adicionar parâmetros de login às linhas do mysql se você não usar o arquivo .my.cnf no seu diretório home. Faça um backup antes de executar este script.


#!/usr/bin/env bash

mysql -e "CREATE DATABASE $2 DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;"
for i in $(mysql -Ns $1 -e "show tables");do
    echo "$1.$i -> $2.$i"
    mysql -e "rename TABLE $1.$i to $2.$i"
done
mysql -e "DROP DATABASE $1"
gerrit damen
fonte
1
Isso também não funcionará para tabelas com gatilhos anexados ou para exibições que não podem ser renomeadas para outros bancos de dados.
precisa saber é
6

Parece que ninguém mencionou isso, mas aqui está outra maneira:

create database NewDatabaseName like OldDatabaseName;

então, para cada tabela, faça:

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

então, se você quiser,

drop database OldDatabaseName;

Essa abordagem teria a vantagem de fazer toda a transferência no servidor com tráfego de rede quase zero, portanto, será muito mais rápido que um despejo / restauração.

Se você possui procedimentos / exibições / etc armazenados, convém transferi-los também.

Tuncay Göncüoğlu
fonte
2
Tanto quanto sei 5.x não suporta a palavra-chave "like" na create databasedeclaração? De onde você tirou isso?
Dragas
Aqui está o link para a create table likesintaxe: dev.mysql.com/doc/refman/5.7/en/create-table-like.html . Quanto à criação de banco de dados, parece que o MySQL abandonou essa cláusula desde então.
Tuncay Göncüoğlu
4

Aqui está uma maneira rápida de gerar um script sql de renomeação, se você tiver muitas tabelas para mover.

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
fonte
Parece bom, mas isso não move os procedimentos ou visualizações armazenados.
davidpricedev 23/01
você provavelmente deve adicionar marcas de hash para envolver o nome da tabela e esquema nome
Funkodebat
4

ALTER DATABASEé a maneira proposta para contornar isso pelo MySQL e RENAME DATABASEé descartada.

De 13.1.32 RENAME DATABASE Sintaxe :

RENAME {DATABASE | SCHEMA} db_name TO new_db_name;

Esta declaração foi adicionada no MySQL 5.1.7, mas foi considerada perigosa e foi removida no MySQL 5.1.23.

fancyPants
fonte
7
Você tem algum exemplo de sintaxe? Não conheço nenhuma maneira de alter databaserenomear o próprio banco de dados, e a documentação à qual você vinculou não sugere que seja possível.
Jordan
@ Jordan Eu também estaria interessado. Eu tentei, tentei e descobri que ele só funciona com a versão> 5.1, mas não posso atualizar no momento.
Fancypants
5
-1: Para escrever sobre as formas propostas, dê um exemplo da maneira não proposta enquanto estiver totalmente ausente para mostrar o exemplo.
hakre
3
Isto está errado. A documentação do banco de dados de renomeação do MySQL diz que rename_database foi destinado a uma tarefa de renomeação muito específica (não é o caso geral de renomeação de banco de dados), que agora é tratada com alter database: 'Para executar a tarefa de atualizar nomes de banco de dados com a nova codificação, use ALTER DATABASE db_name UPGRADE Em vez disso, NOME DO DIRETÓRIO DE DADOS 'Você não pode usar isso para renomear o banco de dados como desejar, não há nenhum lugar para o novo nome de banco de dados neste comando!
Kanat Bolazar
3

No MySQL Administrator, faça o seguinte:

  1. Em Catálogos, crie um novo esquema de banco de dados.
  2. Vá para Backup e crie um backup do esquema antigo.
  3. Execute o backup.
  4. Vá para Restaurar e abra o arquivo criado na etapa 3.
  5. Selecione 'Outro esquema' em Esquema de destino e selecione o novo esquema do banco de dados.
  6. Inicie a restauração.
  7. Verifique o novo esquema e, se parecer bom, exclua o antigo.
Tom
fonte
MySQL Administrator não pode lidar com grandes bases de dados e não há nada rápido sobre ele
deadprogrammer
3

no phpmyadmin você pode renomear facilmente o banco de dados

select database 

  goto operations tab

  in that rename Database to :

  type your new database name and click go

peça para soltar a tabela antiga e recarregar os dados da tabela, clique em OK nos dois

Seu banco de dados foi renomeado

murtaza.webdev
fonte
3

Se você estiver usando o phpMyAdmin, poderá ir para a guia "operações" depois de selecionar o banco de dados que deseja renomear. Em seguida, vá para a última seção "copiar banco de dados para" (ou algo parecido), dê um nome e selecione as opções abaixo. Nesse caso, acho que você deve selecionar as caixas de seleção "estrutura e dados" e "criar banco de dados antes de copiar" e, finalmente, pressionar o botão "ir" nessa seção.

A propósito, estou usando o phpMyAdmin em espanhol, então não tenho certeza de quais são os nomes das seções em inglês.

Peter Mortensen
fonte