Sao chép bảng, chỉ mục và dữ liệu của MySQL


668

Làm cách nào để sao chép hoặc sao chép hoặc sao chép dữ liệu, cấu trúc và chỉ mục của bảng MySQL sang bảng mới?

Đây là những gì tôi đã tìm thấy cho đến nay.

Điều này sẽ sao chép dữ liệu và cấu trúc, nhưng không phải là các chỉ số:

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

Điều này sẽ sao chép cấu trúc và chỉ mục, nhưng không phải dữ liệu:

create table {new_table} like {old_table};

Câu trả lời:


1487

Để sao chép với các chỉ mục và trình kích hoạt, hãy thực hiện 2 truy vấn sau:

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

Để sao chép chỉ cấu trúc và dữ liệu, hãy sử dụng cái này:

CREATE TABLE tbl_new AS SELECT * FROM tbl_old;

Tôi đã hỏi điều này trước đây:

Sao chép bảng MySQL bao gồm các chỉ mục


10
Đáng lưu ý rằng các khóa ngoại được trỏ đến oldtable sẽ cần được sao chép sang newtable (nếu bạn thay thế oldtable)
George

3
Điều này có hiệu quả đối với các bảng lớn (hàng triệu bản ghi) không? .. Tôi đang hỏi vì tôi không biết cách này select *sẽ thực hiện trong các bảng lớn.
fguillen

3
Để đưa ra một ý tưởng sơ bộ, thao tác chèn đã lấy 27 phút trên một bảng gồm 16 triệu hàng (có 5 chỉ mục) trên một phiên bản AWS db.r3.large
hello_harry

6
Điều đáng chú ý là trong khi điều này tạo lại các chỉ mục từ bảng được sao chép, nó không mang theo bất kỳ ràng buộc khóa ngoại nào.
WebSmithery

15
Lưu ý: Điều này sẽ không sao chép AUTO_INCREMENTgiá trị.
Matt Janssen

43

Ngoài giải pháp trên, bạn có thể sử dụng ASđể thực hiện trong một dòng.

CREATE TABLE tbl_new AS SELECT * FROM tbl_old;

32
Điều này sẽ không sao chép các chỉ mục và kích hoạt vì kết quả CHỌN là một bảng tạm thời (chưa được đặt tên) và không "mang" siêu dữ liệu của bảng nguồn. Hãy xem xét nếu bạn đang sử dụng các chức năng, nó sẽ không có ý nghĩa.
chx

1
Tôi đã tìm cách sao lưu bảng cấu trúc và chỉ di chuyển dữ liệu, do đó giảm chỉ mục / ràng buộc / v.v. vì vậy tôi có thể tạo lại chúng. Câu trả lời này thật tuyệt vời khi thấy Google gửi cho tôi ở đây.
Ellesedil

3
đây chính xác là những gì anh ấy đã đề cập trong câu hỏi: create table {new_table} select * from {old_table};không phải là một câu trả lời và không cung cấp thông tin mới.
billynoah

13

Cách của MySQL:

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

Đây phải là câu trả lời được chấp nhận. Vì điều này sao chép tất cả các chỉ mục bao gồm khóa chính và auto_increment
Barkaveer Hakari

10

Tới phpMyAdmin và chọn bảng ban đầu của bạn sau đó chọn " Operations " tab trong " bảng Copy to (database.table) " khu vực. Chọn cơ sở dữ liệu mà bạn muốn sao chép và thêm tên cho bảng mới của bạn.

bảng sao chép - phyMyAdmin Ảnh chụp màn hình


1
@AaronJSpetner Câu trả lời này vẫn hữu ích cho những người dùng khác đến với câu hỏi này và có thể sử dụng PHPMyAdmin để giải quyết vấn đề.
cải cách

3

Tôi đã tìm thấy tình huống tương tự và cách tiếp cận mà tôi đã thực hiện như sau:

  1. Thực thi SHOW CREATE TABLE <table name to clone>: Điều này sẽ cung cấp cho bạn Create Tablecú pháp cho bảng mà bạn muốn sao chép
  2. Chạy CREATE TABLEtruy vấn bằng cách thay đổi tên bảng để sao chép bảng.

Điều này sẽ tạo bản sao chính xác của bảng mà bạn muốn sao chép cùng với các chỉ mục. Điều duy nhất mà sau đó bạn cần là đổi tên các chỉ mục (nếu cần).


2

Cách tốt hơn để sao chép bảng là chỉ sử dụng DDLcâu lệnh. Bằng cách này, độc lập với số lượng bản ghi trong bảng, bạn có thể thực hiện sao chép ngay lập tức.

Mục đích của tôi là:

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;

Điều này tránh được INSERT AS SELECTtuyên bố rằng, trong trường hợp bảng có nhiều bản ghi có thể mất thời gian để được thực thi.

Tôi cũng đề nghị tạo một thủ tục PLQuery như ví dụ sau:

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 ;

Chúc một ngày tốt lành! Alex


1

Mở rộng câu trả lời này người ta có thể sử dụng một thủ tục được lưu trữ:

CALL duplicate_table('tableName');

Điều này sẽ dẫn đến một bảng trùng lặp được gọi là tableName_20181022235959Nếu được gọi khi

SELECT NOW();

các kết quả:

2018-10-22 23:59:59

Thực hiện

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

Sau khi tôi thử giải pháp trên, tôi nghĩ ra cách riêng của mình.

Giải pháp của tôi một chút hướng dẫn và cần DBMS.

Đầu tiên, xuất dữ liệu.

Thứ hai, mở dữ liệu xuất khẩu.

Thứ ba, thay thế tên bảng cũ bằng tên bảng mới.

Thứ tư, thay đổi tất cả tên kích hoạt trong dữ liệu (Tôi sử dụng MySQL và nó hiển thị lỗi khi tôi không thay đổi tên kích hoạt).

Thứ năm, nhập dữ liệu SQL đã chỉnh sửa của bạn vào cơ sở dữ liệu.


0

Thử cái này :

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

Tôi đã chọn 4 cột từ bảng cũ và tạo một bảng mới.


-2

CHO MySQL

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

ĐỐI VỚI MSSQL Sử dụng MyDatabase:

Select * into newCustomersTable  from oldCustomersTable;

SQL này được sử dụng để sao chép các bảng, ở đây nội dung của oldCustomersTable sẽ được sao chép vào newCustomersTable.
Hãy chắc chắn rằng newCustomersTable không tồn tại trong cơ sở dữ liệu.


4
Lỗi SQL Lỗi (3172): Biến không được khai báo: 'newCustomerTable'
mikewasmike

Bạn phải làm gì đó sai. Vì điều này sẽ làm việc 100%. Đọc trước khi bạn bỏ phiếu tiêu cực. Nội dung tham khảo cho bạn. w3schools.com/sql/sql_select_into.asp
Krishneil

1
Lưu ý rằng câu hỏi là về MySQL. Một số cú pháp SQL có thể không được hỗ trợ.
mikewasmike

1
Cách MySQL TẠO BẢNG công thức nấu ăn_new THÍCH sản xuất.recipes; CHỌN công thức nấu ăn_new CHỌN * TỪ sản xuất.recipes;
Krishneil

1
Tôi đã chỉnh sửa câu hỏi của mình vì câu trả lời trước chỉ dành cho MSSQLL
Krishneil
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.