MySQL tablosu, dizinler ve verileri çoğaltma


670

Bir MySQL tablosunun verilerini, yapısını ve indekslerini nasıl yenisiyle kopyalayabilir veya kopyalayabilirim?

Şimdiye kadar bulduğum şey bu.

Bu, verileri ve yapıyı kopyalar, ancak endeksleri kopyalamaz:

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

Bu, yapıyı ve dizinleri kopyalar, ancak verileri kopyalamaz:

create table {new_table} like {old_table};

Yanıtlar:


1489

Dizinler ve tetikleyicilerle kopyalamak için şu 2 sorguyu yapın:

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

Yalnızca yapı ve verileri kopyalamak için bunu kullanın:

CREATE TABLE tbl_new AS SELECT * FROM tbl_old;

Bunu daha önce sordum:

Dizinler içeren bir MySQL tablosu kopyalama


10
Oldtable'ı gösteren yabancı anahtarların newtable'a kopyalanması gerekeceğini belirtmek gerekir (eğer oldtable'ı değiştiriyorsanız)
George

3
Bu büyük tablolar (milyonlarca kayıt) için işe yarıyor mu? .. soruyorum çünkü bunun select *büyük tablolarda nasıl performans göstereceğini bilmiyorum .
fguillen

3
Kabaca bir fikir vermek için, ekleme işlemi bir AWS db.r3.large örneğinde 16M satırlık (5 dizinli) bir tabloya 27 dakika sürdü
hello_harry

6
Bu kopyalanan tablodan dizinleri yeniden ederken, bu mu dikkati çekiyor değil herhangi bir yabancı anahtar kısıtlamaları üzerinde taşır.
WebSmithery

15
Not: Bu, AUTO_INCREMENTdeğeri kopyalamaz .
Matt Janssen

43

Yukarıdaki çözümden ayrı olarak, AStek bir satırda yapmak için kullanabilirsiniz .

CREATE TABLE tbl_new AS SELECT * FROM tbl_old;

32
SELECT sonucu (adsız) geçici bir tablo olduğundan ve kaynak tablonun meta verilerini "taşımadığından" bu, dizinleri ve tetikleyicileri kopyalamaz. İşlevleri kullanıp kullanmadığınızı düşünün, bunun bir anlamı olmaz.
chx

1
Ben yapı tablosu yedekleme ve böylece sadece dizinleri / kısıtlamaları / vb bırakarak, veri taşımak bakıyordu. böylece onları yeniden yaratabilirdim. Bu cevap, Google'ın beni buraya gönderdiği için bu konuda harikaydı.
Ellesedil

3
tam olarak bu soruda bahsettiği şeydir: create table {new_table} select * from {old_table};bir cevap değil ve yeni bir bilgi sağlamıyor.
billynoah

14

MySQL yolu:

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

Bu kabul edilen cevap olmalıydı. Bu, birincil anahtar ve auto_increment dahil tüm dizinleri kopyalarken
Channaveer Hakari

10

PhpMyAdmin'e gidin ve orijinal tablonuzu seçin, ardından " Tabloyu (database.table) konumuna kopyala " alanında " İşlemler " sekmesini seçin . Kopyalamak istediğiniz veritabanını seçin ve yeni tablonuz için bir ad ekleyin.

kopya tablosu - phyMyAdmin Ekran Görüntüsü


1
@AaronJSpetner Bu cevap, bu soruya gelen ve sorunu çözmek için PHPMyAdmin kullanabilen diğer kullanıcılar için hala yararlıdır.
yeniden düzenlendi

3

Aynı durumu buldum ve aldığım yaklaşım şöyle:

  1. Yürüt SHOW CREATE TABLE <table name to clone>: Bu, Create Tableklonlamak istediğiniz tablonun sözdizimini verir
  2. CREATE TABLETabloyu klonlamak için tablo adını değiştirerek sorguyu çalıştırın .

Bu, dizinlerle birlikte klonlamak istediğiniz tablonun tam kopyasını oluşturur. Daha sonra ihtiyacınız olan tek şey dizinleri yeniden adlandırmaktır (gerekirse).


2

Bir tabloyu çoğaltmanın en iyi yolu yalnızca DDLdeyim kullanmaktır . Bu şekilde, tablodaki kayıt sayısından bağımsız olarak, çoğaltmayı anında gerçekleştirebilirsiniz.

Amacım:

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;

Bu, INSERT AS SELECTçok fazla kayıt içeren bir tablonun yürütülmesi için zaman alabileceği ifadesini önler .

Ayrıca aşağıdaki örnekte bir PLSQL yordamı oluşturmayı öneririm:

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 ;

İyi günler! Alex


Bunu deneyen var mı? Beklendiği gibi çalışıyor mu?
Radu Murzea

1

Bu cevabı genişletmek saklı bir yordamı kullanabilir:

CALL duplicate_table('tableName');

Bu, tableName_20181022235959ne zaman çağrılırsa adlı adlı yinelenen bir tabloyla sonuçlanır

SELECT NOW();

Sonuçlar:

2018-10-22 23:59:59

uygulama

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

Yukarıdaki çözümü denedikten sonra kendi yolumu buluyorum.

Benim çözüm biraz manuel ve DBMS gerekiyor.

İlk olarak, verileri dışa aktarın.

İkinci olarak, dışa aktarma verilerini açın.

Üçüncü olarak, eski tablo adını yeni tablo adıyla değiştirin.

Dördüncü olarak, verilerdeki tüm tetikleyici adını değiştirin (MySQL kullanıyorum ve tetikleyici adını değiştirmediğimde hata gösteriyor).

Beşinci olarak, düzenlenen SQL verilerinizi veritabanına alın.


0

Bunu dene :

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

Eski tablodan 4 sütun seçtim ve yeni bir tablo yaptım.


-2

MySQL İÇİN

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

MSSQL İÇİN MyDatabase:

Select * into newCustomersTable  from oldCustomersTable;

Bu SQL tabloları kopyalamak için kullanılır, burada oldCustomersTable içeriği kopyalanacaktır newCustomersTable.
Emin olun newCustomersTable gelmez veritabanında mevcut.


4
Thows error SQL Error (3172): Bildirilmemiş değişken: 'newCustomerTable'
mikewasmike

Yanlış bir şey yapıyor olmalısın. Bu% 100 çalışacağından. Olumsuz oy vermeden önce okuyun. Sizin için içerik referansı. w3schools.com/sql/sql_select_into.asp
Krishneil

1
Sorunun MySQL ile ilgili olduğunu unutmayın. Bazı SQL sözdizimi desteklenmeyebilir.
mikewasmike

1
MySQL Yolu TABLO OLUŞTURUN recipes_new LIKE production.recipes; INSERT tarifleri_yeni SELECT * FROM production.recipes;
Krishneil

1
Önceki cevap sadece MSSQLL
Krishneil
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.