Дублирование таблицы, индексов и данных MySQL


670

Как мне скопировать или клонировать или дублировать данные, структуру и индексы таблицы MySQL в новую?

Это то, что я нашел до сих пор.

Это скопирует данные и структуру, но не индексы:

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

Это скопирует структуру и индексы, но не данные:

create table {new_table} like {old_table};

Ответы:


1489

Для копирования с индексами и триггерами выполните следующие 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

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 отправил меня сюда.
Эллеседил

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 и выберите исходную таблицу, затем выберите « Операции». » в области « Копировать таблицу в (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 ;

Хорошего дня! Alex


Кто-нибудь пробовал это? Это работает, как ожидалось?
Раду Мурзеа

1

Развивая этот ответ, можно использовать хранимую процедуру:

CALL duplicate_table('tableName');

Что приведет к дублированию таблицы с именем tableName_20181022235959If, когда

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
Ошибка Thows Ошибка SQL (3172): необъявленная переменная: 'newCustomerTable'
mikewasmike

Вы должны делать что-то не так. Как это будет работать на 100%. Прочитайте, прежде чем дать отрицательный голос. Содержание ссылки для вас. w3schools.com/sql/sql_select_into.asp
Кришнейл

1
Обратите внимание, что вопрос о MySQL. Некоторый синтаксис SQL может не поддерживаться.
mikewasmike

1
MySQL Way CREATE TABLE recipes_new LIKE production.recipes; INSERT recipes_new SELECT * FROM production.recipes;
Кришнейл

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