[mysql] MySQL 테이블, 인덱스 및 데이터 복제

MySQL 테이블의 데이터, 구조 및 인덱스를 새로운 테이블로 복사 또는 복제 또는 복제하려면 어떻게해야합니까?

이것이 내가 지금까지 찾은 것입니다.

이것은 데이터와 구조를 복사하지만 인덱스는 복사하지 않습니다.

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

이것은 구조와 색인을 복사하지만 데이터는 복사하지 않습니다.

create table {new_table} like {old_table};



답변

인덱스와 트리거로 복사하려면 다음 두 쿼리를 수행하십시오.

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

구조와 데이터 만 복사하려면 다음을 사용하십시오.

CREATE TABLE tbl_new AS SELECT * FROM tbl_old;

나는 전에 이것을 물었다 :

인덱스를 포함한 MySQL 테이블 복사


답변

위의 솔루션 외에도 AS한 줄로 만들 수 있습니다 .

CREATE TABLE tbl_new AS SELECT * FROM tbl_old;


답변

MySQL 방식 :

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


답변

phpMyAdmin으로 이동 하여 원본 테이블을 선택한 다음 “(테이블 을 datadata.table)에 복사 “영역 에서 ” 작업 “탭 을 선택하십시오 . 복사 할 데이터베이스를 선택하고 새 테이블의 이름을 추가하십시오.

복사 테이블-phyMyAdmin 스크린 샷


답변

나는 같은 상황과 내가 사용한 접근법을 다음과 같이 발견했다.

  1. 실행 SHOW CREATE TABLE <table name to clone>: Create Table복제하려는 테이블 의 구문을 제공합니다.
  2. CREATE TABLE테이블 이름을 변경하여 테이블을 복제 하여 쿼리를 실행하십시오 .

그러면 인덱스와 함께 복제하려는 테이블의 정확한 복제본이 생성됩니다. 필요한 경우 인덱스의 이름을 바꾸는 것만 필요합니다 (필요한 경우).


답변

테이블을 복제하는 더 좋은 방법은 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 ;

좋은 하루 보내세요! 알렉스


답변

이 답변을 확장 하면 저장 프로 시저를 사용할 수 있습니다.

CALL duplicate_table('tableName');

어떤 tableName_20181022235959경우 호출하면 If라는 중복 테이블이 생성 됩니다.

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 ;