這篇文章給大家分享的是有關(guān)MySQL數(shù)據(jù)庫(kù)的表結(jié)構(gòu)和表數(shù)據(jù),小編覺(jué)得挺實(shí)用的,因此分享給大家學(xué)習(xí),希望大家閱讀完這篇文章后可以有所收獲。
創(chuàng)新互聯(lián)公司主營(yíng)通許網(wǎng)站建設(shè)的網(wǎng)絡(luò)公司,主營(yíng)網(wǎng)站建設(shè)方案,成都app軟件開(kāi)發(fā)公司,通許h5微信小程序搭建,通許網(wǎng)站營(yíng)銷推廣歡迎通許等地區(qū)企業(yè)咨詢
1、前言
在功能開(kāi)發(fā)完畢,在本地或者測(cè)試環(huán)境進(jìn)行測(cè)試時(shí),經(jīng)常會(huì)遇到這種情況:有專門的測(cè)試數(shù)據(jù),測(cè)試過(guò)程會(huì)涉及到修改表中的數(shù)據(jù),經(jīng)常不能一次測(cè)試成功,所以,每次執(zhí)行測(cè)試后,原來(lái)表中的數(shù)據(jù)其實(shí)已經(jīng)被修改了,下一次測(cè)試,就需要將數(shù)據(jù)恢復(fù)。
我一般的做法是:先創(chuàng)建一個(gè)副本表,比如測(cè)試使用的user表,我在測(cè)試前創(chuàng)建副本表user_bak,每次測(cè)試后,將user表清空,然后將副本表user_bak的數(shù)據(jù)導(dǎo)入到user表中。
上面的操作是對(duì)一個(gè)table做備份,如果涉及到的table太多,可以創(chuàng)建database的副本。
接下來(lái)我將對(duì)此處的表結(jié)構(gòu)復(fù)制以及表數(shù)據(jù)復(fù)制進(jìn)行闡述,并非數(shù)據(jù)庫(kù)的復(fù)制原理?。。?!
下面是staff表的表結(jié)構(gòu)
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、執(zhí)行舊表的創(chuàng)建SQL來(lái)創(chuàng)建表
如果原始表已經(jīng)存在,那么可以使用命令查看該表的創(chuàng)建語(yǔ)句:
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的命令執(zhí)行結(jié)果中,Create Table的值就是創(chuàng)建表的語(yǔ)句,此時(shí)可以直接復(fù)制創(chuàng)建表的SQL,然后重新執(zhí)行一次就行了。
當(dāng)數(shù)據(jù)表中有數(shù)據(jù)的時(shí)候,看到的創(chuàng)建staff表的sql就會(huì)稍有不同。比如,我在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)
此時(shí)在執(zhí)行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)
注意,上面結(jié)果中的倒數(shù)第二行
ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COMMENT='員工表'
因?yàn)閟taff表的id是自增的,且已經(jīng)有了2條記錄,所以下一次插入數(shù)據(jù)的自增id應(yīng)該為3,這個(gè)信息,也會(huì)出現(xiàn)在表的創(chuàng)建sql中。
2.2、使用like創(chuàng)建新表(僅包含表結(jié)構(gòu))
使用like根據(jù)已有的表來(lái)創(chuàng)建新表,特點(diǎn)如下:
1、方便,不需要查看原表的表結(jié)構(gòu)定義信息;
2、創(chuàng)建的新表中,表結(jié)構(gòu)定義、完整性約束,都與原表保持一致。
3、創(chuàng)建的新表是一個(gè)空表,全新的表,沒(méi)有數(shù)據(jù)。
用法如下:
mysql> select * from staff; #舊表中已有2條數(shù)據(jù) +----+--------+-----+--------+--------+ | 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='員工表' # 注意沒(méi)有AUTO_INCREMENT=3 1 row in set (0.00 sec) mysql> select * from staff_bak_1; # 沒(méi)有包含舊表的數(shù)據(jù) Empty set (0.00 sec)
2.3、使用as來(lái)創(chuàng)建新表(包含數(shù)據(jù))
使用as來(lái)創(chuàng)建新表,有一下特點(diǎn):
1、可以有選擇性的決定新表包含哪些字段;
2、創(chuàng)建的新表中,會(huì)包含舊表的數(shù)據(jù);
3、創(chuàng)建的新表不會(huì)包含舊表的完整性約束(比如主鍵、索引等),僅包含最基礎(chǔ)的表結(jié)構(gòu)定義。
用法如下:
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創(chuàng)建表的時(shí)候沒(méi)有保留完整性約束,其實(shí)這個(gè)仔細(xì)想一下也能想明白。因?yàn)槭褂胊s創(chuàng)建表的時(shí)候,可以指定新表包含哪些字段呀,如果你創(chuàng)建新表時(shí),忽略了幾個(gè)字段,這樣的話即使保留了完整約束,保存數(shù)據(jù)是也不能滿足完整性約束。
比如,staff表有一個(gè)索引idx1,由name和dep字段組成;但是我創(chuàng)建的新表中,沒(méi)有name和dep字段(只選擇了其他字段),那么新表中保存idx1也沒(méi)有必要,對(duì)吧。
mysql> -- 只選擇id、gender、addr作為新表的字段,那么name和dep組成的索引就沒(méi)必要存在了 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創(chuàng)建原表的副本(推薦)
使用like創(chuàng)建新表,雖然保留了舊表的各種表結(jié)構(gòu)定義以及完整性約束,但是如何將舊表的數(shù)據(jù)導(dǎo)入到新表中呢?
最極端的方式:寫一個(gè)程序,先將舊表數(shù)據(jù)讀出來(lái),然后寫入到新表中,這個(gè)方式我就不嘗試了。
有一個(gè)比較簡(jiǎn)單的命令:
mysql> select * from staff; #原表數(shù)據(jù) +----+--------+-----+--------+--------+ | 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創(chuàng)建的表,與原表相同的表結(jié)構(gòu)和完整性約束(自增除外) 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)
其實(shí)這條SQL語(yǔ)句,是知道兩個(gè)表的表結(jié)構(gòu)和完整性約束相同,所以,可以直接select *。
insert into staff_bak_1 select * from staff;
如果兩個(gè)表結(jié)構(gòu)不相同,其實(shí)也是可以這個(gè)方式的,比如:
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字段組成的數(shù)據(jù)記錄插入到demo表中,對(duì)應(yīng)_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)
這是兩個(gè)表的字段數(shù)量不相同的情況,此時(shí)需要手動(dòng)指定列名,否則就會(huì)報(bào)錯(cuò)。
另外,如果兩個(gè)表的字段數(shù)量,以及相同順序的字段類型相同,如果是全部字段復(fù)制,即使字段名不同,也可以直接復(fù)制:
# staff_bak_5的字段名與staff表并不相同,但是字段數(shù)量、相同順序字段的類型相同,所以可以直接插入 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數(shù)據(jù)庫(kù)的表結(jié)構(gòu)和表數(shù)據(jù),雖然從篇幅上看很復(fù)雜,但是示例代碼非常詳細(xì)且容易理解,如果想了解更多相關(guān)內(nèi)容,請(qǐng)關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊。