复制 MySQL 表、索引和数据

Posted

技术标签:

【中文标题】复制 MySQL 表、索引和数据【英文标题】:Duplicating a MySQL table, indices, and data 【发布时间】:2011-03-17 20:07:18 【问题描述】:

我如何复制或克隆或复制数据、结构、 和一个 mysql 表的索引到一个新表?

这是我目前发现的。

这将复制数据和结构, 但不是索引:

create table new_table select * from old_table;

这将复制结构和索引, 但不是数据:

create table new_table like old_table;

【问题讨论】:

run mysql create table by select another and copied the indexes automatically的可能重复 【参考方案1】:

要使用索引和触发器进行复制,请执行以下 2 个查询:

CREATE TABLE new_table LIKE old_table; 
INSERT INTO new_table SELECT * FROM old_table;

要仅复制结构和数据,请使用这个:

CREATE TABLE new_table AS SELECT * FROM old_table;

我之前问过这个问题:

Copy a MySQL table including indexes

【讨论】:

值得注意的是,需要将指向 oldtable 的外键复制到 newtable(如果您要替换 oldtable) 这适用于大表(数百万条记录)吗?我问是因为我不知道select * 在大表中的表现如何。 粗略地说,在 AWS db.r3.large 实例上的 16M 行(有 5 个索引)的表上插入操作需要 27 分钟 值得注意的是,虽然这会从被复制的表中重新创建索引,但它不会继承任何外键约束。 注意:这不会复制 AUTO_INCREMENT 值。【参考方案2】:

除了上面的解决方案,你还可以使用AS使其成为一行。

CREATE TABLE tbl_new AS SELECT * FROM tbl_old;

【讨论】:

这不会复制索引和触发器,因为 SELECT 结果是一个(未命名的)临时表,并且不“携带”源表的元数据。考虑一下,如果你使用函数,那就没有意义了。 我正在寻找备份结构表并仅移动数据,从而删除索引/约束/等。所以我可以重新创建它们。鉴于 Google 将我发送到这里,这个答案非常棒。 这正是他在问题中已经提到的内容:create table new_table select * from old_table; 不是答案,也没有提供新信息。【参考方案3】:

对于 MySQL

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

对于 MSSQL 使用MyDatabase

Select * into newCustomersTable  from oldCustomersTable;

该SQL用于复制表,这里将oldCustomersTable的内容复制到newCustomersTable。 确保数据库中不存在newCustomersTable

【讨论】:

Thows 错误 SQL 错误 (3172):未声明的变量:'newCustomerTable' 你一定是做错了什么。因为这将 100% 有效。在您投反对票之前阅读。内容供您参考。 w3schools.com/sql/sql_select_into.asp 请注意,问题是关于 MySQL 的。可能不支持某些 SQL 语法。 MySQL 方式 CREATE TABLE recipes_new LIKE production.recipes; INSERT recipes_new SELECT * FROM production.recipes; 我已经编辑了我的问题,因为之前的答案仅适用于 MSSQLL【参考方案4】:

我发现了同样的情况,我采取的方法如下:

    执行 SHOW CREATE TABLE <table name to clone> :这将为您提供要克隆的表的 Create Table 语法 通过更改表名来运行CREATE TABLE 查询以克隆表。

这将创建您要克隆的表的精确副本以及索引。然后,您唯一需要做的就是重命名索引(如果需要)。

【讨论】:

【参考方案5】:

MySQL方式:

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

【讨论】:

这应该是公认的答案。因为这会复制所有索引,包括主键和 auto_increment 其实这应该是公认的答案!【参考方案6】:

在我尝试了上面的解决方案之后,我想出了自己的方法。

我的解决方案有点手动,需要 DBMS。

首先,导出数据。

其次,打开导出数据。

第三,用新表名替换旧表名。

第四,更改数据中的所有触发器名称(我使用MySQL,不更改触发器名称时显示错误)。

第五,将您编辑的 SQL 数据导入数据库。

【讨论】:

【参考方案7】:

转到 phpMyAdmin 并选择您的原始表格,然后在“将表格复制到(database.table)”中选择“操作”选项卡区域。选择要复制的数据库并为新表添加名称。

【讨论】:

@AaronJSpetner 这个答案对其他提出这个问题并能够利用 phpMyAdmin 解决问题的用户仍然有帮助。【参考方案8】:

扩展this answer 可以使用存储过程:

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 ;

【讨论】:

【参考方案9】:

复制表的更好方法是仅使用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 ;

祝你有美好的一天! 亚历克斯

【讨论】:

【参考方案10】:

试试这个:

`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 列并制作了一个新表。

【讨论】:

【参考方案11】:

要创建表结构,只需使用以下代码:

CREATE TABLE new_table LIKE current_table; 

要将数据从表复制到另一个,请使用以下代码:

INSERT INTO new_table SELECT * FROM current_table;

【讨论】:

【参考方案12】:

要复制一个表及其结构而没有来自不同数据库的数据,请使用它。关于新的数据库sql类型

CREATE TABLE currentdatabase.tablename LIKE olddatabase.tablename

【讨论】:

【参考方案13】:

值得一提的是检查表之前是否已经存在的重要性 试图复制它:

CREATE TABLE IF NOT EXISTS new_table LIKE old_table;

INSERT new_table
SELECT * FROM old_table;

正如之前的答案所说,这将复制 structuredata表的所有依赖对象

见MySql Tutorial:

【讨论】:

【参考方案14】:

简单克隆: 它从另一个表创建一个表,而不考虑任何列属性和索引。

CREATE TABLE new_table SELECT * FROM original_table;

浅层克隆: 这只会根据原表的结构创建一个空表

CREATE TABLE new_table LIKE original_table;

以下命令将在原始表的基础上创建一个空表。

CREATE TABLE adminUsers LIKE users;

深度克隆: 这意味着新表将具有现有表的每列和索引的所有属性。如果您想维护现有表的索引和属性,这非常有用。

CREATE TABLE new_table LIKE original_table;

INSERT INTO new_table SELECT * FROM original_table;

https://towardsdatascience.com/how-to-clone-tables-in-sql-dd29586ec89c

【讨论】:

以上是关于复制 MySQL 表、索引和数据的主要内容,如果未能解决你的问题,请参考以下文章

MySQL 复制表结构和复制表结构,数据

雷林鹏分享:MySQL 复制表

MySQL 复制表:如何准确无误的创建复制表?

吴裕雄 26-MySQL 复制表

linux MySQL 如何复制表数据或表结构到新表中

mysql 数据库怎么复制一张表?