1、前言
在功能開發完畢,在本地或測試環境進行測試時,經常會遇到這種情況:有專門的測試數據,測試過程會涉及到修改表中的數據,經常不能一次測試成功,所以,每次執行測試後,原來表中的數據其實已經被修改了,下一次測試,就需要將數據恢復。
我一般的做法是:先建立一個副本表,例如測試使用的user表,我會在測試前建立副本表user_bak,每次測試後,將user表清空,然後將副本表user_bak的資料匯入至user表中。
上面的動作是對一個table做備份,如果涉及到的table太多,可以建立database的副本。
接下來我將對此處的表結構複製以及表格資料複製進行闡述,並非資料庫的複製原理! ! ! !
下面是staff表格的表格結構
create table staff ( id int not null auto_increment comment '自增id', name char(20) not null comment '用户姓名', dep char(20) not null comment '所属部门', gender tinyint not null default 1 comment '性别:1男; 2女', addr char(30) not null comment '地址', primary key(id), index idx_1 (name, dep), index idx_2 (name, gender) ) engine=innodb default charset=utf8mb4 comment '员工表';
2、具體方式
##2.1、執行舊表的建立SQL來建立表格
如果原始表已經存在,那麼可以使用指令來檢視該表的建立語句:mysql> show create table staff\G *************************** 1. row *************************** Table: staff Create Table: CREATE TABLE `staff` ( `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '自增id', `name` char(20) NOT NULL COMMENT '用户姓名', `dep` char(20) NOT NULL COMMENT '所属部门', `gender` tinyint(4) NOT NULL DEFAULT '1' COMMENT '性别:1男; 2女', `addr` char(30) NOT NULL, PRIMARY KEY (`id`), KEY `idx_1` (`name`,`dep`), KEY `idx_2` (`name`,`gender`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='员工表' 1 row in set (0.01 sec)可以看到,上面
show creat table xx的指令執行結果中,Create Table的值就是建立表格的語句,此時可以直接複製建立表格的SQL,然後重新執行一次就行了。
當資料表中有資料的時候,看到的建立staff表的sql就會稍有不同。例如,我在staff中加入了兩筆記錄:mysql> insert into staff values (null, '李明', 'RD', 1, '北京'); Query OK, 1 row affected (0.00 sec) mysql> insert into staff values (null, '张三', 'PM', 0, '上海'); Query OK, 1 row affected (0.00 sec) mysql> select * from staff; +----+--------+-----+--------+--------+ | id | name | dep | gender | addr | +----+--------+-----+--------+--------+ | 1 | 李明 | RD | 1 | 北京 | | 2 | 张三 | PM | 0 | 上海 | +----+--------+-----+--------+--------+ 2 rows in set (0.00 sec)此時在執行show create table指令:
mysql> show create table staff\G *************************** 1. row *************************** Table: staff Create Table: CREATE TABLE `staff` ( `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '自增id', `name` char(20) NOT NULL COMMENT '用户姓名', `dep` char(20) NOT NULL COMMENT '所属部门', `gender` tinyint(4) NOT NULL DEFAULT '1' COMMENT '性别:1男; 2女', `addr` char(30) NOT NULL, PRIMARY KEY (`id`), KEY `idx_1` (`name`,`dep`), KEY `idx_2` (`name`,`gender`) ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COMMENT='员工表' 1 row in set (0.00 sec)注意,上面結果中的倒數第二行
ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COMMENT='员工表'因為staff表的id是自增的,而且已經有了2筆記錄,所以下一次插入資料的自增id應該為3,這個信息,也會出現在表的建立sql中。
2.2、使用like建立新表(僅包含表格結構)
使用like根據現有的表來建立新表,特點如下:1、方便,不需要查看原始表的表結構定義資訊;mysql> select * from staff; #旧表中已有2条数据 +----+--------+-----+--------+--------+ | id | name | dep | gender | addr | +----+--------+-----+--------+--------+ | 1 | 李明 | RD | 1 | 北京 | | 2 | 张三 | PM | 0 | 上海 | +----+--------+-----+--------+--------+ 2 rows in set (0.00 sec) mysql> create table staff_bak_1 like staff; # 直接使用like,前面指定新表名,后面指定旧表(参考的表) Query OK, 0 rows affected (0.02 sec) mysql> show create table staff_bak_1\G *************************** 1. row *************************** Table: staff_bak_1 Create Table: CREATE TABLE `staff_bak_1` ( `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '自增id', `name` char(20) NOT NULL COMMENT '用户姓名', `dep` char(20) NOT NULL COMMENT '所属部门', `gender` tinyint(4) NOT NULL DEFAULT '1' COMMENT '性别:1男; 2女', `addr` char(30) NOT NULL, PRIMARY KEY (`id`), KEY `idx_1` (`name`,`dep`), KEY `idx_2` (`name`,`gender`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='员工表' # 注意没有AUTO_INCREMENT=3 1 row in set (0.00 sec) mysql> select * from staff_bak_1; # 没有包含旧表的数据 Empty set (0.00 sec)
2.3、使用as來建立新表(包含資料)
mysql> create table staff_bak_2 as select * from staff; Query OK, 2 rows affected (0.02 sec) Records: 2 Duplicates: 0 Warnings: 0 mysql> select * from staff_bak_2; +----+--------+-----+--------+--------+ | id | name | dep | gender | addr | +----+--------+-----+--------+--------+ | 1 | 李明 | RD | 1 | 北京 | | 2 | 张三 | PM | 0 | 上海 | +----+--------+-----+--------+--------+ 2 rows in set (0.00 sec) mysql> show create table staff_bak_2\G *************************** 1. row *************************** Table: staff_bak_2 Create Table: CREATE TABLE `staff_bak_2` ( `id` int(11) NOT NULL DEFAULT '0' COMMENT '自增id', `name` char(20) CHARACTER SET utf8mb4 NOT NULL COMMENT '用户姓名', `dep` char(20) CHARACTER SET utf8mb4 NOT NULL COMMENT '所属部门', `gender` tinyint(4) NOT NULL DEFAULT '1' COMMENT '性别:1男; 2女', `addr` char(30) CHARACTER SET utf8mb4 NOT NULL ) ENGINE=InnoDB DEFAULT CHARSET=latin1 1 row in set (0.00 sec)利用as建立表格的時候沒有保留完整性約束,其實這個仔細想一下也能想明白。因為使用as建立表的時候,可以指定新表包含哪些字段呀,如果你建立新表時,忽略了幾個字段,這樣的話即使保留了完整約束,保存資料是也不能滿足完整性約束。
mysql> -- 只选择id、gender、addr作为新表的字段,那么name和dep组成的索引就没必要存在了 mysql> create table staff_bak_3 as (select id, gender, addr from staff); Query OK, 2 rows affected (0.02 sec) Records: 2 Duplicates: 0 Warnings: 0 mysql> show create table staff_bak_3\G *************************** 1. row *************************** Table: staff_bak_3 Create Table: CREATE TABLE `staff_bak_3` ( `id` int(11) NOT NULL DEFAULT '0' COMMENT '自增id', `gender` tinyint(4) NOT NULL DEFAULT '1' COMMENT '性别:1男; 2女', `addr` char(30) CHARACTER SET utf8mb4 NOT NULL ) ENGINE=InnoDB DEFAULT CHARSET=latin1 1 row in set (0.00 sec) mysql> select * from staff_bak_3; +----+--------+--------+ | id | gender | addr | +----+--------+--------+ | 1 | 1 | 北京 | | 2 | 0 | 上海 | +----+--------+--------+ 2 rows in set (0.00 sec)
2.4、使用like insert select建立原表的副本(建議)
mysql> select * from staff; #原表数据 +----+--------+-----+--------+--------+ | id | name | dep | gender | addr | +----+--------+-----+--------+--------+ | 1 | 李明 | RD | 1 | 北京 | | 2 | 张三 | PM | 0 | 上海 | +----+--------+-----+--------+--------+ 2 rows in set (0.00 sec) mysql> select * from staff_bak_1; # 使用like创建的表,与原表相同的表结构和完整性约束(自增除外) Empty set (0.00 sec) mysql> insert into staff_bak_1 select * from staff; # 将staff表的所有记录的所有字段值都插入副本表中 Query OK, 2 rows affected (0.00 sec) Records: 2 Duplicates: 0 Warnings: 0 mysql> select * from staff_bak_1; +----+--------+-----+--------+--------+ | id | name | dep | gender | addr | +----+--------+-----+--------+--------+ | 1 | 李明 | RD | 1 | 北京 | | 2 | 张三 | PM | 0 | 上海 | +----+--------+-----+--------+--------+ 2 rows in set (0.00 sec)其實這條SQL語句,是知道兩個表的表結構和完整性限制相同,所以,可以直接select *。
insert into staff_bak_1 select * from staff;如果兩個表格結構不相同,其實也是可以這個方式的,例如:
mysql> show create table demo\G *************************** 1. row *************************** Table: demo Create Table: CREATE TABLE `demo` ( `_id` int(11) NOT NULL AUTO_INCREMENT, `_name` char(20) DEFAULT NULL, `_gender` tinyint(4) DEFAULT '1', PRIMARY KEY (`_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 1 row in set (0.00 sec) # 只将staff表中的id和name字段组成的数据记录插入到demo表中,对应_id和_name字段 mysql> insert into demo (_id, _name) select id,name from staff; Query OK, 2 rows affected (0.00 sec) Records: 2 Duplicates: 0 Warnings: 0 mysql> select * from demo; +-----+--------+---------+ | _id | _name | _gender | +-----+--------+---------+ | 1 | 李明 | 1 | | 2 | 张三 | 1 | +-----+--------+---------+ 2 rows in set (0.00 sec)這是兩個表格的欄位數量不相同的情況,此時需要手動指定列名,否則就會報錯。 另外,如果兩個表格的欄位數量,以及相同順序的欄位類型相同,如果是全部欄位複製,即使欄位名稱不同,也可以直接複製:
# staff_bak_5的字段名与staff表并不相同,但是字段数量、相同顺序字段的类型相同,所以可以直接插入 mysql> show create table staff_bak_5\G *************************** 1. row *************************** Table: staff_bak_5 Create Table: CREATE TABLE `staff_bak_5` ( `_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '自增id', `_name` char(20) NOT NULL COMMENT '用户姓名', `_dep` char(20) NOT NULL COMMENT '所属部门', `_gender` tinyint(4) NOT NULL DEFAULT '1' COMMENT '性别:1男; 2女', `_addr` char(30) NOT NULL, PRIMARY KEY (`_id`), KEY `idx_1` (`_name`,`_dep`), KEY `idx_2` (`_name`,`_gender`) ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COMMENT='员工表' 1 row in set (0.00 sec) mysql> insert into staff_bak_5 select * from staff; Query OK, 2 rows affected (0.00 sec) Records: 2 Duplicates: 0 Warnings: 0 mysql> select * from staff_bak_5; +-----+--------+------+---------+--------+ | _id | _name | _dep | _gender | _addr | +-----+--------+------+---------+--------+ | 1 | 李明 | RD | 1 | 北京 | | 2 | 张三 | PM | 0 | 上海 | +-----+--------+------+---------+--------+ 2 rows in set (0.00 sec)
推荐 《mysql视频教程》
以上是MySQL複製表結構與表數據的詳細內容。更多資訊請關注PHP中文網其他相關文章!