::: hljs-center
1.SQL概述
:::
SQL用來和數(shù)據(jù)庫打交道的,完成和數(shù)據(jù)庫的通信,SQL是一套標(biāo)準(zhǔn),但是每一個數(shù)據(jù)庫都有自己覺得特性,別的數(shù)據(jù)庫沒有,當(dāng)時用這個數(shù)據(jù)庫特性相關(guān)的功能,這是SQL語句可能就不是標(biāo)準(zhǔn)了。
::: hljs-center
2.什么是數(shù)據(jù)庫:
:::
數(shù)據(jù)庫,通常是一個或者一組文件,保存了一些符合特定規(guī)格的數(shù)據(jù),數(shù)據(jù)庫對應(yīng)的英語單詞是DataBase,簡稱DB,數(shù)據(jù)庫軟件稱為數(shù)據(jù)庫管理系統(tǒng)個(DBMS),如Oracle,SQL Server,MySQL,,,,
::: hljs-center
3.mysql概述
:::
Mysql最初是由MySQL AB公司開發(fā)的一套關(guān)系型數(shù)據(jù)庫管理系統(tǒng),Mysql不僅是最流行的開源數(shù)據(jù)庫,二期是業(yè)界成長最快的數(shù)據(jù)庫,每天有超過7萬次的下載量,其應(yīng)用范圍從大型企業(yè)到專有的嵌入應(yīng)用系統(tǒng)
MySQL AB是由兩個瑞典人和一個芬蘭人在瑞典創(chuàng)辦的,從08年初Sun Microsystems收購了MySQL AB公司,在09年Orcle收購了Sun公司,使Mysql并入Oracle的數(shù)據(jù)庫產(chǎn)品線
::: hljs-center
增刪改查:crud
:::
C:Create(增)
R:retrive(查:檢索)
U:update(改)
D:Delete(刪)
::: hljs-center
4.sql語句的分類:
:::
- DQL:數(shù)據(jù)查詢語言(凡是帶有select關(guān)鍵字的都是查詢語句)
- DML:數(shù)據(jù)操作語言(凡是對表中數(shù)據(jù)進(jìn)行增刪改的都是DML)
::: hljs-center
::: hljs-left
insert delete update
:::
:::
insert增
delete刪
update改
3.DDL:數(shù)據(jù)定義語言(凡是帶有create drop alter都是DDL)DDL主要操作的是結(jié)構(gòu),不是數(shù)據(jù)
create :新建 drop:刪 alter:改
這個增刪改和DML不同,這個主要是對表結(jié)果進(jìn)行操作
4.TCL:事物控制語言(包括事物提交commit,事物回滾:rollback)
5.DCL:數(shù)據(jù)控制語言(授權(quán)grant,撤銷權(quán)限r(nóng)evoke)
::: hljs-center
5.mysql常用的命令
:::
::: hljs-center
- 登陸命令:mysql -uroot -p 密碼
- 查看數(shù)據(jù)庫:show databases;
- 使用數(shù)據(jù)庫:use mysql;
- 查詢數(shù)據(jù)庫中的表 :show tables;
- 查看表中的數(shù)據(jù):select * from 表名字
- 查看表的結(jié)構(gòu):desc 表名字
- 查看mysql數(shù)據(jù)庫的版本號:select version();
- 查看當(dāng)前使用的數(shù)據(jù)庫:select database();
- 終止命令的輸入:ctlr +c
- 注意:mysql是不見 “;” 不執(zhí)行,“;”表示結(jié)束?。。?/strong>
-
:::
::: hljs-center
6.簡單查詢
:::
1.查詢一個字段 :
select 字段名 from 表名
其中要注意:
select 和from都是關(guān)鍵字,都是標(biāo)識符
對于sql語句都是通用的,都是以‘;’結(jié)尾,素有sql語言不區(qū)分大小寫
2.查詢表的結(jié)構(gòu):
desc 表名;
3.查詢一個字段:
select 字段一 from 表名;
4.查詢兩個或者多個字段,使用逗號隔開
select 字段一,字段二 from 表名;
5.查詢所有字段:
5.1.把所有字段都寫上
select a,b,c,d,e,f from 表名;
5.2.可以使用
selectl from 表名;6.給查詢的列起別名(as關(guān)鍵字)
select 字段1,字段二 as字段二的別名 from 表名;
注意:只是更改了顯示結(jié)果,原表沒改的。select不會進(jìn)行修改操作的,它只提供查詢。
as關(guān)鍵字可以省略,用空格代替
select 字段1,字段二 空格 字段二的別名 from 表名;
假設(shè)起別名的時候,別名里面有空格怎么辦???
解決方法:
select 字段1,字段二 空格(as) ‘字段二的別名’ from 表名;
如果別名是中文的話,就要用單引號括起來
select 字段一,字段二*12 as ‘中文別名’ from 表名;
7.字段可以使用數(shù)學(xué)表達(dá)式
比如計(jì)算字段二的12個月的工資情況。
select 字段一,字段二*12 as 字段二別名 from 表名;
::: hljs-center
7.條件查詢where:(篩選)
:::
7.1不是將表中所有的數(shù)據(jù)都查找出來,是查詢出來符合條件的
查詢格式:
select
字段1,字段2,字段3
from
表名
where 條件;
7.2條件包括有:
= 等于
查詢薪資等于800的姓名和編號
select name,num from 表名 where sal=800;
<> 或者 != 不等于
查詢薪資不等于800的姓名和編號
select name,num from 表名 where sal!=800;
select name,num from 表名 where sal<>800;
< 小于
查詢薪資小于2000的員工姓名和編號
select name.num from 表名 where sal < 2000;
<=小于等于
查詢薪資小于等于2000的員工姓名和編號
select name,num from 表名 where sal <= 3000;
**> 大于
=大于等于
同理;**
between and 介于兩者之間
查詢薪資在2450到3000之間的員工信息,包括2450和3000
**第一種方法:>= and <=**
select
name,num
from
表名
where
sal >= 2450 and sal <= 3000 ;
**第二種方法:between and**
select
name,num
from
表名
where
sal between 2450 and 3000 ;
查詢哪些員工的津貼補(bǔ)助為null
is null 為null
is not null 不為null
select name,num from 表名 where comm is null;在數(shù)據(jù)庫中,null不能使用=進(jìn)行衡量,需要使用is null,null代表什么也沒有,不是一個值,所以不能使用等號。
查詢哪些員工的津貼補(bǔ)助不為null
select name,num from 表名 where comm is not null;
查詢工作崗位為MANAGER并且工資大于2500的員工信息
and 并且
select name,num from 表名 where job='MANAGER' and sal > 2500;
or 或者
查詢工作崗位是manage和工作崗位是SALESMAN的員工
select name,num,job from 表名 where job = 'manage' or job = 'SALESMAN';
in 包含,相當(dāng)于多個or
查詢工作崗位是manage和salesman的員工
select name,num,job from 表名 where job in ('manage','saleman');
eg:查詢薪資是800和5000的員工信息
select name,num,sal from 表名 where sal = 800 or sal = 5000;
select name,num,sal from 表名 where sal in (800,5000);
not in 不在這幾個值中的數(shù)據(jù)
select name,num,sal from 表名 where sal not in (800,3000,5000);
like 稱為模糊查詢,支持%或者下劃線匹配
%:匹配任意多個字符
下劃線:一個下劃線只匹配一個字符
eg:找出名字中含有字母O 的
select name from 表名 where name like '%O%';
2.找出名字以T 結(jié)尾的
select name from 表名 where name like '%T';
找出第二個字母是A 的
select name from 表名 where name like '_A%';
找出以k開頭的名字
select name from 表名 where name like ‘K%’;
找出第三個字母是R的名字
select name from 表名 where name like '__R%';
找出名字中有‘_’的 (轉(zhuǎn)義字符)
select name form 表名 where name like '%_%';
::: hljs-center
7排序數(shù)據(jù)
:::
單一字段排序
排序采用order by 子句,order by后面跟上排序的字段,排序字段可以放多個,多個采用逗號分隔,order by默認(rèn)采用升序,如果存在where子句,那么order by 必須到where語句的后面
按照薪水由小到大排序(系統(tǒng)默認(rèn)是由小到大)
查詢所有員工薪資排序
select name.num.sal from 表名 order by sal;
降序
select name.num.sal from 表名 order by sal desc;
兩個或者兩個以上的字段排序
薪資一樣的話,就安裝員工的姓名排序(升序)
select
name,num
from
表名
order by
sal asc,name asc;
sal在前,起主導(dǎo),只有sal相等的時候,才會考慮name.
根據(jù)字段的位置可以進(jìn)行排序
按照查詢結(jié)果的第二列sal進(jìn)行排序。
select name.num,sal from 表名 order by 2;
eg:找出工資在1250到3000之間的員工信息,要求按照薪資降序排列
select name,num,sal from 表名 where sal between 1250 and 3000 order by sal desc;
::: hljs-center
8.數(shù)據(jù)處理函數(shù)
:::
數(shù)據(jù)處理函數(shù)又被稱為單行處理函數(shù),
單行處理函數(shù):一個輸入對應(yīng)一個輸出
多行處理函數(shù):多個輸入對于一個輸出
單行處理函數(shù)常見的有:
::: hljs-center
- Lower 轉(zhuǎn)換小寫
- upper 轉(zhuǎn)換大寫
- substr取子串(截取的字符串,起始下標(biāo),截取的長度)注意:起始下標(biāo)從1開始
- concat 字符串拼接
- length 取長度
- trim 去空格
- str_to date 將字符串轉(zhuǎn)換成日期
- date_format 格式化日期
- format 設(shè)置千分位
- round 四舍五入
- rand() 生成隨機(jī)數(shù)
- Ifnull 可以將null轉(zhuǎn)換成一個具體值
- case..when..than..when..then..else..end 當(dāng)什么時候怎么做,其他時候怎么做。
:::
eg:lower例子
select lower(name) from 表名;
eg:upper例子
select upper(name) from 表名;
eg:找出員工名字第一個字母是A的員工信息
第一種方式:
select name,num from 表名 where name like 'A%';
第二種方式:
select name,num from 表名 where substr(name,1,1) = 'A';
eg:concat字符串拼接
select concat(name,num) from 表名;
eg:length取字符串長度
select length(name) as namelength from 表名;
eg:trim 去空格
select * from 表名 where name = trim (' hahahah');
eg:round 四舍五入保留整數(shù)位: select round(1234.56,0) from 表名; 保留一位小數(shù): select round(1234.56,1) from 表名; 精確到十分位: select round(1234.56,-1) from 表名;
eg:生成隨機(jī)數(shù)
select rand() from 表名;
100以內(nèi)的隨機(jī)數(shù):select round(rand()*100,0) from 表名;
ifnull 是空處理函數(shù),在所有數(shù)據(jù)庫當(dāng)只當(dāng)中,只要有null參與的運(yùn)算,最終結(jié)果都是null;**
select name, sal+comm from 表名;**
*select name,(sal+comm)12 from 表名; 這是錯誤的做法
ifnull(數(shù)據(jù),被當(dāng)做哪個值),當(dāng)補(bǔ)助為null的時候,把補(bǔ)助當(dāng)做0 來計(jì)算。**
select name,(sal+ifnull(comm,0))*12 from 表名;
eg:當(dāng)員工的工作崗位是manage的時候,工資上漲10%,當(dāng)工作崗位是salesman的時候,公司上調(diào)50%
select name,job,sal as oldsal(case job when 'manage' than sal81.1 when 'saleman' than sal*1.5 else sal end) as newsal from 表名;
::: hljs-center
9.分組函數(shù)(多行處理函數(shù))
:::
多行處理函數(shù)的特點(diǎn):輸入多行,最終輸出一行
::: hljs-center
#### 5個分組函數(shù)
- count 計(jì)數(shù)
- sun 求和
- max 最大值
- min 最小值
- avg 平均值
:::
eg:計(jì)算出最高工資
select max(sal) from 表名;
eg:計(jì)算出最低工資
select min(sal) from 表名;
eg:計(jì)算出員工的全體總工資
select sum(sal) from 表名;
eg:計(jì)算出全體員工的平均工資:
select avg(sal) from 表名;
eg:計(jì)算出這家公司有多少人
select count(name) from 表名;
分組函數(shù)在使用的時候需要注意哪些?
注意事項(xiàng)1.分組函數(shù)自動忽略null
*2注意事項(xiàng)二.eg:count()和count()的區(qū)別是什么?*
select coutn() from 表名;selet count(comm) from 表名;
count(*):表示統(tǒng)計(jì)表中的總行數(shù),(只要有一行數(shù)據(jù),count++)
count(comm) :表示統(tǒng)計(jì)該字段下所有部位NULL的元素的總數(shù)。
注意事項(xiàng)三:所有的分組函數(shù)可以組合起來一起用
select sum(sal),min(sal),max(sal),avg(sal),count(*) from 表名;
::: hljs-center
10.分組查詢
:::
分組查詢:在實(shí)際的應(yīng)用各種,可能喲這樣的需求,先進(jìn)行分組,對每一組的數(shù)據(jù)進(jìn)行操作,這個時候,我們需要分組查詢,如何來分組查詢呢?
select …… from …… group by ……
將之前的關(guān)鍵字全部組合在一起,看一下他們的執(zhí)行順序
select
……
from
……
where
……
group by
……
order by
……
執(zhí)行順序是
from------where-------group by -------select----order by
注意事項(xiàng)四:分組函數(shù)不能直接使用在where字句中
eg:找出比最低工資高的員工信息
select name,num from 表名 where sal > min(sal);
- 這是錯誤滴,會報(bào)錯,為什么呢???
- 因?yàn)閣here在group by分組函數(shù)之前?。。?!
列如:找出每個工作崗位的工資和
select job,sum(sal) from 表名 group by job;
- 語句的執(zhí)行順序:先從表總查詢數(shù)據(jù)
- 2.根據(jù)job字段進(jìn)行分組
- 3.然后對每一組的數(shù)據(jù)進(jìn)行sum(sal)
重點(diǎn)結(jié)論:在一條select語句當(dāng)中,如果有g(shù)roup by語句的話,select后面只能跟參加分組的字段,以及分組函數(shù)之外,其他的一律都不要加?。。。?/strong>
例如1:找出每個部門的最高薪資
select 部門編號,max(sal) from 表名 group by 部門編號;
例題2:找出每個部門,不同工作崗位的最高薪資
select 工作崗位,部門, max(sal) from 表名 group by 部門,工作崗位;
例題三:使用having可以對分完組之后的數(shù)據(jù)進(jìn)一步過濾,having必須和group by聯(lián)合使用,
找出每個部門的最高薪資,要求顯示最高薪資大于3000?
select 部門,max(sal) from 表名 group by 部門 having max(sal) > 3000;
方法二:先篩選出>3000過濾掉,然后在分組,在進(jìn)行查詢。
select 部門,max(sal) from 表名 where sal> 3000 group by 部門;
例題四:where沒有辦法的
找出每個部門的平均薪資,要求顯示平均薪資高于2500的
select 部門 avg(sal) from 表格 group by 部門 having avg (sal)>2500;
select 部門 avg(sal) from 表格 where avg(sal)>2500 group by 部門 ;
這是錯誤的,因?yàn)橐驗(yàn)椋纸M是在where之后執(zhí)行的,而avg(sal)是分組函數(shù)。所以在這里只能使用having。
例題五:找出每個崗位的平均薪資,要求顯示平均薪資大于1500的,除開manage之外,要求按照平均薪資降序排序
select 崗位,avg(sal) from 表名 where job != 'manage' group by 崗位 having avg(sal) > 1500 order by avg(sal) desc;
把查詢結(jié)果去除重復(fù)記錄(distinct)
select job from 表名
select distinct job from 表名
distinct出現(xiàn)在兩個字段之前,表示,這兩個字段聯(lián)合起來去重。
select distinct job,deptno from 表名;
例如:統(tǒng)計(jì)一下工作崗位的數(shù)量?
select count(dostomct job) from 表名
::: hljs-center
11.連接查詢
:::
連接查詢的概念:
從一張表中淡出查詢,稱為單標(biāo)查詢
多張表聯(lián)合起來查詢數(shù)據(jù),被稱為連接查詢。連接查詢的分類:
1.根據(jù)語法的年代分類:
SQL92:1992年出現(xiàn)的語法
SQL99:1999年出現(xiàn)的語法2.根據(jù)表連接查詢的方式分類:
內(nèi)連接:
- 等值連接
- 非等值連接
- 自連接
外連接:- 左外連接:
- 右外連接:
全連接注意:當(dāng)兩張表進(jìn)行連接查詢的時候,沒有任何條件的限制會發(fā)生什么現(xiàn)象???
笛卡爾積現(xiàn)象,它是一個數(shù)學(xué)現(xiàn)象。
避免笛卡爾積現(xiàn)象!??!
連接時加條件,滿足這個條件的記錄篩選出來,但是匹配次數(shù)是沒有減少的,只不過把條件符合的篩選出來select name,num from 表一,表二 where 表一.編號 = 表二.編號;
提高效率,可以給表起別名
我們來看一下92語法和99語法的語法格式
比如,顯示員工屬于哪個部門,并且顯示出員工和部門信息
SQL92
select
表一別名.姓名,表二別名.部門
from 表一 別名 ,表二 別名
where
表一別名.部門編號 = 表二別名.部門編號;
SQL99
select
表一別名.姓名,表二別名.部門
from
表一 別名 join 表二 別名
on
表一別名.部門編號 = 表二別名.部門編號;
……
where 篩選條件
以上可以看出,sql92的缺點(diǎn),結(jié)果不清晰,表的連接條件,和后期進(jìn)一步篩選的條件都放到where中
sql99的優(yōu)點(diǎn):表連接的條件是獨(dú)立的,連接之后,如果還需要進(jìn)一步篩選,可以在語句后面加where,
內(nèi)連接之等值連接(inner)
select
e.ename,d,dname
from
emp e
inner join
emp b
on
e.deptno = d.deptno;
內(nèi)連接之非等值連接
條件不是一個等量關(guān)系,稱為非等值連接。
eg:找出每個員工的薪資等級,要求顯示員工名,薪資,薪資等級。
select
a.ename,a,sal,s.grade
from
emp a
inner join
salgrade s
on
a.sal between s.losal and s.hisal;
內(nèi)連接之自連接
eg:查詢員工的上級領(lǐng)導(dǎo),要求顯示員工名和對應(yīng)的領(lǐng)導(dǎo)名
技巧:一張表看成兩張表,
select
a.ename as ‘員工名’,b.ename '領(lǐng)導(dǎo)名'
from
emp a
join
emp b
on a.mgr = b.empno;
外連接
外連接(右外連接right)
select
e.ename, d.dname
from
emp e right join dept d
on
e.deptno = d.deptno;
外連接(左外連接 left)
select
e.name , d.name
from
dept d left join emp e
on
e.deptno = d.deptno;
right 代表join關(guān)鍵字右邊的這張表看成主表,主要是為了將這張表的數(shù)據(jù)全部查詢出來,捎帶著關(guān)聯(lián)查詢左邊的表,在外連接當(dāng)中個,兩張表連接,產(chǎn)生了主次關(guān)系
帶有right的是右連接,
帶有l(wèi)eft的是左連接
任何一個右或者左連接都有他們左或者右的寫法。
//outer 可以省略select e.name , d.name from dept d left outer join emp e on e.deptno = d.deptno;
**eg:查詢每個員工的上級領(lǐng)導(dǎo),要求顯示所有員工的名字和領(lǐng)導(dǎo)名。**
select
a.ename,b.ename
from
emp a left join emp b
on
a.mgr = b.empno;
![image.png](https://s2.51cto.com/images/20210914/1631597445368174.png)
#### 多張表怎么連接
select
……
from
a
join
b
on
a和b的條件
join
c
on
a和c的條件
right join
d
on
a和d的條件
**一條sal語句中,內(nèi)連接和外連接都能夠混合使用,**
> eg:找出每個員工的部門名稱,以及工資等級,要求顯示員工名 工資 部門名 薪資等級
select
e.ename,e.sal,d.dname,s.grade
from
emp e
join
dept d
on
e.deptno = d.deptno;
join
salgrade s
on
e.sal between s.losal and s.hisal;
::: hljs-center
## 12.子查詢
:::
#### 什么是子查詢:
> select 語句中嵌套了select語句,被嵌套的select語句稱為子查詢
#### 子查詢都可以出現(xiàn)在哪里呢?
select
……(select)
from
……(select)
where
……(select)
……
#### where字句中的子查詢
> eg:找出比最低公司高的員工姓名和工資
select
ename,sal
from
emp
where
sal>(select min(sal) from emp);
#### from字句中的子查詢
**from后面的子查詢,可以把子查詢中的結(jié)果當(dāng)做一張臨時表。**
eg:找出每個崗位的平均工資的薪資等級
> 每個崗位的平均工資:
select job,avga(sal) from emp group by job;
等級:
select
t.*,s.grand
from
(select job,avga(sal) as sal from emp group by job) t
join
salgrade s
on
t.sal between s.losal and s.hisal;
#### select出現(xiàn)的子查詢
eg:找出每個員工的部門名稱,要求顯示員工名和部門名??
select
e.name e.deptno,
(select d.dname from dept d where
e.deptno = d.deptno) as dname
from emp e;
![image.png](https://s2.51cto.com/images/20210914/1631600860120199.png)
## union合并查詢結(jié)果
> eg:查詢工作崗位是manage和saleman的員工
select
ename,jog
from
emp
where
job='manage'or job='saleman';
union的使用
select ename,job from emp where job = 'manage';
union
select ename,job from emp where job = 'saleman';
union的優(yōu)點(diǎn):
> union的效率高一些,對于表連接來說,每連接一次新表,則匹配的次數(shù)滿足笛卡爾積,但是union可以減少匹配的次數(shù),在減少匹配次數(shù)的情況下,還可以完成兩個結(jié)果的拼接
**注:union使用的注意事項(xiàng):
union在進(jìn)行結(jié)果集合并的時候,要求結(jié)果集的列數(shù)要想同?。?!**
select ename from emp where job = 'manage';
union
select ename,job from emp where job = 'saleman';
**這樣就是錯誤的**
::: hljs-center
## 14.limit分頁查詢
:::
> limit:顯示結(jié)果集的一部分?jǐn)?shù)據(jù)。
分頁的作用:提高用戶的體驗(yàn),因?yàn)橐淮稳慷疾槌鰜?,用戶體驗(yàn)差,可以翻頁查看。
limit的使用:
eg:安裝薪資降序,取出排序在前五名的員工
select
ename,sal
from
emp
order by
sal desc
limit 5;
**完整寫法:**
limit的用法,后面可以跟兩個數(shù)字,
limit startIndex (起始下標(biāo),從0開始), length(長度);
**缺省用法:**
limit 5;取前五
**在myql中,limit在order by之后執(zhí)行。**
eg:取出工資排名在3-5名的員工
select
ename,sal
from
emp
order by
sal desc
limit 2,3;
> eg:取出工資5-9名的員工
select
ename,sal
from
emp
order by
sal desc
limit 4,5;
## 分頁
**每頁顯示3條記錄**
第一頁:limit 0,3
第二頁:limit 3,3
第三頁:limit 6,3
第四頁:limit 9,3
每頁顯示pagesize條記錄,第pagenum頁:
limit (頁碼-1)*pagesize,pagesize;
關(guān)于DQL語句總結(jié):
select
……
from
……
where
……
group by
……
having
……
order by
……
limit
> 執(zhí)行順序:
from --- where---- group by ----having---- select---- order by ----limit
::: hljs-center
## 15.表的創(chuàng)建
:::
#### 1.建表的語法格式(DDL)
create table 表名 (
字段名1 數(shù)據(jù)類型,
字段名2 數(shù)據(jù)類型,
字段名3 數(shù)據(jù)類型);
> 表名:建議以t_或者tbl_開始,可讀性強(qiáng),見名知意。
#### 2.數(shù)據(jù)類型有:
> varchar:可變長度的字符串,會根據(jù)實(shí)際的數(shù)據(jù)長度動態(tài)分配空間。
> char:定長字符串,不管實(shí)際數(shù)據(jù)長度,分配固定長度的空間去存儲數(shù)據(jù)。使用不恰當(dāng),可能會導(dǎo)致空間的浪費(fèi)。
int:數(shù)字中的整型,最長(11位)
bigint:數(shù)字中的長整型
float:單精度
double:雙精度
date:短日期類型
datetime:長日期
clob:字符大對象,最多可以存儲4G的字符串(255位)
比如:文章,說明,簡介
blob:二進(jìn)制大對象,專門用來存儲圖片,聲音,視頻,等流媒體數(shù)據(jù)。往BLOB類型字段上插入數(shù)據(jù)的時候,需要使用IO流
**
eg:創(chuàng)建一個學(xué)生表**
學(xué)號、姓名、性別、年齡、郵件地址
create table t_student (
num int,
name varchar(20),
sex char(1),
age int(3)
e-mail varchar(255));
**刪除表** drop table t_student; //當(dāng)這張表不存在的時候會報(bào)錯
drop table if exists t_student ; //當(dāng)這張表存在的時候刪除
![image.png](https://s2.51cto.com/images/20210915/1631689867131213.png)
#### 4.插入數(shù)據(jù):insert(DML)
語法格式
insert into 表名 (字段名1,字段名2,字段名3,……) values(值1,值2,值3,……);
注意:字段名和值要一一對應(yīng),數(shù)據(jù)類型要對應(yīng),
eg:
mysql> insert into t_student (no,name,age,sex,email) values (1,'張三',20,'m','zhangsan@qq.com');
![image.png](https://s2.51cto.com/images/20210915/1631690853156958.png)
**注意:前民的字段可以省略,后面的值必須要一一對應(yīng)寫上,!!**
#### 5.格式化數(shù)字:format(數(shù)字,‘格式’)
#### str_to_date 將字符串轉(zhuǎn)換為日期類型
> 語法格式:str_to_date(‘字符串日期’,‘日期格式’)
> mysql的日期格式有:%Y/%m/%d/%h/%i/%s
![image.png](https://s2.51cto.com/images/20210915/1631693743713591.png)
#### date format 將日期類型轉(zhuǎn)換成特定格式
**date format(日期類型數(shù)據(jù),‘日期格式’)**
> 它會自動將數(shù)據(jù)庫中的date類型轉(zhuǎn)換成varchar類型,并且采用的格式是mysql的默認(rèn)的日期格式。
![image.png](https://s2.51cto.com/images/20210915/1631694194875513.png)
#### date和datetime兩個類型的區(qū)別
> date:是短日期,只包括年月日信息
datetime長日期,包括年月日時分秒信息
![image.png](https://s2.51cto.com/images/20210915/1631694780884609.png)
#### now()獲取系統(tǒng)當(dāng)前時間
![image.png](https://s2.51cto.com/images/20210915/1631694944195268.png)
## 修改update(DML)
語法格式:
> update 表名 set 字段名1=值1字段名2=值2,字段名3=值三,…… where 條件;
注意:如果不加where條件,會導(dǎo)致所有的數(shù)據(jù)全部更新?。。?!
![image.png](https://s2.51cto.com/images/20210915/1631695512960181.png)
## 刪除數(shù)據(jù)delete(DML)
delect from 表名 where 條件
注意:沒有條件,整張表的數(shù)據(jù)都會刪除。
![image.png](https://s2.51cto.com/images/20210915/1631695817841801.png)
![image.png](https://s2.51cto.com/images/20210915/1631695865318492.png)
**注意:delete刪除之后可以回滾數(shù)據(jù),可以恢復(fù)數(shù)據(jù),數(shù)據(jù)在硬盤上的真實(shí)存儲空間不會被釋放,缺點(diǎn)是:刪除效率比較低,**
**truncate:語句刪除效率比較高,表被一次性清理了,不能恢復(fù)。
**
> truncate table表名;
![image.png](https://s2.51cto.com/images/20210915/1631699684540977.png)
#### insert可以一次性插入多條記錄
語法格式:
> insert into t_time (字段名1,字段名2,字段名3) values(值1,值二,值三),(值1,值二,值三);
![image.png](https://s2.51cto.com/images/20210915/1631698676167062.png)
#### 快速創(chuàng)建表
語法格式
**create table 表名 as select * from 表二;**
> 原理:將一個查詢結(jié)果當(dāng)做一張表新建
這個可以完成表的快速復(fù)制
表創(chuàng)建出來,同時表中的數(shù)據(jù)也存在了
![image.png](https://s2.51cto.com/images/20210915/1631698912196536.png)
#### 表結(jié)構(gòu)的增刪改
alter(修改)
create(創(chuàng)建)
drop(刪除)
> 1.在實(shí)際的開發(fā)中,需求一旦確定設(shè)計(jì)好之后,很少進(jìn)行表結(jié)構(gòu)的修改,添加字段,刪除字段,修改字段等等。
因?yàn)殚_發(fā)進(jìn)行中,修改表結(jié)構(gòu)成本比較高,
::: hljs-center
## 16.約束
:::
約束:約束字段
#### 什么是約束????
> 約束(constraint),在創(chuàng)建表的時候,給表中的字段加一些約束,來保證表中數(shù)據(jù)的完整性和有效性。
#### 約束包括有:
> 非空約束:not null
唯一性約束:unique
主鍵約束:primary key
外鍵約束:foreign key
檢查約束:check
#### 1.非空約束:not null;
它約束的字段不能為null;
![image.png](https://s2.51cto.com/images/20210916/1631760605825609.png)
#### 2.唯一性約束(unique)
> 唯一性約束unique約束的字段不能重復(fù),但是可以為空
![image.png](https://s2.51cto.com/images/20210916/1631761607533434.png)
![image.png](https://s2.51cto.com/images/20210916/1631761626389133.png)
![image.png](https://s2.51cto.com/images/20210916/1631761644954074.png)
#### 表級約束
> 什么時候使用表級約束呢?
需要給多個字段聯(lián)合起來添加某一個約束的時候,需要使用表級約束,not null 沒有表級約束語法,unique有。
![image.png](https://s2.51cto.com/images/20210916/1631764983804028.png)
![image.png](https://s2.51cto.com/images/20210916/1631765000220796.png)
![image.png](https://s2.51cto.com/images/20210916/1631765014828027.png)
#### unique和not null 聯(lián)用
在mysql中,如果一個字段同時被not null和unique同時約束的時候,該字段自動稱為主鍵字段。
![image.png](https://s2.51cto.com/images/20210916/1631765403266026.png)
#### 主鍵約束
#### 1.主鍵約束的相關(guān)術(shù)語
> 主鍵約束、主鍵字段、主鍵值
主鍵約束:就是一種約束
主鍵字段該字段上添加了主鍵約束,這樣的字段叫做:主鍵字段
主鍵值:主鍵字段中的每一個值叫做主鍵值
#### 2.什么是主鍵,有什么用??
> 主鍵值是每一行記錄的唯一標(biāo)識
主鍵值是每一行記錄的身份證號
注意:任何一張表都應(yīng)該有逐漸,沒有主鍵,表無效?。。?!
主鍵的特征:not null + unique(主鍵值不能是null,也不能重復(fù),要具有唯一性)相當(dāng)于身份證號。
**如何給一張表添加主鍵約束**
列級約束:
![image.png](https://s2.51cto.com/images/20210916/1631766689918501.png)
表級約束:
![image.png](https://s2.51cto.com/images/20210916/1631766578261788.png)
多個字段聯(lián)合起來添加一個主鍵約束,
![image.png](https://s2.51cto.com/images/20210916/1631766828647909.png)
####
外鍵約束
外鍵約束可以為NULL,外鍵約束引用的字段不一定是主鍵,但是至少具有unique約束。
![image.png](https://s2.51cto.com/images/20210916/1631775313493945.png)
::: hljs-center
## 17.存儲引擎
:::
**什么存儲引擎???**
> 指定不同的存儲引擎,表的存儲結(jié)構(gòu)不一樣。
如何給表指定存儲引擎
**show create table t_student;**
在建表的時候可以在最后小括號的右邊使用:
![image.png](https://s2.51cto.com/images/20210916/1631776328154697.png)
> ENGINE:來指定存儲引擎
CHARSET:來指定這張表的字符編碼方式
默認(rèn)的存儲引擎是InnoDB
默認(rèn)的字符編碼是UTF-8;
![image.png](https://s2.51cto.com/images/20210916/1631776462766902.png)
#### 查看mysql中支持得存儲引擎
**mysql> show engines G**
::: hljs-center
## 18.事物
:::
> 一個事物其實(shí)就是一個完整的業(yè)務(wù)邏輯。只有dml語句才會喲事物有關(guān),其他語句都和事物無?。。。?因?yàn)橹挥衭pdate insert delete 這三個語句是對數(shù)據(jù)表中的數(shù)據(jù)進(jìn)行增刪改的,只要是涉及到數(shù)據(jù)的增刪改的那么久一定要考慮到安全問題,數(shù)據(jù)安全是第一位。
#### 什么是事務(wù)呢?
> 一個事物就是多條dml語句同時成功或者同時失敗。
#### 事務(wù)是怎么做到多條dml語句同時成功和同時失敗的呢?
> innoDB存儲引擎:提供一組喲哪里記錄事務(wù)性活動的日志文件。
在事務(wù)的執(zhí)行過程中,每一條dml的操作都會記錄到事務(wù)性活動的日志文件中,在事務(wù)的執(zhí)行過程中,我們可以提交事務(wù),也可以回滾事務(wù)。
提交事務(wù):清空事務(wù)性活動的日志文件,將數(shù)據(jù)全部徹底持久化到數(shù)據(jù)庫表中,提交事務(wù)標(biāo)志著,事務(wù)的結(jié)束,并且是一種全部成功的結(jié)束
回滾事務(wù):將之前所有的dml操作全部撤銷,并且清空事務(wù)性活動的日志文件,回滾事務(wù)標(biāo)志著,事務(wù)的結(jié)束,并且是一種全部失敗的結(jié)束
#### 事務(wù)的4個特性:
> 原子性:說明事務(wù)是最小的工作單元,不可再分
一致性:所有事務(wù)要求,在同一個事務(wù)當(dāng)中,多有操作必須同時成功,或者同時失敗,
隔離性:A事務(wù)和B事物之間具有一定的隔離,像教室一樣,教室的那道墻就是隔離性,
持久性:事物最終結(jié)束的一個保障,事物提交,就相當(dāng)于將沒有保存到硬盤上的數(shù)據(jù)保存到硬盤上。
#### 事物的隔離性:
**1.讀未提交:read uncommitted(最低的隔離級別)(沒有提交就已經(jīng)讀到了)**
什么是讀未提交:
事物A可以讀取到事物B未提交的數(shù)據(jù)
這種隔離級別存在的問題就是:
臟讀現(xiàn)象:(Dirty Read)
我們稱為讀到了臟數(shù)據(jù),這種隔離級別一般都是理論上的,大多數(shù)的數(shù)據(jù)庫隔離級別都是二擋起步?。?!
#### 2. 讀已提交:read committed(提交之后才能讀到)
**什么是讀已提交:**
事物A只能讀取到事物B已經(jīng)提交了的數(shù)據(jù)
**這種隔離級別解決了什么問題?**
解決了臟讀現(xiàn)象
**這種隔離級別存在什么問題?**
不可重復(fù)讀取數(shù)據(jù)
**什么是不可重復(fù)讀取數(shù)據(jù)呢?**
在事務(wù)開啟之后,第一次讀到的數(shù)據(jù)是3條,當(dāng)前事務(wù)還沒有結(jié)束,可能第二次在讀取的時候,讀到的數(shù)據(jù)是4條,4不等于3,稱為不可重復(fù)讀取,
> 這種隔離級別是比較真實(shí)的數(shù)據(jù),每一次讀到的數(shù)據(jù)是絕對的真實(shí),oracle默認(rèn)數(shù)據(jù)庫的隔離級別是:read committed
#### 3.可重復(fù)讀(提交之后也讀不到,永遠(yuǎn)讀取的都是剛開始事務(wù))
**什么是可重復(fù)讀????**
事務(wù)A開啟之后,不管是多久,每一次在事務(wù)A中讀取到的數(shù)據(jù)都是一致的,即使事務(wù)B將數(shù)據(jù)已經(jīng)修改,并且提交了,事務(wù)A中
讀取到的數(shù)據(jù)還是沒有發(fā)生改變,這就是可重復(fù)讀。
**可重復(fù)讀解決了什么問題?**
解決了不可重復(fù)讀取數(shù)據(jù)
**可重復(fù)讀存在的問題是什么?**
可能會出現(xiàn)幻影讀
**每一次讀取到的數(shù)據(jù)都是幻象,不夠真實(shí),**
#### 4.序列化/串行化:selializable(最高的隔離級別)
> 這是最高隔離級別,效率最低,解決了所有的問題,這種隔離級別表示事務(wù)排隊(duì),不能并發(fā),每一次讀取到的 **數(shù)據(jù)都是最真實(shí)的,并且效率是最低的**
**eg:使用read uncommitted 讀未提交**
![image.png](https://s2.51cto.com/images/20210916/1631789189732327.png)
![image.png](https://s2.51cto.com/images/20210916/1631789208526989.png)
![image.png](https://s2.51cto.com/images/20210916/1631789229387351.png)
![image.png](https://s2.51cto.com/images/20210916/1631789251261040.png)
::: hljs-center
## 19.索引
:::
#### 什么是索引:
> 索引在數(shù)據(jù)庫表的字段上添加,為了提高檢索查詢效率存在的一種機(jī)制
,一張表的一個字段可以添加一個索引,當(dāng)然,多個字段聯(lián)合起來也可以添加索引,索引相當(dāng)于一本書的目錄,是為了縮小掃描范圍而存在的機(jī)制。
#### 對于一本字典來說,查找某個漢子有兩種方式:
> 1.一頁一頁挨著找,知道找到位置,這種查找方式屬于字典掃描
2.第二種方式,先通過目錄去定位一個大概的位置,然后直接定位到這個位置,做局域性掃描,縮小掃描的范圍,快速的插座,這種查找方式屬于通過索引檢索,效率較高。
![image.png](https://s2.51cto.com/images/20210917/1631866851282560.png)
> 如果name字段上沒有沒有添加索引,或者說沒有給name字段創(chuàng)建索引,mysql會進(jìn)行全掃描,會將name字段上的每一個值都比對一遍,效率比較低,
**mysql在查詢方面主要就是兩種方式:1.全表掃描,2.添加索引(縮小掃描范圍)。**
遵循左小右大原則存放,采用中序遍歷取數(shù)據(jù)
我們來看索引的實(shí)現(xiàn)原理把?。。?!
![image.png](https://s2.51cto.com/images/20210917/1631867336701148.png)
在mysql中,索引是一個單獨(dú)的對象,不同的存儲引擎以不同的形式存在,在myisam存儲引擎中,索引存儲在一個myi文件中,在innoDB存儲引擎中索引存儲在一個邏輯名稱叫做tablespace當(dāng)中,在memory存儲引擎中索引被存儲在內(nèi)存當(dāng)中,不管索引存儲在哪里,索引在mysql當(dāng)中都是一個樹的形式存在(自平衡二叉樹:B-Tree).
![image.png](https://s2.51cto.com/images/20210917/1631867892779421.png)
![image.png](https://s2.51cto.com/images/20210917/1631867968441194.png)
#### 在mysql當(dāng)中,主鍵上,以及unique字段上都會自動添加索引
**什么條件下,我們會考慮給字段添加索引???**
> 條件1:數(shù)據(jù)量龐大
條件二:該字段經(jīng)常出現(xiàn)在where后面,以條件的形式存在,這個字段經(jīng)常被掃描
條件三:該字段很少dml操作,因?yàn)閐ml之后,索引需要重新排序。
#### 索引的創(chuàng)建 刪除 查看
創(chuàng)建索引:
![image.png](https://s2.51cto.com/images/20210917/1631868555405150.png)
![image.png](https://s2.51cto.com/images/20210917/1631868569211908.png)
![image.png](https://s2.51cto.com/images/20210917/1631868881622941.png)
![image.png](https://s2.51cto.com/images/20210917/1631868891587082.png)
#### 索引失效
第一種情況
![image.png](https://s2.51cto.com/images/20210917/1631870496464234.png)
第二種情況
![image.png](https://s2.51cto.com/images/20210917/1631870513913629.png)
第三種情況
![image.png](https://s2.51cto.com/images/20210917/1631870529827712.png)
第四種情況
![image.png](https://s2.51cto.com/images/20210917/1631870546263858.png)
第五種情況:
![image.png](https://s2.51cto.com/images/20210917/1631870575754443.png)
#### 索引在數(shù)據(jù)庫中的分類:
> 單一索引:一個字段上添加索引
復(fù)合索引:兩個字段或者更多的字段上添加索引
主鍵索引:主鍵上添加索引
唯一性索引:具有unique約束的字段上添加索引。
越唯一,效率越高!?。?!
::: hljs-center
## 20.視圖
:::
#### 1.什么是視圖:
> view:站在不同的角度去看待同一份數(shù)據(jù),視圖是用來簡化sql語句的。
#### 2.創(chuàng)建視圖:
create view 視圖名字 as select * from emp;
mysql> create view dept_view as select * from dept2;
Query OK, 0 rows affected (0.01 sec)
#### 3.刪除視圖:
drop view 視圖名
mysql> drop view dept_view;
Query OK, 0 rows affected (0.03 sec)
注意:視圖as后面必須是DQL語句
#### 4.用視圖做什么???
> 我們對視圖對象進(jìn)行增刪改查,會導(dǎo)致原表被操作,
![image.png](https://s2.51cto.com/images/20210917/1631871159192807.png)
視圖更新
**mysql> update dept_view set dname = 'xiejaingmei' where deptno = 60;**
![image.png](https://s2.51cto.com/images/20210917/1631871409896526.png)
假設(shè)有一條非常復(fù)雜的sql語句,而這條sql語句需要在不同的位置上反復(fù)使用,每一次使用這個sql語句的時候都需要重新編寫,很長,很麻煩,怎么辦,可以把這條復(fù)雜的sql語句以視圖對象的形式新建。
![image.png](https://s2.51cto.com/images/20210917/1631871545123313.png)
::: hljs-center
## 21.DBA常用命令
:::
數(shù)據(jù)備份
#### 數(shù)據(jù)導(dǎo)出:在cmd命令行執(zhí)行:
> mysqldump 庫名 >D:位置.sql -uroot -p密碼;
mysqldump 庫名 表名 >D:位置.sql -uroot -p密碼;
![image.png](https://s2.51cto.com/images/20210917/1631872640451661.png)
#### 數(shù)據(jù)導(dǎo)入:
> 進(jìn)入數(shù)據(jù)庫
mysql -u root -p 密碼
創(chuàng)建庫
create database xjm;
使用數(shù)據(jù)庫
use xjm;
初始化數(shù)據(jù)庫
source D:xjm.sal;
::: hljs-center
## 22.數(shù)據(jù)庫設(shè)計(jì)的三范式
:::
數(shù)據(jù)庫表的設(shè)計(jì)依據(jù),教你怎么進(jìn)行數(shù)據(jù)庫表的設(shè)計(jì)
> 第一范式:
要求一張表必須有主鍵,沒一個字段原子性不可再分
第二范式:
建立在第一范式的基礎(chǔ)之上,要求所有非主鍵字段完全依賴主鍵,不要產(chǎn)生部分依賴。
第三范式:完全建立在第二范式基礎(chǔ)之上,要求所有非主鍵字段直接依賴主鍵,不要產(chǎn)生傳遞依賴。
按照以上的范式進(jìn)行,可以避免表中數(shù)據(jù)的冗余,避免空間的浪費(fèi)
**第一范式:最核心,最重要的范式,所有表都需要滿足,必須要有主鍵,并且每一個字段都是原子性不可再分。**
![image.png](https://s2.51cto.com/images/20210917/1631873050247090.png)
第二范式,建立在第一范式基礎(chǔ)之上,要求所有非主鍵字段,完全依賴于主鍵,不要產(chǎn)生部分依賴
![image.png](https://s2.51cto.com/images/20210917/1631873549520370.png)
![image.png](https://s2.51cto.com/images/20210917/1631873582467985.png)
![image.png](https://s2.51cto.com/images/20210917/1631873518807179.png)
第三范式,建立在第二范式的基礎(chǔ)上,要求所有非主鍵字段完全依賴主鍵,不要產(chǎn)生傳遞依賴
![image.png](https://s2.51cto.com/images/20210917/1631873762217185.png)
![image.png](https://s2.51cto.com/images/20210917/1631873858384421.png)
一個班級對應(yīng)多個學(xué)生
## 多對多:三張表,關(guān)系表,兩個外鍵
一對多:二張表 多的表加外鍵
一對一:在實(shí)際開發(fā)中,可能存在一張表字段太多,太龐大,這個時候要拆分表。
#### 總結(jié)表的設(shè)計(jì)
> 一對一:外鍵唯一(fk+unique)
一對多:二張表 多的表加外鍵
多對多:三張表,關(guān)系表,兩個外鍵
本文摘自 :https://blog.51cto.com/u