寫(xiě)在前面的話
?
上一節(jié)主要談?wù)?MySQL 是怎么安裝的以及最簡(jiǎn)單的初始化我們應(yīng)該做哪些配置。其中也用到了一些簡(jiǎn)單的用戶操作 SQL,所以這一節(jié)主要學(xué)習(xí)常用的 SQL 使用。
?
?
SQL 介紹
?
在了解 SQL 之前,對(duì)于 SQL 需要有以下簡(jiǎn)單的認(rèn)知:
1. 主流的來(lái)個(gè)標(biāo)準(zhǔn),SQL92 和 SQL99,在 MySQL 5.7 以后采用的是 SQL92。
2. 在 5.7 中新增了 sql_mode,作用在于限制哪些 SQL 能夠使用,一個(gè)很明顯的例子是 group by 的使用。
?
在上一節(jié)簡(jiǎn)單說(shuō)過(guò)常用的 SQL 分類(主要前 3 個(gè)):
DDL:數(shù)據(jù)定義語(yǔ)言
DCL:數(shù)據(jù)控制語(yǔ)言
DML:數(shù)據(jù)操作語(yǔ)言
DQL:數(shù)據(jù)查詢語(yǔ)言
?
?
數(shù)據(jù)類型
?
這算是數(shù)據(jù)定義過(guò)程中的一個(gè)重點(diǎn),針對(duì)不同的數(shù)據(jù)我們給定不同的數(shù)據(jù)類型,作用在于保證數(shù)據(jù)的準(zhǔn)確性和標(biāo)準(zhǔn)性。
數(shù)值類型:
類 | 類型 | 說(shuō)明 |
---|---|---|
tinyint | 整數(shù) | 很小,0 - 255 |
smallint | 整數(shù) | 較小,-2^15 - 2^15 |
mediumint | 整數(shù) | 中等,很少用 |
int | 整數(shù) | 常規(guī),-2^31 - 2^31 |
bigint | 整數(shù) | 較大,-2^63 - 2^63 |
float | 浮點(diǎn)數(shù) | 小型單精度浮點(diǎn)數(shù),四個(gè)字節(jié) |
double | 浮點(diǎn)數(shù) | 常規(guī)單精度浮點(diǎn)數(shù),八個(gè)字節(jié) |
decimal | 定點(diǎn)數(shù) | 包含整數(shù)部分,小數(shù)部分或者同時(shí)包含二者精確數(shù)值 |
bit | BIT | 位字段值 |
?
字符類型:
類 | 類型 | 說(shuō)明 |
---|---|---|
char | 文本 | 固定長(zhǎng)度字符串,最多 255 個(gè)字符 |
varchar | 文本 | 可變長(zhǎng)度字符串,最多 65535 個(gè)字符 |
tinytext | 文本 | 可變長(zhǎng)度字符串,最多 255 個(gè)字符 |
text | 文本 | 可變長(zhǎng)度字符串,最多 65535 個(gè)字符 |
mediumtext | 文本 | 可變長(zhǎng)度字符串,最多 1600萬(wàn) 個(gè)字符 |
longtext | 文本 | 可變長(zhǎng)字符串,最多 42億 字符 |
enum | 整數(shù) | 一組固定合法值組成的枚舉 |
set | 整數(shù) | 一組固定合法值組成的集 |
在生產(chǎn)中最容易出現(xiàn)的就是字符串字段長(zhǎng)度不足的問(wèn)題,所以在設(shè)計(jì)的時(shí)候注意選對(duì)類型。
char 之所以是定長(zhǎng),比如我們定義 char(10),那就意味著傳的最大長(zhǎng)度是 10,如果不夠補(bǔ)充空格,反正就是占用 10 個(gè)字符。
varchar 相比之下,則是在指定的范圍內(nèi)按需分配,如 varchar(10),最大長(zhǎng)度 10,不足就不足,不浪費(fèi)。
至于 enum,則屬于特別的使用,如本字段的值是指定范圍,如 enum("北京", "上海", "廣州", "深圳"),這樣使用能夠優(yōu)化索引。但用的其實(shí)并不多。
?
時(shí)間類型:
類型 | 格式 | 示例 |
---|---|---|
date | YYYY-MM-DD | 2019-08-08 |
time | hh:mm:ss[.uuuuuu] | 10:50:29.123456 |
datetime | YYYY-MM-DD hh:mm:ss[.uuuuuu] | 2019-08-08 10:50:29.123456 |
timestamp | YYYY-MM-DD hh:mm:ss[.uuuuuu] | 2019-08-08 10:50:29.123456 |
year | YYYY | 2019 |
timestamp 會(huì)受到時(shí)區(qū)的影響,且范圍有限制。不是很建議。
?
二進(jìn)制類型(這類不建議存到 MySQL):
類 | 類型 | 說(shuō)明 |
---|---|---|
binary | 二進(jìn)制 | 類似 char 固定長(zhǎng)度,但存儲(chǔ)的是二進(jìn)制 |
varbinary | 二進(jìn)制 | 類型 varchar |
tinyblob | blob | 最大長(zhǎng)度 255 的 blob 列 |
blob | blob | 最大長(zhǎng)度 65535 的 blob 列 |
mediumblob | blob | 最大長(zhǎng)度 1600萬(wàn) 的 blob 列 |
longblob | blob | 最大長(zhǎng)度 42億 的 blob 列 |
?
?
表屬性
?
1. 列屬性(主要關(guān)鍵字):
primary key:主鍵,非空唯一約束,一個(gè)表只能有一個(gè),但是能由多個(gè)列組成。
not null:非空約束,屬于設(shè)計(jì)規(guī)范,盡可能不要列空,可以使用默認(rèn)值 0 替代空。
unique key:唯一鍵,值不能重復(fù) 。
unsigned:無(wú)符號(hào),主要用于數(shù)字列,非負(fù)數(shù)。
key:索引,可以給某列建立索引來(lái)優(yōu)化查詢。
default:默認(rèn)值,列沒(méi)有值時(shí)默認(rèn)填充。
auto_increment:自增,主要針對(duì)數(shù)字,順序填充數(shù)據(jù),默認(rèn) 1 開(kāi)始,可以設(shè)置起始值和偏移量。
comment:注釋。
?
2. 表屬性:
存儲(chǔ)引擎:在 5.7 默認(rèn)是 innodb,在老版本中可能是 MyISAM。
字符集:常見(jiàn)的 utf8,utf8mb4 等。
校對(duì)(排序)規(guī)則:如 utf8_general_ci,utf8_bin 這種。主要用于大小寫(xiě)是否敏感。
可以通過(guò)以下 SQL 查看系統(tǒng)支持:
# 查看編碼show charset;# 查看排序規(guī)則show collation;
?
?
數(shù)據(jù)庫(kù)操作(DDL)
?
1. 創(chuàng)建數(shù)據(jù)庫(kù)并指定查看字符集:
# 默認(rèn)創(chuàng)建create database a;show create database a;# 指定字符集創(chuàng)建create database b charset utf8mb4;show create database b;# 指定字符集和排序規(guī)則創(chuàng)建create database c charset utf8mb4 collate utf8mb4_bin;show create database c;
結(jié)果如下:
可以看到,MySQL 默認(rèn)不指定字符集創(chuàng)建數(shù)據(jù)庫(kù)的時(shí)候,創(chuàng)建的數(shù)據(jù)庫(kù)的字符集為拉?。╨atin1)。
排序規(guī)則 ci 結(jié)尾的都是大小寫(xiě)不敏感的。bin 大小寫(xiě)敏感。
當(dāng)然,創(chuàng)建數(shù)據(jù)庫(kù)還可以使用:
create schema d;
這樣也是能夠創(chuàng)建數(shù)據(jù)庫(kù)的。
建庫(kù)規(guī)范:
a. 庫(kù)名不應(yīng)該包含大小寫(xiě)。
b. 庫(kù)名不該以數(shù)字開(kāi)頭。
c. 建庫(kù)一定要加字符集。
d. 庫(kù)名要有意義。
?
特別注意:
禁止生產(chǎn)種執(zhí)行 drop database xxx;
?
2. 修改數(shù)據(jù)庫(kù)字符集:
alter database a charset utf8mb4;
查看:
但是值得注意的是,修改后的字符集必須比之前的字符集范圍更大。原因是數(shù)據(jù)的兼容性。
同時(shí),不到萬(wàn)不得已一般不要修改。
?
?
數(shù)據(jù)表操作(DDL)
?
語(yǔ)法格式:
create table students(列1 屬性(數(shù)據(jù)類型, 約束, 其它),列2 屬性,...)
?
1. 創(chuàng)建一個(gè)名為學(xué)校的測(cè)試庫(kù),創(chuàng)建一張名為學(xué)生的用戶表:
# 創(chuàng)建庫(kù)create database school charset utf8mb4 collate utf8mb4_bin;# 指定庫(kù)use school;# 創(chuàng)建表create table students (id int not null primary key auto_increment comment "學(xué)號(hào)",sname varchar(255) not null comment "姓名",sage tinyint unsigned not null default 0 comment "年齡",sgender enum("m", "f", "n") not null default "n" comment "性別",id_card char(18) not null unique comment "身份證",add_time timestamp not null default now() comment "入學(xué)時(shí)間") engine=innodb charset=utf8mb4 comment "學(xué)生表";
建表規(guī)范:
a. 表名小寫(xiě),不能數(shù)字開(kāi)頭且具有意義。
b. 選擇合適的數(shù)據(jù)類型,字符集,存儲(chǔ)引擎。
c. 每個(gè)列都需要有注釋說(shuō)明且非空,如果為空選擇 0 代替。
?
特別注意:
禁止生產(chǎn)種執(zhí)行 drop table xxx;
?
2. 查看表結(jié)構(gòu):
desc students;
結(jié)果如圖:
也可以查看建表語(yǔ)句:
show create table students\G
?
3. 添加列:
a. 直接添加手機(jī)號(hào)列:
alter table students add mobile varchar(20) not null unique comment "手機(jī)號(hào)";
如圖:
默認(rèn)添加列加到最后面。
?
b. 在 id_card 后面添加微信列:
alter table students add wechat varchar(20) not null unique comment "微信" after id_card;
如圖:
?
c. 在最前面加個(gè)列:
alter table students add school_id tinyint not null comment "學(xué)校編號(hào)" first;
如圖:
?
4. 修改列:
a. 添加 qq 列,然后刪除它:
# 添加alter table students add qq varchar(20) not null unique comment "QQ";desc students;# 刪除alter table students drop qq;desc students;
添加:
刪除:
?
b. 修改列屬性:
alter table students modify mobile varchar(15);
如圖:
可以發(fā)現(xiàn),雖然只是修改了 varchar,但是 null 也修改了。所以修改的時(shí)候建議多以屬性都加一遍。
?
c. 修改列名和數(shù)據(jù)類型:
alter table students change sgender sg char(1) not null default 'n';
我們這里將 sgender 改為 sg,并修改類型:
?
在過(guò)去的版本中,我們應(yīng)該避免在業(yè)務(wù)高峰期修改表結(jié)構(gòu),因?yàn)檫@會(huì)導(dǎo)致數(shù)據(jù)庫(kù)鎖表。
但可以使用?pt-osc 工具(Percona 的),可以在線修改,不再鎖表,原理在于創(chuàng)建一個(gè)新表。
當(dāng)然,在 MySQL 8.0 以后的版本以及自身集成了該工具。
?
5. 復(fù)制表結(jié)構(gòu)建立一張新表:
create table t1 like students;
對(duì)于 DCL,主要就兩個(gè),一個(gè)是 grant,一個(gè)是 revoke。
?
?
數(shù)據(jù)增刪改(DML)
?
1. 插入數(shù)據(jù):
a. 最標(biāo)準(zhǔn)的 insert 語(yǔ)法:
insert into students(school_id,id,sname,sage,sg,id_card,wechat,add_time,mobile) values (11,1,'張三',18,'m','511123199311111214','13290909801',now(),'13290909801');
?
b. 省事寫(xiě)法:
由于我們每個(gè)字段都按照順序?qū)?,所以沒(méi)必須要把字段列出來(lái)。
insert into students values (11,2,'李四',19,'f','511123199311111124','13290222201',now(),'13290222201');
?
c. 部分插入:
因?yàn)橛行┳侄问怯赡J(rèn)值的,所以我們可以就使用默認(rèn)值:
insert into students(school_id,sname,sage,id_card,wechat,mobile) values (11,'王五',18,'511123199311112224','13290909221','13290909221');
?
d. 同時(shí)插入多個(gè):
insert into students(school_id,sname,sage,id_card,wechat,mobile) values(11,'老趙',12,'511123133311112224','13233909221','13233909221'),(11,'老錢',16,'511333133311112224','13333909221','13333909221'),(12,'老孫',25,'511113133311112224','13111909221','13111909221');
?
e. 查看插入結(jié)果:
select * from students;
結(jié)果如圖:
?
2. 修改數(shù)據(jù):
a. 把張三的年齡改為 20:
update students set sage=20 where sname='張三';
??
b. 把所有名字老開(kāi)頭的性別改為 m:
update students set sg='m' where sname like '老%';
結(jié)果如圖:
?
c. 同時(shí)修改多個(gè)值:
update students set sage=25,sg='f' where sname='張三';
結(jié)果如圖:
?
3. 刪除數(shù)據(jù):
delete from students where sname="老孫";
不推薦使用!??!
?
清空表的方法:
delete from students;
delete 逐行全部刪除,屬于 DDL 操作,速度慢!?。?/p>
同時(shí),我們可以從上面的 id 可以看到,由于發(fā)生了 delete 導(dǎo)致 id 不連續(xù),確實(shí)的那一部分仍然占據(jù)著磁盤,這將導(dǎo)致可能數(shù)據(jù)量不大,但是磁盤占用很大的情況。這就是磁盤碎片。
truncate table students;
truncate?全部清空數(shù)據(jù)頁(yè),干干凈凈,屬于 DML 操作,速度快。
都不推薦?。?!
特別注意:
update / delete 一定要記得?where,否則原地爆炸。
?
在實(shí)際生產(chǎn)中,我們都是使用偽刪除的方式,也就是新加數(shù)據(jù)狀態(tài)字段,如可用為 1,不可用為 0,我們刪除就將狀態(tài)由 1 改為 0。
alter table students add status tinyint not null default 1 comment "數(shù)據(jù)狀態(tài)";
刪除就將改行數(shù)據(jù) status 改為 0。
?
?
查詢 DQL(Data Query Language)
?
1. 單獨(dú)使用,查看系統(tǒng)參數(shù):select @@xxx
select @@port;select @@basedir;select @@datadir;select @@socket;select @@server_id;
結(jié)果如下:
有些復(fù)雜的我們可以使用 show 來(lái)模糊查詢:
show variables like 'log%';
如圖:
?
2. 單獨(dú)使用,調(diào)用函數(shù):select 函數(shù)();?
# 顯示當(dāng)前信息select now();select database();select user();# 打印輸出select concat("hello world");# 定制化輸出select concat(user,"@",host) from mysql.user;# 一行輸出select group_concat(user,"@",host) from mysql.user;
結(jié)果:
更多的函數(shù)可以查看官方文檔:
https://dev.mysql.com/doc/refman/5.7/en/func-op-summary-ref.html
?
3. 單表子句,FROM:
select * from students;
不建議在生產(chǎn)中使用,如果表數(shù)據(jù)太大會(huì)造成卡死。
查詢指定列:
select sname,sage,mobile from students;
如圖:
?
4. 單表子句,WHERE:
在使用之前,MySQL 官方提供了專門用于學(xué)習(xí)的一個(gè)數(shù)據(jù)庫(kù):world,可以前往官網(wǎng)下載:
https://dev.mysql.com/doc/index-other.html
如圖:
將示例的數(shù)據(jù)庫(kù)導(dǎo)入 MySQL 中,當(dāng)然也可以下載 world_x,那個(gè)是新數(shù)據(jù),只是測(cè)試沒(méi)必要:
包含三張表,城市,國(guó)家,國(guó)家語(yǔ)言??梢允褂?desc 了解每張表的數(shù)據(jù)結(jié)構(gòu)。
a. 等值查詢:查詢中國(guó)(CHN)的城市
select * from city where CountryCode="CHN";
結(jié)果:
也可以單獨(dú)查詢深圳:
select * from city where Name="shenzhen";
如圖:
?
b. 比較查詢:>,<,>=,<=,<>
查詢世界人口小于 100 的城市:
select * from city where population<100;
如圖:
?
c. 邏輯查詢:and,or
?查詢中國(guó)人口大于 500 萬(wàn)的:
select * from city where countrycode="CHN" and population>=5000000;
如圖:
查詢中國(guó)或美國(guó)的城市:
select * from city where countrycode="CHN" or countrycode="USA";
?
d. 模糊查詢:%
查詢 bei 開(kāi)頭的:
select * from city where name like "bei%";
查詢名字中包含 bei 的(不走索引,性能極差,不推薦):
select * from city where name like "?i%";
如圖:
?
e. 列表匹配:in(類似 or)
select * from city where countrycode in ("CHN","USA");
如圖:
?
f. 查詢范圍:between and(類似 >= and <=)
查詢?nèi)丝谠?830000 和 840000 之間的城市:
select * from city where population between 830000 and 840000;
換成 and 寫(xiě)為:
select * from city where population>=830000 and population<=840000;
結(jié)果:
?
5. GROUP BY 聚合函數(shù)
常用的聚合函數(shù)有以下一些:
最大值:max()最小值:min()平均值:avg()求和:sum()統(tǒng)計(jì):count()列轉(zhuǎn)行:group_concat()
?
a. 統(tǒng)計(jì)每個(gè)國(guó)家的人口數(shù)量:
select countrycode,sum(population) from city group by countrycode;
結(jié)果:
?
b. 統(tǒng)計(jì)中國(guó)各省總?cè)丝冢?/p>
select District,sum(population) from city where countrycode="CHN" group by District;
結(jié)果:
?
3. 統(tǒng)計(jì)世界上每個(gè)國(guó)家城市數(shù)量:
select CountryCode,count(name) from city group by CountryCode;
結(jié)果:
?
6. 單表子句:HAVING
例如統(tǒng)計(jì)中國(guó)各省總?cè)丝跀?shù),只顯示小于 100 萬(wàn)的。
select district,sum(population) from city where countrycode="CHN" group by district having sum(population)<1000000;
如圖:
之所以使用 having,是因?yàn)?where 有順序要求,分別是 where -- group by -- having。
在 group by 之后只能使用 having 不能再用 where 了。另外 having 后條件不走索引。
?
7. 排序和限制:ORDER BY LIMIT
a. 查詢中國(guó)的城市信息,并按照人口升序排序。
select * from city where countrycode="CHN" order by population;
如圖:
?
b. 統(tǒng)計(jì)各省總?cè)丝跀?shù)并按照降序排列。
select district,sum(population) from city where countrycode="CHN" group by district order by sum(population) desc;
默認(rèn)升序,降序需要 desc:
?
c. 統(tǒng)計(jì)全國(guó)各省人口大于 500 萬(wàn)的按照降序排列并取前三。
select district,sum(population) from city where countrycode="CHN" group by district order by sum(population) desc limit 3;
如圖:
當(dāng)然,limit 也可做限制,如:
select district,sum(population) from city where countrycode="CHN" group by district order by sum(population) desc limit 2,3;
limit n,m,這意味著跳過(guò)前面的 n 行,然后顯示 m 行,于是結(jié)果為:
當(dāng)然也可以另外的寫(xiě)法:limit m offset n,一個(gè)意思。
?
8. 去重復(fù):DISTINCT
查詢所有國(guó)家:
select distinct(countrycode) from city;
如果只是查詢 countrycode 會(huì)有很多重復(fù)數(shù)據(jù),可以通過(guò) distinct 去掉重復(fù):
?
9. 聯(lián)合查詢:union all
之前查詢中國(guó)和美國(guó)使用了 and 和 in 的方法,但這并不是性能最優(yōu)的方法。最好的是使用 union all:
select * from city where countrycode="CHN" union all select * from city where countrycode="USA";
值得注意的是 union 會(huì)去掉重復(fù)數(shù)據(jù),而 union all 不會(huì)去重復(fù)。?
?
10. 多表連接查詢:join
首選準(zhǔn)備 4 張表,關(guān)系是這樣的:
建表語(yǔ)句:
-- 刪掉舊數(shù)據(jù)新建數(shù)據(jù)庫(kù)drop database school;create database school charset utf8mb4 collate utf8mb4_bin;use school;-- 學(xué)生表create table student(sno int not null primary key auto_increment comment "學(xué)號(hào)",sname varchar(20) not null comment "姓名",sage tinyint unsigned not null comment "年齡",sgender enum("m","f","n") not null default "n" comment "性別") engine=innodb charset=utf8mb4;-- 課程表create table course(cno int not null primary key auto_increment comment "課程編號(hào)",cname varchar(20) not null comment "課程名稱",tno int not null comment "教師編號(hào)") engine=innodb charset=utf8mb4;-- 學(xué)生成績(jī)表create table sc(sno int not null comment "學(xué)號(hào)",cno int not null comment "課程編號(hào)",score tinyint not null default 0 comment "成績(jī)") engine=innodb charset=utf8mb4;-- 教師表create table teacher(tno int not null primary key auto_increment comment "教師編號(hào)",tname varchar(20) not null comment "教師名字") engine=innodb charset=utf8mb4;
?
基礎(chǔ)數(shù)據(jù):
-- 學(xué)生信息INSERT INTO student VALUES(1,'張三',18,'m'),(2,'李四',18,'m'),(3,'王五',18,'m'),(4,'老趙',19,'f'),(5,'老錢',20,'m'),(6,'老孫',20,'f'),(7,'老李',25,'m');-- 教師信息INSERT INTO teacher VALUES(101,'李老師'),(102,'張老師'),(103,'王老師');-- 課程信息INSERT INTO course VALUES(1001,'linux',101),(1002,'python',102),(1003,'mysql',103);-- 學(xué)生成績(jī)INSERT INTO sc VALUES(1,1001,80),(1,1002,59),(2,1002,90),(2,1003,100),(3,1001,99),(3,1003,40),(4,1001,79),(4,1002,61),(4,1003,99),(5,1003,40),(6,1001,89),(6,1003,77),(7,1001,67),(7,1003,82);?
?
最后效果:
?
多表查詢測(cè)試:
a. 統(tǒng)計(jì)張三學(xué)習(xí)了幾門課:
select st.sname,count(sc.cno) as course_nums from student as st join sc on st.sno=sc.sno where st.sname="張三";
這里用到的知識(shí)有:
1. 通過(guò) as 可以對(duì)字段就行取別名,便于后面書(shū)寫(xiě)使用。
2. 在一開(kāi)始不知道這么寫(xiě)的時(shí)候可以選擇將 select 和 from 之間的內(nèi)容替換為 *,然后再根據(jù)需求修改。
結(jié)果:
?
b. 查詢張三學(xué)習(xí)的課程名稱:
同樣可以先查出所有信息:
select * from student as st join sc on st.sno=sc.sno join course as co on co.cno=sc.cno where st.sname="張三";
結(jié)果:
然后我們只需要姓名列和課程名稱列:
select st.sname,co.cname from student as st join sc on st.sno=sc.sno join course as co on co.cno=sc.cno where st.sname="張三";
結(jié)果:
?
c. 查詢李老師教的學(xué)生名字:
select te.tname,co.cname,st.sname from teacher as te join course as co on co.tno=te.tno join sc on sc.cno=co.cno join student as st on st.sno=sc.sno where te.tname="李老師";
結(jié)果:
?
d. 計(jì)算李老師所教課程的平均分:
select avg(sc.score) from teacher as te join course as co on te.tno=co.tno join sc on co.cno=sc.cno where te.tname="李老師";
結(jié)果:
?
e. 計(jì)算每個(gè)老師的平均分,并降序排列:
select te.tname,avg(sc.score) from teacher as te join course as co on te.tno=co.tno join sc on co.cno=sc.cno group by te.tname order by avg(sc.score) desc;
結(jié)果:
?
f. 查詢李老師80分以下的學(xué)生:
select * from teacher as te join course as co on te.tno=co.tno join sc on sc.cno=co.cno join student as st on st.sno=sc.sno where te.tname="李老師" and sc.score<80;
結(jié)果:
?
g. 查詢所有老師成績(jī)不及格的:
select * from teacher as te join course as co on co.tno=te.tno join sc on sc.cno=co.cno join student as st on sc.sno=st.sno where sc.score<60;
結(jié)果:
?
h. 查詢平均成績(jī)大于 60 的學(xué)生:
select st.sname,avg(score) from sc join student as st on st.sno=sc.sno group by sc.sno having avg(score)>60;
結(jié)果:
這里值得注意的是,由于 group by 后面不能使用 where,所以篩選條件變成 having。
?
i. 顯示各門成績(jī)的最高分最低分:
select co.cname,max(sc.score) as "最高分",min(sc.score) as "最低分" from sc join course as co on co.cno=sc.cno group by sc.cno;
結(jié)果:
?
11.?information_schema 視圖庫(kù):
在說(shuō)明這個(gè)之前,可以簡(jiǎn)單了解以下視圖??梢赃@樣理解,視圖就是對(duì)復(fù)雜 SQL 的封裝,舉個(gè)例子:
select co.cname,max(sc.score) as "最高分",min(sc.score) as "最低分" from sc join course as co on co.cno=sc.cno group by sc.cno;
這是上面一條復(fù)雜的查詢,如果每次用這個(gè)就寫(xiě)一次,這么長(zhǎng)肯定很麻煩,這就可以將它保存為視圖:
create view mytest_view as select co.cname,max(sc.score) as "最高分",min(sc.score) as "最低分" from sc join course as co on co.cno=sc.cno group by sc.cno;
可以在前面增加創(chuàng)建視圖:create view 視圖名字 as
此時(shí)就可以直接使用:
select * from mytest_view;
結(jié)果:
?
在 MySQL 5.7 中,有三個(gè)庫(kù)用于存儲(chǔ)視圖:information_schema,performance_schema,sys
這里主要談?wù)?information_schema 中的 tables 表,其中主要的字段包括:
字段名稱 | 作用 |
---|---|
TABLE_SCHEMA | 庫(kù)名 |
TABLE_NAME | 表名 |
ENGINE | 引擎 |
TABLE_ROWS | 表的行數(shù) |
AVG_ROW_LENGTH | 表中行的平均大?。ㄗ止?jié)) |
DATA_LENGTH | 數(shù)據(jù)占用空間大?。ㄗ止?jié)) |
INDEX_LENGTH | 索引占用空間大?。ㄗ止?jié)) |
可以直接查詢:
select TABLE_SCHEMA,TABLE_NAME,ENGINE,TABLE_ROWS,AVG_ROW_LENGTH,DATA_LENGTH,INDEX_LENGTH from tables;
?
示例:
a. 顯示每個(gè)庫(kù)都有哪些表:
select TABLE_SCHEMA,group_concat(TABLE_NAME) from information_schema.tables group by TABLE_SCHEMA;
結(jié)果類似:
| world | countrylanguage,country,city|
?
b. 統(tǒng)計(jì)所有庫(kù)下表的個(gè)數(shù):
select TABLE_SCHEMA,count(TABLE_NAME) from information_schema.tables group by TABLE_SCHEMA;
結(jié)果:
?
c. 統(tǒng)計(jì) world 下面每張表所占的磁盤:
select TABLE_NAME,concat((DATA_LENGTH INDEX_LENGTH)/1024, " KB") as LENGTH from information_schema.tables where TABLE_SCHEMA="world";
結(jié)果:
當(dāng)然會(huì)發(fā)現(xiàn)小數(shù)位數(shù)太多,沒(méi)啥意義,可以設(shè)置小數(shù):保留兩位
select TABLE_NAME,concat(round((DATA_LENGTH INDEX_LENGTH)/1024, 2)," KB") as LENGTH from information_schema.tables where TABLE_SCHEMA="world";
結(jié)果:
?
d. 統(tǒng)計(jì)所有庫(kù)占用大?。?/p>
select TABLE_SCHEMA,concat(round(sum(DATA_LENGTH INDEX_LENGTH)/1024,2)," KB") as DB_LENGTH from information_schema.tables group by TABLE_SCHEMA;
結(jié)果:
?
e. 統(tǒng)計(jì)整個(gè)庫(kù)占用的空間:
select concat(sum(DATA_LENGTH INDEX_LENGTH)/1024," KB") as TOTAL_LENGTH from information_schema.tables;
結(jié)果:
?
f. 假設(shè)現(xiàn)在有 1000 張表,需要單獨(dú)生產(chǎn)備份語(yǔ)句,就需要用到 SQL 拼接:
mysqldump -uroot -p123 world city >/tmp/world_city.sql
這是備份單個(gè)表的語(yǔ)句,如果需要備份 1000 個(gè),可以使用 SQL 來(lái)生成:
select concat("mysqldump -uroot -p123 ",TABLE_SCHEMA," ",TABLE_NAME," >/tmp/",TABLE_SCHEMA,"_",TABLE_NAME,".sql") from information_schema.tables where TABLE_SCHEMA="world";
結(jié)果如下:
但這只是單純的 SQL 結(jié)果,可以將其輸出到文件:前提是在 /etc/my.cnf 中指定安全目錄?secure-file-priv=/tmp
select concat("mysqldump -uroot -p123 ",TABLE_SCHEMA," ",TABLE_NAME," >/tmp/",TABLE_SCHEMA,"_",TABLE_NAME,".sql") from information_schema.tables where TABLE_SCHEMA="world" into outfile '/tmp/1.sh'
?
12. show 命令如下表
命令 | 作用 |
---|---|
show databases; | 查看數(shù)據(jù)庫(kù) |
show tables; | 查看表 |
show tables from information_schema; | 查看指定庫(kù)的表 |
show create database world; | 查看建庫(kù)語(yǔ)句 |
show create table city; | 查看建表語(yǔ)句 |
show grants for root@'%'; | 查看用戶授權(quán) |
show charset; | 查看支持的編碼 |
show collation; | 查看數(shù)據(jù)庫(kù)支持的排序規(guī)則 |
show processlist; | 查看數(shù)據(jù)庫(kù)連接情況 |
show index from city; | 查看表索引情況 |
show status; | 查看數(shù)據(jù)庫(kù)情況 |
show status like '%lock%'; | 模糊查詢數(shù)據(jù)庫(kù)狀態(tài) |
show variables; | 查看數(shù)據(jù)庫(kù)配置信息 |
show variables like "%timeout%"; | 模糊查詢配置信息 |
show engines; | 查看存儲(chǔ)引擎 |
show engine innodb status\G | 查看 innodb 相關(guān)信息 |
show binary logs; | 列舉所有二進(jìn)制日志 |
show master status; | 查看數(shù)據(jù)庫(kù)日志位置 |
show binlog evnets in xxx | 查看二進(jìn)制日志事件 |
show slave status\G | 查看從庫(kù)狀態(tài) |
show relaylog events; | 查看從庫(kù) relaylog |
?
?
小結(jié)?
?
增刪查改的核心語(yǔ)句都在這里,內(nèi)容非常多!
來(lái)源:https://www.icode9.com/content-2-389751.html聯(lián)系客服