Duplicar una tabla MySQL, índices y datos

670

¿Cómo copio, clono o duplico los datos, la estructura y los índices de una tabla MySQL en una nueva?

Esto es lo que he encontrado hasta ahora.

Esto copiará los datos y la estructura, pero no los índices:

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

Esto copiará la estructura y los índices, pero no los datos:

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

Respuestas:

1489

Para copiar con índices y disparadores, haga estas 2 consultas:

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

Para copiar solo la estructura y los datos, use este:

CREATE TABLE tbl_new AS SELECT * FROM tbl_old;

He preguntado esto antes:

Copie una tabla MySQL que incluya índices

Haim Evgi
fuente
10
Vale la pena señalar que las claves foráneas que apuntan a oldtable deberán copiarse en newtable (si está reemplazando oldtable)
George
3
¿Funciona para tablas grandes (millones de registros)? Pregunto porque no sé cómo funcionará esto select *en tablas grandes.
fguillen
3
Para dar una idea aproximada, la operación de inserción tomó 27 minutos en una tabla de 16 millones de filas (con 5 índices) en una instancia de AWS db.r3.large
hello_harry
66
Vale la pena señalar que si bien esto recrea los índices de la tabla que se está copiando, no transfiere ninguna restricción de clave externa.
WebSmithery
15
Nota: Esto no copiará el AUTO_INCREMENTvalor.
Matt Janssen
43

Además de la solución anterior, puede usar ASpara hacerlo en una línea.

CREATE TABLE tbl_new AS SELECT * FROM tbl_old;
theDistantStar
fuente
32
Esto no copiará índices y disparadores ya que el resultado SELECCIONAR es una tabla temporal (sin nombre) y no "transporta" los metadatos de la tabla fuente. Considere si estaría usando funciones, no tendría sentido.
chx
1
Estaba buscando hacer una copia de seguridad de la tabla de estructura y mover solo los datos, dejando caer índices / restricciones / etc. para poder recrearlos Esta respuesta fue increíble en lo que respecta a ver como Google me envió aquí.
Ellesedil
3
esto es exactamente lo que ya menciona en la pregunta: create table {new_table} select * from {old_table};no es una respuesta y no proporciona información nueva.
billynoah
14

Manera MySQL:

CREATE TABLE recipes_new LIKE production.recipes;
INSERT recipes_new SELECT * FROM production.recipes;
Krishneil
fuente
Esta debería haber sido la respuesta aceptada. Como esto copia todos los índices, incluida la clave principal y el aumento automático
Channaveer Hakari
10

Vaya a phpMyAdmin y seleccione su tabla original, luego seleccione la pestaña " Operaciones " en el área " Copiar tabla a (database.table) ". Seleccione la base de datos donde desea copiar y agregue un nombre para su nueva tabla.

copiar tabla - Captura de pantalla de phyMyAdmin

spuvi86
fuente
1
@AaronJSpetner Esta respuesta sigue siendo útil para otros usuarios que llegan a esta pregunta y pueden utilizar PHPMyAdmin para resolver el problema.
reformado el
3

Encontré la misma situación y el enfoque que tomé fue el siguiente:

  1. Ejecutar SHOW CREATE TABLE <table name to clone>: esto le dará la Create Tablesintaxis de la tabla que desea clonar
  2. Ejecute la CREATE TABLEconsulta cambiando el nombre de la tabla para clonarla.

Esto creará una réplica exacta de la tabla que desea clonar junto con los índices. Lo único que necesita es cambiar el nombre de los índices (si es necesario).

Jai
fuente
2

La mejor manera de duplicar una tabla es usar solo DDLinstrucciones. De esta forma, independientemente del número de registros en la tabla, puede realizar la duplicación al instante.

Mi proposito es:

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;

Esto evita la INSERT AS SELECTafirmación de que, en el caso de una tabla con muchos registros, puede llevar tiempo ejecutarla.

Sugiero también crear un procedimiento PLSQL como el siguiente ejemplo:

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 ;

¡Que tengas un buen día! Alex

Alessandro
fuente
¿Alguien ha probado esto? ¿Funciona como se esperaba?
Radu Murzea
1

Ampliando esta respuesta, uno podría usar un procedimiento almacenado:

CALL duplicate_table('tableName');

Lo que dará como resultado una tabla duplicada llamada tableName_20181022235959If if when

SELECT NOW();

resultados:

2018-10-22 23:59:59

Implementación

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
fuente
1

Después de probar la solución anterior, ideé mi propio camino.

Mi solución es un pequeño manual y necesita DBMS.

Primero, exportar los datos.

En segundo lugar, abra los datos de exportación.

Tercero, reemplace el nombre de la tabla anterior con el nombre de la tabla nueva.

Cuarto, cambie todo el nombre del disparador en los datos (uso MySQL y muestra un error cuando no cambio el nombre del disparador).

Quinto, importe sus datos SQL editados a la base de datos.

Võ Minh
fuente
0

Prueba esto :

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

Seleccioné 4 columnas de la tabla antigua e hice una tabla nueva.

Crazy_DT0
fuente
-2

PARA MySQL

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

PARA USO DE MSSQL MyDatabase:

Select * into newCustomersTable  from oldCustomersTable;

Este SQL se usa para copiar tablas, aquí se copiará el contenido de oldCustomersTable newCustomersTable.
Asegúrese de que newCustomersTable no exista en la base de datos.

Krishneil
fuente
44
Error de Thows Error de SQL (3172): variable no declarada: 'newCustomerTable'
mikewasmike
Debes estar haciendo algo mal. Como esto funcionará al 100%. Lea antes de dar un voto negativo. Referencia de contenido para ti. w3schools.com/sql/sql_select_into.asp
Krishneil
1
Tenga en cuenta que la pregunta es sobre MySQL. Algunas sintaxis SQL pueden no ser compatibles.
mikewasmike
1
MySQL Way CREATE TABLE recetas_nuevo COMO producción.recipes; INSERTAR recetas_nuevo SELECCIONAR * DESDE producción.recipes;
Krishneil
1
He editado mi pregunta ya que la respuesta anterior era solo para MSSQLL
Krishneil