MySQLテーブル、インデックス、データの複製


668

MySQLテーブルのデータ、構造、およびインデックスを新しいテーブルにコピー、複製、または複製するにはどうすればよいですか?

これは私がこれまでに見つけたものです。

これはデータと構造をコピーしますが、インデックスはコピーしません:

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

これは構造とインデックスをコピーしますが、データはコピーしません:

create table {new_table} like {old_table};

回答:


1487

インデックスとトリガーでコピーするには、次の2つのクエリを実行します。

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

構造とデータだけをコピーするには、次のコードを使用します。

CREATE TABLE tbl_new AS SELECT * FROM tbl_old;

私は以前にこれを尋ねました:

インデックスを含むMySQLテーブルをコピーする


10
oldtableを指す外部キーをnewtableにコピーする必要があることに注意してください(oldtableを置き換える場合)
George

3
これは大きなテーブル(何百万ものレコード)で機能しますか?..これselect *が巨大なテーブルでどのように機能するかわからないので、私は尋ねています。
fguillen 16

3
おおまかに言うと、AWS db.r3.largeインスタンスの16M行(インデックスが5つ)のテーブルで挿入操作に27分かかりました
hello_harry

6
これにより、コピーされるテーブルからインデックスが再作成されますが、外部キー制約は引き継がれませ
WebSmithery 2017

15
注:これはAUTO_INCREMENT値をコピーしません。
Matt Janssen

43

上記のソリューションとは別に、を使用ASして1行で作成できます。

CREATE TABLE tbl_new AS SELECT * FROM tbl_old;

32
SELECTの結果は(名前のない)一時テーブルであり、ソーステーブルのメタデータを「保持」しないため、これはインデックスとトリガーをコピーしません。関数を使用する場合は、意味がありません。
chx 2015

1
構造テーブルのバックアップとデータのみの移動を探していたため、インデックス/制約などを削除していました。だから私はそれらを再現することができました。この回答は、Googleがここに私を送ったのを見て、素晴らしかったです。
Ellesedil 2015

3
これはまさに彼が質問ですでに述べたもの create table {new_table} select * from {old_table};です。答えではなく、新しい情報を提供しません。
ビリーノア2017年

13

MySQLの方法:

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

これは受け入れられるべき答えでした。これにより、主キーとauto_incrementを含むすべてのインデックスがコピーされます
Channaveer Hakari

10

phpMyAdminに移動して元のテーブルを選択し、[ テーブルを(database.table)にコピー ] エリアの[ オペレーション ]タブを選択します。コピーするデータベースを選択し、新しいテーブルの名前を追加します。

テーブルのコピー-phyMyAdminスクリーンショット


1
@AaronJSpetnerこの回答は、この質問に来てPHPMyAdminを利用して問題を解決できる他のユーザーにとっても役立ちます。
改革

3

私は同じ状況を見つけ、私が取ったアプローチは次のとおりです:

  1. 実行SHOW CREATE TABLE <table name to clone>:これは、Create Tableクローンを作成するテーブルの構文を提供します
  2. CREATE TABLEテーブルの名前を変更してクエリを実行し、テーブルのクローンを作成します。

これにより、インデックスとともに複製するテーブルの正確なレプリカが作成されます。次に必要なのは、インデックスの名前を変更することだけです(必要な場合)。


2

テーブルを複製するより良い方法は、 DDLステートメントをことです。このようにして、テーブルのレコード数に関係なく、複製を即座に実行できます。

私の目的は:

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;

これINSERT AS SELECTにより、レコードが多いテーブルの場合、実行に時間がかかる可能性があるというステートメントが回避されます。

次の例のように、PLSQLプロシージャを作成することもお勧めします。

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 ;

ごきげんよう!アレックス


1

この答えを拡張すると、ストアドプロシージャを使用できます。

CALL duplicate_table('tableName');

これは、tableName_20181022235959次の場合に呼び出された場合に呼び出される重複テーブルになります

SELECT NOW();

結果:

2018-10-22 23:59:59

実装

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

上記の解決策を試した後、私は自分のやり方を思いつきました。

私のソリューションは少しマニュアルで、DBMSが必要です。

まず、データをエクスポートします。

次に、エクスポートデータを開きます。

3番目に、古いテーブル名を新しいテーブル名に置き換えます。

4番目に、データ内のすべてのトリガー名を変更します(MySQLを使用しており、トリガー名を変更しないとエラーが表示されます)。

5番目に、編集したSQLデータをデータベースにインポートします。


0

これを試して :

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

古いテーブルから4つの列を選択し、新しいテーブルを作成しました。


-2

MySQLの場合

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

MSSQLの使用MyDatabase

Select * into newCustomersTable  from oldCustomersTable;

このSQLはテーブルのコピーに使用されnewCustomersTableます。ここではoldCustomersTableの内容がにコピーされます。がデータベースに存在しない
ことを確認しnewCustomersTable ください。


4
ThowsエラーSQLエラー(3172):宣言されていない変数: 'newCustomerTable'
mikewasmike

あなたは何か間違ったことをしているに違いありません。これは100%動作します。反対票を投じる前に読んでください。あなたのためのコンテンツ参照。w3schools.com/sql/sql_select_into.asp
Krishneil 2016

1
質問はMySQLに関するものであることに注意してください。一部のSQL構文はサポートされていない場合があります。
mikewasmike 2016

1
MySQLウェイCREATE TABLE recipes_new LIKE production.recipes; INSERT recipes_new SELECT * FROM production.recipes;
Krishneil 2016

1
以前の回答はMSSQLLのみに対するものであったため、質問を編集しました
Krishneil
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.