當(dāng)前位置:首頁 > IT技術(shù) > 數(shù)據(jù)庫 > 正文

一篇文章簡述mysql
2021-09-17 19:49:17

::: 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語句的分類:

:::

  1. DQL:數(shù)據(jù)查詢語言(凡是帶有select關(guān)鍵字的都是查詢語句)
  2. 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 表名;
image.png

ifnull 是空處理函數(shù),在所有數(shù)據(jù)庫當(dāng)只當(dāng)中,只要有null參與的運(yùn)算,最終結(jié)果都是null;**
select name, sal+comm from 表名;**
image.png

*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 表名;
image.png

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 表名;
image.png

::: 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 表名;
image.png
eg:計(jì)算出最低工資
select min(sal) from 表名;
image.png
eg:計(jì)算出員工的全體總工資
select sum(sal) from 表名;
image.png
eg:計(jì)算出全體員工的平均工資:
select avg(sal) from 表名;
image.png
eg:計(jì)算出這家公司有多少人
select count(name) from 表名;
image.png

分組函數(shù)在使用的時候需要注意哪些?

注意事項(xiàng)1.分組函數(shù)自動忽略null
image.png
*2注意事項(xiàng)二.eg:count()和count()的區(qū)別是什么?*
select coutn(
) from 表名;
image.png

selet count(comm) from 表名;
image.png

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 表名;
image.png
::: 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;

image.png

  • 語句的執(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 部門編號;

image.png
例題2:找出每個部門,不同工作崗位的最高薪資

select 工作崗位,部門, max(sal) from 表名 group by 部門,工作崗位;
image.png

例題三:使用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 部門;

image.png

例題四: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;

image.png

把查詢結(jié)果去除重復(fù)記錄(distinct)

select job from 表名
image.png
select distinct job from 表名
image.png

distinct出現(xiàn)在兩個字段之前,表示,這兩個字段聯(lián)合起來去重。

select distinct job,deptno from 表名;
image.png
例如:統(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)連接:

  1. 等值連接
  2. 非等值連接
  3. 自連接
    外連接:
  4. 左外連接:
  5. 右外連接:
    全連接

    注意:當(dāng)兩張表進(jìn)行連接查詢的時候,沒有任何條件的限制會發(fā)生什么現(xiàn)象???

    笛卡爾積現(xiàn)象,它是一個數(shù)學(xué)現(xiàn)象。
    避免笛卡爾積現(xiàn)象!??!
    連接時加條件,滿足這個條件的記錄篩選出來,但是匹配次數(shù)是沒有減少的,只不過把條件符合的篩選出來

    select 
    name,num
    from 
    表一,表二
    where
    表一.編號 = 表二.編號;

    image.png

提高效率,可以給表起別名

image.png

我們來看一下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)名
image.png
技巧:一張表看成兩張表,

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

開通會員,享受整站包年服務(wù)立即開通 >