Duplication d'une table, d'index et de données MySQL

670

Comment copier, cloner ou dupliquer les données, la structure et les index d'une table MySQL vers une nouvelle?

C'est ce que j'ai trouvé jusqu'à présent.

Cela copiera les données et la structure, mais pas les indices:

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

Cela copiera la structure et les indices, mais pas les données:

create table {new_table} like {old_table};
xkcd150
la source

Réponses:

1489

Pour copier avec des index et des déclencheurs, faites ces 2 requêtes:

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

Pour copier simplement la structure et les données, utilisez celui-ci:

CREATE TABLE tbl_new AS SELECT * FROM tbl_old;

J'ai déjà posé cette question:

Copiez une table MySQL avec des index

Haim Evgi
la source
10
Il convient de noter que les clés étrangères pointant vers oldtable devront être copiées dans newtable (si vous remplacez oldtable)
George
3
Est-ce que cela fonctionne pour les grandes tables (des millions d'enregistrements)? .. Je demande parce que je ne sais pas comment cela select *fonctionnera dans les tables énormes.
fguillen
3
Pour donner une idée approximative, l'opération d'insertion a pris 27 minutes sur une table de 16 millions de lignes (avec 5 index) sur une instance AWS db.r3.large
hello_harry
6
Il est intéressant de noter que si cette recrée les index de la table copie, il ne pas porter sur toutes les clés étrangères.
WebSmithery
15
Remarque: cela ne copiera pas la AUTO_INCREMENTvaleur.
Matt Janssen
43

En dehors de la solution ci-dessus, vous pouvez utiliser ASpour le faire en une seule ligne.

CREATE TABLE tbl_new AS SELECT * FROM tbl_old;
theDistantStar
la source
32
Cela ne copiera pas les index et les déclencheurs car le résultat SELECT est une table temporaire (sans nom) et ne "transporte" pas les métadonnées de la table source. Considérez que si vous utilisiez des fonctions, cela n'aurait aucun sens.
chx
1
Je cherchais à sauvegarder la table de structure et à déplacer les données uniquement, supprimant ainsi les index / contraintes / etc. afin que je puisse les recréer. Cette réponse était impressionnante à cet égard, car Google m'a envoyé ici.
Ellesedil
3
c'est exactement ce qu'il mentionne déjà dans la question: create table {new_table} select * from {old_table};pas de réponse et ne donne aucune nouvelle information.
billynoah
14

Façon MySQL:

CREATE TABLE recipes_new LIKE production.recipes;
INSERT recipes_new SELECT * FROM production.recipes;
Krishneil
la source
Cela aurait dû être la réponse acceptée. Comme cela copie tous les index, y compris la clé primaire et
auto_increment
10

Accédez à phpMyAdmin et sélectionnez votre table d'origine, puis sélectionnez l' onglet " Opérations " dans la zone " Copier la table vers (database.table) ". Sélectionnez la base de données où vous souhaitez copier et ajoutez un nom pour votre nouvelle table.

copier la table - Capture d'écran de phyMyAdmin

spuvi86
la source
1
@AaronJSpetner Cette réponse est toujours utile pour les autres utilisateurs qui viennent à cette question et sont capables d'utiliser PHPMyAdmin pour résoudre le problème.
réformé
3

J'ai trouvé la même situation et l'approche que j'ai adoptée était la suivante:

  1. Exécuter SHOW CREATE TABLE <table name to clone>: cela vous donnera la Create Tablesyntaxe de la table que vous souhaitez cloner
  2. Exécutez la CREATE TABLErequête en modifiant le nom de la table pour cloner la table.

Cela créera une réplique exacte de la table que vous souhaitez cloner avec les index. La seule chose dont vous avez alors besoin est de renommer les index (si nécessaire).

I have
la source
2

La meilleure façon de dupliquer une table utilise uniquement l' DDLinstruction. De cette façon, indépendamment du nombre d'enregistrements dans la table, vous pouvez effectuer la duplication instantanément.

Mon but est:

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;

Cela évite l' INSERT AS SELECTaffirmation selon laquelle, dans le cas d'une table avec beaucoup d'enregistrements, l'exécution peut prendre du temps.

Je suggère également de créer une procédure PLSQL comme l'exemple suivant:

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 ;

Bonne journée! Alex

Alessandro
la source
Quelqu'un at-il essayé cela? Fonctionne-t-il comme prévu?
Radu Murzea
1

En développant cette réponse, on pourrait utiliser une procédure stockée:

CALL duplicate_table('tableName');

Ce qui se traduira par une table en double appelée tableName_20181022235959Si appelé lorsque

SELECT NOW();

résultats:

2018-10-22 23:59:59

la mise en oeuvre

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
la source
1

Après avoir essayé la solution ci-dessus, je trouve ma propre voie.

Ma solution un peu manuelle et a besoin d'un SGBD.

Tout d'abord, exportez les données.

Ensuite, ouvrez les données d'exportation.

Troisièmement, remplacez l'ancien nom de table par un nouveau nom de table.

Quatrièmement, changez tout le nom du déclencheur dans les données (j'utilise MySQL et cela affiche une erreur lorsque je ne change pas le nom du déclencheur).

Cinquièmement, importez vos données SQL modifiées dans la base de données.

Võ Minh
la source
0

Essaye ça :

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

J'ai sélectionné 4 colonnes de l'ancienne table et créé une nouvelle table.

Crazy_DT0
la source
-2

POUR MySQL

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

POUR UTILISATION MSSQL MyDatabase:

Select * into newCustomersTable  from oldCustomersTable;

Ce SQL est utilisé pour copier des tables, ici le contenu de oldCustomersTable sera copié newCustomersTable.
Assurez-vous que le newCustomersTable n'existe pas dans la base de données.

Krishneil
la source
4
Thows error Erreur SQL (3172): Variable non déclarée: 'newCustomerTable'
mikewasmike
Vous devez faire quelque chose de mal. Comme cela fonctionnera à 100%. Lisez avant de donner un vote négatif. Référence de contenu pour vous. w3schools.com/sql/sql_select_into.asp
Krishneil
1
Notez que la question concerne MySQL. Certaines syntaxes SQL peuvent ne pas être prises en charge.
mikewasmike
1
MySQL Way CREATE TABLE recipes_new LIKE production.recipes; INSERT recipes_new SELECT * FROM production.recipes;
Krishneil
1
J'ai modifié ma question car la réponse précédente ne concernait que MSSQLL
Krishneil