Menduplikasi tabel, indeks, dan data MySQL


670

Bagaimana cara menyalin atau mengkloning atau menggandakan data, struktur, dan indeks tabel MySQL ke yang baru?

Inilah yang saya temukan sejauh ini.

Ini akan menyalin data dan struktur, tetapi bukan indeks:

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

Ini akan menyalin struktur dan indeks, tetapi bukan data:

create table {new_table} like {old_table};

Jawaban:


1489

Untuk menyalin dengan indeks dan pemicu lakukan 2 pertanyaan ini:

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

Untuk menyalin hanya struktur dan data gunakan yang ini:

CREATE TABLE tbl_new AS SELECT * FROM tbl_old;

Saya sudah menanyakan ini sebelumnya:

Salin tabel MySQL termasuk indeks


10
Patut dicatat bahwa kunci asing yang menunjuk ke oldtable perlu disalin ke tabel baru (jika Anda mengganti oldtable)
George

3
Apakah ini berfungsi untuk tabel besar (jutaan catatan)? .. Saya bertanya karena saya tidak tahu bagaimana ini select *akan bekerja di tabel besar.
fguillen

3
Untuk memberikan gambaran kasar, operasi penyisipan mengambil 27 menit pada tabel 16M baris (dengan 5 indeks) pada AWS db.r3. Contoh besar
hello_harry

6
Perlu dicatat bahwa sementara ini menciptakan kembali indeks dari tabel yang sedang disalin, itu tidak membawa kendala kunci asing.
WebSmithery

15
Catatan: Ini tidak akan menyalin AUTO_INCREMENTnilai.
Matt Janssen

43

Terlepas dari solusi di atas, Anda dapat menggunakannya ASuntuk membuatnya dalam satu baris.

CREATE TABLE tbl_new AS SELECT * FROM tbl_old;

32
Ini tidak akan menyalin indeks dan pemicu karena hasil SELECT adalah tabel sementara (tidak bernama) dan tidak "membawa" metadata dari tabel sumber. Pertimbangkan jika Anda akan menggunakan fungsi, itu tidak masuk akal.
chx

1
Saya sedang mencari cadangan tabel struktur dan hanya memindahkan data, sehingga menjatuhkan indeks / kendala / dll. jadi saya bisa membuatnya kembali. Jawaban ini luar biasa dalam hal melihat ketika Google mengirim saya ke sini.
Ellesedil

3
inilah tepatnya yang sudah dia sebutkan dalam pertanyaan: create table {new_table} select * from {old_table};bukan jawaban dan tidak memberikan informasi baru.
billynoah

14

Cara MySQL:

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

Ini seharusnya jawaban yang diterima. Karena ini menyalin semua indeks termasuk kunci primer dan auto_increment
Channaveer Hakari

10

Pergi ke phpMyAdmin dan pilih tabel asli Anda lalu pilih tab " Operations " di area " Copy table to (database.table) ". Pilih database tempat Anda ingin menyalin dan menambahkan nama untuk tabel baru Anda.

copy table - Screenshot phyMyAdmin


1
@AaronJSpetner Jawaban ini masih bermanfaat untuk pengguna lain yang datang ke pertanyaan ini dan dapat memanfaatkan PHPMyAdmin untuk menyelesaikan masalah.
direformasi

3

Saya menemukan situasi yang sama dan pendekatan yang saya ambil adalah sebagai berikut:

  1. Jalankan SHOW CREATE TABLE <table name to clone>: Ini akan memberi Anda Create Tablesintaks untuk tabel yang ingin Anda klon
  2. Jalankan CREATE TABLEkueri dengan mengubah nama tabel untuk mengkloning tabel.

Ini akan membuat replika tabel yang ingin Anda klon beserta indeksnya. Satu-satunya hal yang Anda butuhkan adalah mengubah nama indeks (jika diperlukan).


2

Cara yang lebih baik untuk menduplikasi tabel hanya menggunakan DDLpernyataan. Dengan cara ini, terlepas dari jumlah catatan dalam tabel, Anda dapat melakukan duplikasi secara instan.

Tujuan saya adalah:

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;

Ini menghindari INSERT AS SELECTpernyataan bahwa, dalam kasus tabel dengan banyak catatan dapat memakan waktu untuk dieksekusi.

Saya juga menyarankan untuk membuat prosedur PLSQL sebagai contoh berikut:

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 ;

Semoga harimu menyenangkan! Alex


Adakah yang sudah mencoba ini? Apakah itu berfungsi seperti yang diharapkan?
Radu Murzea

1

Memperluas jawaban ini, seseorang dapat menggunakan prosedur tersimpan:

CALL duplicate_table('tableName');

Yang akan menghasilkan tabel duplikat yang disebut tableName_20181022235959Jika dipanggil kapan

SELECT NOW();

hasil:

2018-10-22 23:59:59

Penerapan

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

Setelah saya mencoba solusi di atas, saya datang dengan cara saya sendiri.

Solusi saya sedikit manual dan membutuhkan DBMS.

Pertama, ekspor data.

Kedua, buka data ekspor.

Ketiga, ganti nama tabel lama dengan nama tabel baru.

Keempat, ubah semua nama pemicu dalam data (saya menggunakan MySQL dan itu menunjukkan kesalahan ketika saya tidak mengubah nama pemicu).

Kelima, impor data SQL Anda yang diedit ke database.


0

Coba ini :

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

Saya memilih 4 kolom dari tabel lama dan membuat tabel baru.


-2

UNTUK MySQL

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

UNTUK Penggunaan MSSQL MyDatabase:

Select * into newCustomersTable  from oldCustomersTable;

SQL ini digunakan untuk menyalin tabel, di sini konten oldCustomersTable akan disalin newCustomersTable.
Pastikan newCustomersTable tidak ada dalam database.


4
Thows error SQL Error (3172): Variabel yang tidak dideklarasikan: 'newCustomerTable'
mikewasmike

Anda pasti melakukan sesuatu yang salah. Karena ini akan bekerja 100%. Baca sebelum Anda memberikan suara negatif. Referensi konten untuk Anda. w3schools.com/sql/sql_select_into.asp
Krishneil

1
Perhatikan bahwa pertanyaannya adalah tentang MySQL. Beberapa sintaks SQL mungkin tidak didukung.
mikewasmike

1
Cara MySQL MENCIPTAKAN MEJA resep_new SEPERTI produksi.Resep; INSERT recipes_new SELECT * FROM production.recipes;
Krishneil

1
Saya telah mengedit pertanyaan saya karena jawaban sebelumnya hanya untuk MSSQLL
Krishneil
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.