Duplicazione di una tabella MySQL, indici e dati


670

Come faccio a copiare, clonare o duplicare i dati, la struttura e gli indici di una tabella MySQL in una nuova?

Questo è quello che ho trovato finora.

Questo copierà i dati e la struttura, ma non gli indici:

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

Questo copierà la struttura e gli indici, ma non i dati:

create table {new_table} like {old_table};

Risposte:


1489

Per copiare con indici e trigger, esegui queste 2 query:

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

Per copiare solo struttura e dati usa questo:

CREATE TABLE tbl_new AS SELECT * FROM tbl_old;

L'ho già chiesto prima:

Copia una tabella MySQL inclusi gli indici


10
Vale la pena notare che le chiavi esterne che puntano a oldtable dovranno essere copiate su newtable (se si sostituisce oldtable)
George,

3
Funziona per i grandi tavoli (milioni di dischi)? .. Lo sto chiedendo perché non so come select *funzionerà in tavoli enormi.
fguillen,

3
Per dare un'idea approssimativa, l'operazione di inserimento ha richiesto 27 minuti su una tabella di 16 milioni di righe (con 5 indici) su un'istanza AWS db.r3.large
hello_harry

6
Vale la pena notare che mentre ricrea gli indici dalla tabella da copiare, non comporta alcun vincolo di chiave esterna.
WebSmithery,

15
Nota: questo non copia il AUTO_INCREMENTvalore.
Matt Janssen,

43

Oltre alla soluzione sopra, è possibile utilizzare ASper farlo in una riga.

CREATE TABLE tbl_new AS SELECT * FROM tbl_old;

32
Ciò non copierà gli indici e i trigger poiché il risultato SELECT è una tabella temporanea (senza nome) e non "trasporta" i metadati della tabella di origine. Considera se utilizzeresti delle funzioni, non avrebbe senso.
chx,

1
Stavo cercando di eseguire il backup della tabella della struttura e spostare solo i dati, lasciando cadere indici / vincoli / ecc. così potrei ricrearli. Questa risposta è stata fantastica al riguardo visto che Google mi ha inviato qui.
Ellesedil,

3
questo è esattamente ciò che menziona già nella domanda: create table {new_table} select * from {old_table};non una risposta e non fornisce nuove informazioni.
Billynoah,

14

Modo MySQL:

CREATE TABLE recipes_new LIKE production.recipes;
INSERT recipes_new SELECT * FROM production.recipes;

Questa avrebbe dovuto essere la risposta accettata. Poiché questo copia tutti gli indici tra cui chiave primaria e auto_increment
Channaveer Hakari,

10

Vai a phpMyAdmin e seleziona la tabella originale, quindi seleziona la scheda " Operazioni " nell'area " Copia tabella in (database.table) ". Seleziona il database in cui desideri copiare e aggiungi un nome per la tua nuova tabella.

copia tabella - Screenshot di phyMyAdmin


1
@AaronJSpetner Questa risposta è ancora utile per gli altri utenti che vengono a questa domanda e sono in grado di utilizzare PHPMyAdmin per risolvere il problema.
riformato il

3

Ho trovato la stessa situazione e l'approccio adottato è stato il seguente:

  1. Esegui SHOW CREATE TABLE <table name to clone>: questo ti darà la Create Tablesintassi per la tabella che vuoi clonare
  2. Eseguire la CREATE TABLEquery modificando il nome della tabella per clonare la tabella.

Ciò creerà la replica esatta della tabella che si desidera clonare insieme agli indici. L'unica cosa di cui hai bisogno è di rinominare gli indici (se necessario).


2

Il modo migliore per duplicare una tabella sta usando solo l' DDListruzione. In questo modo, indipendentemente dal numero di record nella tabella, è possibile eseguire immediatamente la duplicazione.

Il mio scopo è:

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;

Questo evita l' INSERT AS SELECTaffermazione che, nel caso di una tabella con molti record, può richiedere del tempo per essere eseguita.

Suggerisco anche di creare una procedura PLSQL come nell'esempio seguente:

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 ;

Buona giornata! alex


Qualcuno ha provato questo? Funziona come previsto?
Radu Murzea,

1

Espandendo su questa risposta si potrebbe usare una procedura memorizzata:

CALL duplicate_table('tableName');

Il che si tradurrà in una tabella duplicata chiamata tableName_20181022235959Se chiamato quando

SELECT NOW();

i risultati:

2018-10-22 23:59:59

Implementazione

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 ;

1

Dopo aver provato la soluzione sopra, mi viene in mente la mia strada.

La mia soluzione è un po 'manuale e necessita di DBMS.

Innanzitutto, esporta i dati.

In secondo luogo, aprire i dati di esportazione.

In terzo luogo, sostituire il vecchio nome della tabella con il nuovo nome della tabella.

In quarto luogo, modifica tutto il nome del trigger nei dati (uso MySQL e mostra errore quando non cambio il nome del trigger).

In quinto luogo, importare i dati SQL modificati nel database.


0

Prova questo :

`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;`

Ho selezionato 4 colonne dalla tabella precedente e ho creato una nuova tabella.


-2

PER MySQL

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

PER MSSQL Utilizzare MyDatabase:

Select * into newCustomersTable  from oldCustomersTable;

Questo SQL viene utilizzato per la copia di tabelle, qui verrà copiato il contenuto di oldCustomersTable newCustomersTable.
Assicurarsi che newCustomersTable non esista nel database.


4
Errore di SQL Errore (3172): Variabile non dichiarata: 'newCustomerTable'
mikewasmike

Stai facendo qualcosa di sbagliato. Dato che funzionerà al 100%. Leggi prima di dare un voto negativo. Riferimento contenuto per te. w3schools.com/sql/sql_select_into.asp
Krishneil

1
Si noti che la domanda riguarda MySQL. Alcune sintassi SQL potrebbero non essere supportate.
mikewasmike,

1
MySQL Way CREATE TABLE recipes_ne LIKE production.recipes; INSERISCI ricette_nuovo SELEZIONA * DA production.recipes;
Krishneil,

1
Ho modificato la mia domanda poiché la risposta precedente era solo per MSSQLL
Krishneil,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.