Дублювання таблиці MySQL, індексів та даних


669

Як скопіювати або клонувати або дублювати дані, структуру та індекси таблиці MySQL до нової?

Це те, що я знайшов поки що.

Це скопіює дані та структуру, але не індекси:

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

Це скопіює структуру та індекси, але не дані:

create table {new_table} like {old_table};

Відповіді:


1488

Для копіювання за допомогою індексів та тригерів виконайте ці 2 запити:

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

Щоб скопіювати лише структуру та дані, використовуйте це:

CREATE TABLE tbl_new AS SELECT * FROM tbl_old;

Я вже про це питав:

Скопіюйте таблицю MySQL, включаючи індекси


10
Варто зауважити, що закордонні ключі, що вказують на стару таблицю, потрібно буде скопіювати до нової таблиці (якщо ви замінюєте стару таблицю)
Джордж

3
Це працює для великих таблиць (мільйонів записів)? .. Я запитую, тому що я не знаю, як це select *буде працювати у величезних таблицях.
fguillen

3
Щоб дати грубу ідею, операція вставки зайняла 27 хвилин на таблиці 16М рядків (з 5 індексами) на екземплярі AWS db.r3.large
hello_harry

6
Варто зазначити, що, хоча це відтворює індекси зі скопійованої таблиці, воно не переносить жодних зовнішніх ключових обмежень.
WebSmithery

15
Примітка. Це значення не буде копіювати AUTO_INCREMENT.
Метт Янссен

43

Окрім рішення, наведеного вище, ви можете використовувати його ASдля виготовлення в один рядок.

CREATE TABLE tbl_new AS SELECT * FROM tbl_old;

32
Це не буде копіювати індекси та тригери, оскільки результат SELECT є (безіменною) тимчасовою таблицею та не "несе" метадані вихідної таблиці. Подумайте, якщо ви використовуєте функції, це не має сенсу.
chx

1
Я шукав резервне копіювання таблиці структури та переміщував лише дані, тим самим відкидаючи індекси / обмеження / тощо. щоб я міг їх відтворити. Ця відповідь була дивовижною з цього приводу, коли Google мене сюди надіслав.
Ellesedil

3
саме про це він вже згадує у запитанні: create table {new_table} select * from {old_table};не відповідь і не дає нової інформації.
billynoah

14

MySQL спосіб:

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

Це мала бути прийнятою відповіддю. Оскільки це копіює всі індекси, включаючи первинний ключ та auto_increment
Channaveer Hakari

10

Перейдіть до phpMyAdmin і виберіть оригінальну таблицю, а потім виберіть вкладку " Операції " в області " Копіювати таблицю в (таблиця баз даних) ". Виберіть базу даних, куди потрібно скопіювати, та додайте ім’я для своєї нової таблиці.

таблиця копіювання - Скріншот 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

Після того, як я спробував рішення вище, я придумав власний шлях.

Моє рішення трохи посібник і потребує СУБД.

Спочатку експортуйте дані.

По-друге, відкрийте дані про експорт.

По-третє, замініть стару назву таблиці новою назвою таблиці.

По-четверте, змінити все ім'я тригера в даних (я використовую MySQL, і він показує помилку, коли я не змінюю ім'я тригера).

По-п’яте, імпортуйте відредаговані дані 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 використовується для копіювання таблиць, сюди буде скопійовано вміст oldCustomersTable newCustomersTable.
Переконайтеся , що newCustomersTable НЕ існує в базі даних.


4
Помилка помилки SQL (3172): Недекларована змінна: 'newCustomerTable'
mikewasmike

Ви повинні робити щось не так. Оскільки це буде працювати на 100%. Прочитайте, перш ніж ви отримаєте негативний голос. Посилання на вміст для вас. w3schools.com/sql/sql_select_into.asp
Krishneil

1
Зауважте, що питання стосується MySQL. Деякі синтаксиси SQL можуть не підтримуватися.
mikewasmike

1
MySQL Way СТВОРИТИ ТАБЛИЦЮ рецепти_нові LIKE production.recipes; ВСТАВИТИ рецепти_нові ВИБІР * З виробництва.рецепти;
Крішнейл

1
Я відредагував своє запитання, оскільки попередня відповідь була лише для MSSQLL
Krishneil
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.