Duplicar uma tabela, índices e dados do MySQL

670

Como copiar, clonar ou duplicar os dados, estrutura e índices de uma tabela MySQL para uma nova?

Isto é o que eu encontrei até agora.

Isso copiará os dados e a estrutura, mas não os índices:

create table {new_table} select * from {old_table};

Isso copiará a estrutura e os índices, mas não os dados:

create table {new_table} like {old_table};
xkcd150
fonte

Respostas:

1489

Para copiar com índices e gatilhos, faça estas 2 consultas:

CREATE TABLE newtable LIKE oldtable; 
INSERT INTO newtable SELECT * FROM oldtable;

Para copiar apenas estrutura e dados, use este:

CREATE TABLE tbl_new AS SELECT * FROM tbl_old;

Eu perguntei isso antes:

Copie uma tabela MySQL incluindo índices

Haim Evgi
fonte
10
Vale notar que as chaves estrangeiras apontando para necessidade vontade OldTable a serem copiados para newtable (se você estiver substituindo OldTable)
George
3
Isso funciona para tabelas grandes (milhões de registros)? .. Estou perguntando porque não sei como isso select *será executado em tabelas enormes.
Fevillen
3
Para dar uma idéia, a operação de inserção levou 27mins em uma tabela de linhas 16M (com 5 índices) em uma instância db.r3.large AWS
hello_harry
6
Vale a pena notar que, enquanto isso recria os índices da tabela que está sendo copiada, não carrega nenhuma restrição de chave estrangeira.
WebSmithery
15
Nota: Isso não copiará o AUTO_INCREMENTvalor.
Matt Janssen
43

Além da solução acima, você pode usá AS-la em uma linha.

CREATE TABLE tbl_new AS SELECT * FROM tbl_old;
theDistantStar
fonte
32
Isso não copiará índices e disparadores, pois o resultado SELECT é uma tabela temporária (sem nome) e não "carrega" os metadados da tabela de origem. Considere se você estivesse usando funções, não faria sentido.
Chx
1
Eu estava procurando fazer backup da tabela de estrutura e mover apenas os dados, eliminando índices / restrições / etc. para que eu pudesse recriá-los. Essa resposta foi incrível, pois o Google me enviou aqui.
Ellesedil
3
isto é exatamente o que ele já menciona na pergunta: create table {new_table} select * from {old_table}; não é uma resposta e não fornece novas informações.
precisa saber é
14

Maneira MySQL:

CREATE TABLE recipes_new LIKE production.recipes;
INSERT recipes_new SELECT * FROM production.recipes;
Krishneil
fonte
Essa deveria ter sido a resposta aceita. Como tudo isso copia os índices incluindo chave primária e auto_increment
Channaveer Hakari
10

Vá para phpMyAdmin e selecione sua tabela original e selecione a guia " Operações " na área " Copiar tabela para (database.table) ". Selecione o banco de dados onde deseja copiar e adicione um nome para sua nova tabela.

copiar tabela - Screenshot do phyMyAdmin

spuvi86
fonte
1
@AaronJSpetner Esta resposta ainda é útil para outros usuários que chegam a esta pergunta e podem utilizar o PHPMyAdmin para resolver o problema.
reformada em
3

Encontrei a mesma situação e a abordagem adotada foi a seguinte:

  1. Executar SHOW CREATE TABLE <table name to clone>: Isso fornecerá a Create Tablesintaxe da tabela que você deseja clonar
  2. Execute a CREATE TABLEconsulta alterando o nome da tabela para clonar a tabela.

Isso criará uma réplica exata da tabela que você deseja clonar junto com os índices. A única coisa que você precisa é renomear os índices (se necessário).

Jai
fonte
2

A melhor maneira de duplicar uma tabela é usando apenas DDL instrução Dessa forma, independentemente do número de registros na tabela, você pode executar a duplicação instantaneamente.

Meu objetivo é:

DROP TABLE IF EXISTS table_name_OLD;
CREATE TABLE table_name_NEW LIKE table_name;
RENAME TABLE table_name TO table_name_OLD;
RENAME TABLE table_name _NEW TO table_name;

Isso evita a INSERT AS SELECTafirmação de que, no caso de tabela com muitos registros, pode levar tempo para ser executado.

Sugiro também criar um procedimento PLSQL como o exemplo a seguir:

DELIMITER //
CREATE PROCEDURE backup_table(tbl_name varchar(255))
BEGIN
  -- DROP TABLE IF EXISTS GLS_DEVICES_OLD;
  SET @query = concat('DROP TABLE IF EXISTS ',tbl_name,'_OLD');
  PREPARE stmt FROM @query;
  EXECUTE stmt;
  DEALLOCATE PREPARE stmt;

  -- CREATE TABLE GLS_DEVICES_NEW LIKE GLS_DEVICES;
  SET @query = concat('CREATE TABLE ',tbl_name,'_NEW LIKE ',tbl_name);
  PREPARE stmt FROM @query;
  EXECUTE stmt;
  DEALLOCATE PREPARE stmt;

  -- RENAME TABLE GLS_DEVICES TO GLS_DEVICES_OLD;
  SET @query = concat('RENAME TABLE ',tbl_name,' TO ',tbl_name,'_OLD');
  PREPARE stmt FROM @query;
  EXECUTE stmt;
  DEALLOCATE PREPARE stmt;  

  --  RENAME TABLE GLS_DEVICES_NEW TO GLS_DEVICES;
  SET @query = concat('RENAME TABLE ',tbl_name,'_NEW TO ',tbl_name);
  PREPARE stmt FROM @query;
  EXECUTE stmt;
  DEALLOCATE PREPARE stmt; 
END//
DELIMITER ;

Tenha um bom dia! Alex

Alessandro
fonte
alguem ja tentou isso? Funciona como esperado?
Radu Murzea
1

Expandindo esta resposta, pode-se usar um procedimento armazenado:

CALL duplicate_table('tableName');

O que resultará em uma tabela duplicada chamada tableName_20181022235959Se chamada quando

SELECT NOW();

resultados:

2018-10-22 23:59:59

Implementação

DELIMITER $$
CREATE PROCEDURE duplicate_table(IN tableName VARCHAR(255))
  BEGIN
    DECLARE schemaName VARCHAR(255) DEFAULT SCHEMA();
    DECLARE today VARCHAR(14) DEFAULT REPLACE(REPLACE(REPLACE(NOW(), '-', ''), ' ', ''), ':', ''); -- update @ year 10000
    DECLARE backupTableName VARCHAR(255) DEFAULT CONCAT(tableName, '_', today);

    IF fn_table_exists(schemaName, tableName)
      THEN
        CALL statement(CONCAT('CREATE TABLE IF NOT EXISTS ', backupTableName,' LIKE ', tableName));
        CALL statement(CONCAT('INSERT INTO ', backupTableName,' SELECT * FROM ', tableName));
        CALL statement(CONCAT('CHECKSUM TABLE ', backupTableName,', ', tableName));
      ELSE
        SELECT CONCAT('ERROR: Table "', tableName, '" does not exist in the schema "', schemaName, '".') AS ErrorMessage;
      END IF;
  END $$
DELIMITER ;

DELIMITER $$
CREATE FUNCTION fn_table_exists(schemaName VARCHAR(255), tableName VARCHAR(255))
  RETURNS TINYINT(1)
  BEGIN
    DECLARE totalTablesCount INT DEFAULT (
      SELECT COUNT(*)
      FROM information_schema.TABLES
      WHERE (TABLE_SCHEMA COLLATE utf8_general_ci = schemaName COLLATE utf8_general_ci)
        AND (TABLE_NAME COLLATE utf8_general_ci = tableName COLLATE utf8_general_ci)
    );
    RETURN IF(
      totalTablesCount > 0,
      TRUE,
      FALSE
    );
  END $$
DELIMITER ;

DELIMITER $$
CREATE PROCEDURE statement(IN dynamic_statement TEXT)
  BEGIN
      SET @dynamic_statement := dynamic_statement;
      PREPARE prepared_statement FROM @dynamic_statement;
      EXECUTE prepared_statement;
      DEALLOCATE PREPARE prepared_statement;
  END $$
DELIMITER ;
Nae
fonte
1

Depois de experimentar a solução acima, criei meu próprio caminho.

Minha solução é um pouco manual e precisa de DBMS.

Primeiro, exporte os dados.

Segundo, abra os dados de exportação.

Terceiro, substitua o nome antigo da tabela pelo novo nome da tabela.

Quarto, altere todo o nome do acionador nos dados (eu uso o MySQL e ele mostra erro quando não altero o nome do acionador).

Quinto, importe seus dados SQL editados para o banco de dados.

Võ Minh
fonte
0

Tente o seguinte:

`CREATE TABLE new-table (id INT(11) auto_increment primary key) SELECT old-table.name, old-table.group, old-table.floor, old-table.age from old-table;`

Selecionei 4 colunas da tabela antiga e criei uma nova tabela.

Crazy_DT0
fonte
-2

PARA MySQL

CREATE TABLE newtable LIKE oldtable ; 
INSERT newtable SELECT * FROM oldtable ;

PARA MSSQL Use MyDatabase:

Select * into newCustomersTable  from oldCustomersTable;

Este SQL é usado para copiar tabelas, aqui o conteúdo de oldCustomersTable será copiado para newCustomersTable.
Verifique se newCustomersTable não existe no banco de dados.

Krishneil
fonte
4
Erro de erro SQL (3172): Variável não declarada: 'newCustomerTable'
mikewasmike
Você deve estar fazendo algo errado. Como isso funcionará 100%. Leia antes de dar um voto negativo. Referência de conteúdo para você. w3schools.com/sql/sql_select_into.asp
Krishneil
1
Observe que a pergunta é sobre o MySQL. Algumas sintaxes SQL podem não ser suportadas.
mikewasmike
1
MySQL Way CREATE TABLE recipes_new COMO production.recipes; INSERIR recipes_new SELECT * FROM production.recipes;
Krishneil
1
Eu editei minha pergunta, pois a resposta anterior era apenas para MSSQLL
Krishneil 3/17/17