1. 程式人生 > 實用技巧 >Mysql基礎_SQL語言

Mysql基礎_SQL語言

1. DQL語言的學習

① 基礎查詢

/*
語法:
	select 查詢列表
	from 表名; 
特點:
	① 通過select查詢完的結果 ,是一個虛擬的表格,不是真實存在
	② 要查詢的東西 可以是常量值、可以是表示式、可以是欄位、可以是函式
        ③ 可以沒有from語句
        ④ 先執行from語句,再執行select查詢
*/    
#✳查詢單個欄位
	select 欄位名
	from 表名;
#✳查詢多個欄位
	select 欄位1,欄位2,...,欄位n
	from 表名;
#✳查詢所有欄位(查詢整個表資料)
	select *
	from 表名; #雖然這種方式比較簡單,但是為了提高可讀性,建議不使用*,而是列出所有欄位。
#✳查詢時給欄位起別名(as)
	select 欄位1 【as】 別名1,欄位2 【as】 別名2...
	from 表;  #其中as可以省略,直接用空格
#✳查詢結果去重(distinct)
	select distinct 欄位
	from 表;  

② 條件查詢

/*	條件查詢:根據條件過濾原始表的資料,查詢到想要的資料
語法:
	select 查詢列表
	from 表名
	where 篩選條件;
特點:先執行from語句,在執行where語句,最後執行select語句
分類:
一、✔條件表示式
		> < >= <= = != <> <=>安全等於 
		between 值1 and 值2 	    篩選所需要的值在值1和值2之間,等同於 >=值1 and <=值2
		is null /is not null	    用於判斷null值(也只能判斷null值)
		in / not in		    in是指包含,後面接(值1,值2...),相當於多個or,但效率更高
	注意:安全等於<=>可以判斷null值,而=不能判斷null值
	示例:篩選學生表中:姓名為張三的所有資訊。
		select *
		from students
		where name='張三';

二、✔邏輯表示式
		and(&&):兩個條件如果同時成立,結果為true,否則為false
		or(||):兩個條件只要有一個成立,結果為true,否則為false
		not(!):如果條件成立,則not後為false,否則為true
	示例:篩選學生表中:分數在60和70之間的學生全部資訊。
		select *
		from students
		where score>=60 and scord<=70;

三、✔模糊查詢
		like: 通常搭配萬用字元使用
		萬用字元:%任意多個字元,_任意單個字元(%不能表示null)
	示例:篩選學生表中:姓名第二個字為偉的學生全部資訊
		select *
		from students
		where name like '_偉%';
*/

③ 排序查詢

/*	排序查詢:對查詢的結果按某一欄位進行排序。
語法:
	select 查詢列表
	from 表
	【where 篩選條件】
	order by 排序的欄位|表示式|函式|別名 【asc|desc】;
特點:
	① 可以沒有where篩選語句
	② asc值升序,desc指降序,如果不寫預設為升序
	③ 排序列表支援單個欄位、多個欄位、函式、表示式、別名
	④ order by的位置一般放在查詢語句的最後(除limit語句之外)
	⑤ 先執行from語句,再執行where語句,然後執行select,最後執行order by排序
*/
#示例:查詢學生表中:所有姓張的學生全部資訊,並按照考試成績進行降序排列
	select *
	from students
	where name like '張%'
	order by score desc;

④ 常見函式

1) 單行函式

  • concat: 將多個欄位/字元進行拼接。

    #語法:concat(欄位/字元1,欄位/字元2,...,欄位/字元n)
    #示例:查詢學生表中:所有學生的姓名和成績,並顯示為一列,格式示範:張三(98分)
    	select concat(name,'(',score,'分)') as 姓名(分數)
    	from students;	
    
  • ifnull:判斷某欄位或表示式是否為null,如果為null 返回指定的值,否則返回原本的值

    #語法:ifnull(欄位/表示式,指定值)
    #示例:查詢學生表中:所有學生的姓名和成績,並將原來成績為null(沒參加考試)的同學成績改為0分
    	select name,ifnull(score,0)
    	from students;
    
  • isnull:判斷某欄位或表示式是否為null,如果是,則返回1,否則返回0

    #語法:ifnull(欄位/表示式)
    #示例:查詢學生表中:所有學生的姓名以及是否缺考,如果缺考記為1,否則記為0
    	select name,ifnull(score)
    	from students;
    
  • substr:擷取子串

    #語法:substr(欄位/字元,初始索引,擷取字元長度)
    #注意:字串索引從1開始,而不是從0開始,如果擷取字元長度省略,則擷取到最後。
    #示例:擷取一個字串的前三個字母
    	select substr('zhang',1,3); #查詢結果為zha
    
  • length :獲取位元組個數

    #語法:length(欄位/字元)
    #注意:獲取的是位元組個數,而不是字元個數,在utf8編碼中,1個漢字為3個位元組,1個字母為1個位元組。
    #示例:
    	select length('123張'); #查詢結果為6
    
  • instr:返回子串第一次出現的索引

    #語法:instr(欄位/字元,子串)
    #注意:如果字串不在原字元中,則返回0
    #示例:
    	select instr('123六六456','六六'); #查詢結果為4
    	select instr('123六六456','六六六'); #查詢結果為0
    
  • round:四捨五入

    #語法:round(數字,保留小數位數)
    #注意:保留小數位數可以不寫,那麼預設四捨五入為整數。
    #示例:
    	select round(4.76,1); #查詢結果為4.8
    
  • truncate:截斷

    #語法:truncate(數字,保留小數位數)
    #注意:保留小數位數可以不寫,那麼預設截斷為整數。截斷不是四捨五入,而是均舍掉,4.1、4.9截斷均為4。
    #示例:
    	select truncate(4.76,1); #查詢結果為4.7
    
  • rand:0-1之間隨機數

    #語法:rande()
    #示例:	
    	select rand(); #返回一個範圍在0-1之間的隨機值
    
  • floor:向下取整

    #語法:floor(數字)
    #注意:返回一個不大於括號中值的最大整數。
    #示例:	
    	select floor(4.7); #查詢結果為4
    
  • ceil:向上取整

    #語法:floor(數字)
    #注意:返回一個不小於括號中值的最大整數。
    #示例:	
    	select ceil(4.7); #查詢結果為5
    
  • mod:取餘

    #語法:mod(數1,數2);
    #注意:返回結果為數1除以數2所得的餘數。
    #示例:
    	SELECT MOD(10,3); #查詢結果為1
    
  • now:當前系統日期+時間

    #語法:now();
    #示例:
    	SELECT now(); #查詢結果為:2020-07-08 16:43:35
    
  • curdate:當前系統日期

    #語法:curdate();
    #示例:
    	SELECT curdate(); #查詢結果為:2020-07-08
    
  • curtime:當前系統時間

    #語法:curtime();
    #示例:
    	SELECT curtime(); #查詢結果為:16:45:28
    
  • str_to_date:將字元轉換成日期

    #語法:str_to_date(字元,日期格式);
    #注意:%Y是年,%m是月,%d是日,%H是小時,%i是分,%s是秒
    #示例:
    	select str_to_date('2020-7-8','%Y-%m-%d'); #查詢結果為:2020-07-08
    
  • date_format:將日期轉換成字元

    #語法:date_format(日期,日期格式);
    #注意:%Y是年,%m是月,%d是日,%H是小時,%i是分,%s是秒
    #示例:
    	select date_format('2020-7-8','今天是%Y年%m月%d日')); #查詢結果為:今天是2020年07月08日
    
  • 其他日期函式

    select date(now()); #返回日期,結果為:2020-07-08
    select year(now()); #返回年,結果為:2020
    select month(now()); #返回月
    select day(now()); #返回日
    select minute(now()); #返回分鐘
    select second(now()); #返回秒
    select datediff('2020-08-08','2020-07-08'):#返回兩個日期相差的天數,結果為:31
    

2)分組函式/聚集函式

聚集函式:作用於一組函式,最後返回一個值

分類:

  • sum() 求和
  • min() 最小值
  • max() 最大值
  • avg() 平均值
  • count() 計數
#示例:查詢學生表中,學生成績的總和、最小值、最大值、平均成績以及學生總人數
	select sum(score),min(score),max(score),avg(score),count(*)
	from students;

特點:

  • 以上五個分組函式都忽略null值,除了count(*);
  • sum和avg一般用於處理數值型,max、min、count可以處理任何資料型別;
  • 都可以搭配distinct使用,用於統計去重後的結果。

⑤ 分組查詢

/*	分組查詢:將查詢結果按照1個或多個欄位進行分組,欄位值相同的為一組。
語法:
	select 查詢的欄位,分組函式
	from 表
	【where 分組前的篩選條件】
	group by 分組的欄位
	【having 分組後的篩選條件】
	【order by 排序】
特點:
	① where語句、having語句和order by語句可以沒有;
	② 可以按單個欄位分組,也可以按多個欄位分組,欄位之間用逗號隔開;
	③ 和分組函式一同查詢的欄位最好是分組後的欄位;
	④ 分組篩選
		where	在分組前對原始表進行篩選,位於group by的前面
		havng	在分組後對分組後的結果集進行篩選,位於group by的後面
	⑤ having後可以支援別名;
	⑥ 先執行from,再執行where,然後執行group by,having,接著執行select,最後執行order by。
*/
#示例:查詢學生表中,每個班級的平均分數,並根據此進行降序排列
	select avg(score) as 平均分數,grade as 班級名
	from students
	group by grade
	order by avg(score);

⑥ 連線查詢

連線查詢:所要查詢的內容在多個表中,對多個表進行連線後查詢
笛卡爾乘積:如果連線條件省略或無效則會出現。檢索出的行數目等於第一個表中的行數乘以第二個表的行數。
解決辦法:新增上連線條件

SQL92語法(瞭解):支援內連線(等值連線、非等值連線、自連線)

  • 等值連線

    /*
    語法:
    	select 查詢列表
    	from 表1 別名,表2 別名
    	where 表1.key=表2.key
    	【and 篩選條件】
    	【group by 分組欄位】
    	【having 分組後的篩選】
    	【order by 排序欄位】
    
    特點:
    	① 一般為表起別名;
    	② 多表的順序可以調換;;
    	③ n表連線至少需要n-1個連線條件;
    	④ 等值連線的結果是多表的交集部分。
    */
    
  • 非等值連線

    /*
    語法:
    	select 查詢列表
    	from 表1 別名,表2 別名
    	where 非等值的連線條件
    	【and 篩選條件】
    	【group by 分組欄位】
    	【having 分組後的篩選】
    	【order by 排序欄位】
    */
    
  • 自連線

    /*
    語法:
    	select 查詢列表
    	from 表 別名1,表 別名2
    	where 等值的連線條件
    	【and 篩選條件】
    	【group by 分組欄位】
    	【having 分組後的篩選】
    	【order by 排序欄位】
    */
    

SQL99語法✳(重點):支援內連線(等值連線、非等值連線、內連線)、外連線(左外、右外、全外)和交叉連線。

  • 內連線

    /*
    語法:
    	select 欄位,...
    	from 表1
    	【inner】 join 表2 on  連線條件
    	【inner】 join 表3 on  連線條件
    	...
    	【where 篩選條件】
    	【group by 分組欄位】
    	【having 分組後的篩選條件】
    	【order by 排序的欄位或表示式】
    特點:
    	① 一般為表起別名;
    	② 多表的順序可以調換;
    	③ n表連線至少需要n-1個連線條件;
    	④ 內連線的結果是多表的交集部分✦✦;
    	⑤ inner關鍵字可以省略;
    	⑥ 先執行from,再執行join on,接著where,之後group by having,然後select,最後order by。
    */
    
  • 外連線

    /*
    語法:
    	select 欄位,...
    	from 表1
    	left/right/full 【outer】 join 表2 on  連線條件
    	left/right/full 【outer】 join 表3 on  連線條件
    	...
    	【where 篩選條件】
    	【group by 分組欄位】
    	【having 分組後的篩選條件】
    	【order by 排序的欄位或表示式】
    特點:
    	① 查詢的結果=主表中所有的行,如果從表和它匹配的將顯示匹配行,如果從表沒有匹配的則顯示null;
    	② 多表的順序很重要,left join 左邊的是主表,right join 右邊的就是主表,full join 兩邊都是主表;
    	③ outer關鍵字可以省略。
    */
    
  • 交叉連線(不常用,關鍵字為cross join)

⑦ 子查詢

/*
子查詢:一條查詢語句中又嵌套了另一條完整的select語句,其中被巢狀的select語句,稱為子查詢或內查詢
主查詢:在外面的查詢語句,稱為主查詢或外查詢
特點:
	① 子查詢都放在小括號內;
	② 子查詢可以放在from後面、select後面、where後面、having後面,但一般放在條件的右側;
	③ 子查詢優先於主查詢執行,主查詢使用了子查詢的執行結果;
	④ 子查詢根據查詢結果的行數不同分為以下兩類:
	  - 單行子查詢(結果集只有一行)
    		一般搭配單行操作符使用:> < = <> >= <= 
   			 非法使用子查詢的情況:
   			 a、子查詢的結果為一組值
   			 b、子查詢的結果為空
 	  - 多行子查詢(結果集有多行)
   			 一般搭配多行操作符使用:any、all、in、not in
  			 in: 屬於子查詢結果中的任意一個就行
 			 any和all往往可以用其他查詢代替
*/

⑧ 分頁查詢

/*
應用場景:當要查詢的條目數太多,一頁顯示不全
語法:
	select 欄位|表示式,...
	from 表1
	【連線型別 join 表2  on 連線條件】
	【where 條件】
	【group by 分組欄位】
	【having 條件】
	【order by 排序的欄位】
	limit 【起始的條目索引,】條目數;
特點:
	① 起始條目索引從0開始
	② 其實條目索引可以省略,如省略預設為0
	③ limit子句放在查詢語句的最後;
	④ 先執行from,再執行join on,接著where,再接著group by having,之後select,然後order by,最後limit。
*/
#示例:查詢學生表中,分數位於前五的學生全部資訊(假設前五名沒有並列排名)
	select *
	from students
	order by score desc
	limit 5;

⑨ 聯合查詢

/*
union:合併、聯合,將多次查詢結果合併成一個結果集
語法:
	select 欄位|常量|表示式|函式 【from 表】 【where 條件】 union 【all】
	select 欄位|常量|表示式|函式 【from 表】 【where 條件】 union 【all】
	select 欄位|常量|表示式|函式 【from 表】 【where 條件】 union  【all】
	.....
	select 欄位|常量|表示式|函式 【from 表】 【where 條件】
特點:
	① 多條查詢語句的查詢的列數必須是一致的;
	② 多條查詢語句的查詢的各列型別、順序最好一致,各列資料型別也可以不一致,但必須相容(可以隱含轉換);
	③ union代表去重,union all代表不去重。   
*/
#示例(多個表):假設一班和二班均有一張成績表,現在要把兩張表的資訊合併。
	select name,score
	from grade1
	union
	select name,score
	from grade2;
#示例(一個表):查詢學生表中:成績大於90或者姓趙的同學的全部資訊(要求用union不用or)
	select *
	from students
	where score>90
	union
	select *
	from students
	where name like('趙%')	

2. DML語言的學習

① 插入

/*
在表中插入資料,有兩種方式。
✳方式一(重點):
語法:
	insert into 表名(欄位1,...)
	values(值1,...);
特點:
	① 欄位型別和值型別一致或相容,而且一一對應;
	② 欄位的個數和順序不一定與原始表中的欄位個數和順序一致,但必須保證值和欄位一一對應;
	③ 欄位可以省略,預設為所有欄位,並且順序和表中的儲存順序一致;
	④ 不可以為空的欄位,必須插入值;
	⑤ 假如表中有可以為null的欄位,注意可以通過以下兩種方式插入null值:欄位和值都省略/欄位寫上,值使用null。
	
✳方式二:
語法:
	insert into 表名
	set 欄位1=值1,欄位2=值2,...,欄位n=值n;
	
✳二者區別:
	1).方式一支援一次插入多行,語法如下:
		insert into 表名【(欄位名,..)】 
		values(值,..),(值,...),...;
	2).方式一支援子查詢,語法如下:
		insert into 表名
		查詢語句;
*/
#示例:在學生表中插入一條學生資訊,學號:8,姓名:李四,班級:2,姓別:男,成績:88,電話:123456789
	#方式一
		insert into students(id,name,grade,gender,score,phone)
		values(8,'李四',2,'男',88,'123456789'); 
	#方式2
		insert into students
		set id=8,name='李四',grade=2,gender='男',score=88,phone='123456789'; 

② 修改

/*
語法:
	update 表名 
	set 欄位1=新值1,欄位2=新值2,...
	【where 條件】
特點:如果沒有where篩選條件,則會更改表中所有行。	
*/
#示例:在學生表中修改李四的成績為90分
	update students
	set score=90
	where name='李四';

③ 刪除

/*
刪除表中資料,有兩種方式。
✳方式一(重點):delete語句✔
語法:
	delete from 表名
	【where 篩選條件】;
特點:
	① 如果沒有where篩選條件,則會刪除表中所有行;
	② delect刪除的是表中的一行,而不是整個表,也不是一行中的某一個數據。
	
✳方式二:truncate table語句
語法:
	truncate table 表名
特點:
	① truncate table不能刪除某一行,而是刪除表中所有資料;
	② truncate table語句刪除效率更高,其實質是刪除原來的表,然後重建了新表,而不是逐行刪除表資料。
	
✳二者區別:
	1).truncate table不能加where條件,而delete可以加where條件
	2).truncate table 刪除帶自增長的列的表後,如果再插入資料,資料從1開始,
	   delete 刪除帶自增長列的表後,如果再插入資料,資料從上一次的斷點處開始。
	3).truncate table刪除不能回滾,delete刪除可以回滾
*/
#示例:在學生表中刪除李四的資訊
	#只能用方式一,不能用方式二
		delete from students
		where name='李四';
	
#示例:刪除學生表中全部資訊	
	#方式1
		delete from students;
	#方式2
		truncate table students;
*/

3. DDL語言的學習

① 庫和表的管理

庫的管理:

/*
1)、建立庫
	create database 【if not exists】庫名;
2)、刪除庫
	drop database 【if exists】庫名;
*/

表的管理:
1. 建立表 create table

/*
語法:
	create table 【if not exists】 表名(
		欄位名 欄位型別 【約束】,
		欄位名 欄位型別 【約束】,
		。。。
		欄位名 欄位型別 【約束】 
);
*/
#示例:建立一個學生表,包含學號、姓名、班級、性別、分數和電話號碼
	create table students(
		id int,
		name varchar(10),
		grade int,
		gender char(1),
		score int,
		phone varchar(20)       
	);

2. 修改表 alter table

/*
1).新增列
	alter table 表名 add column 列名 型別 【first|after 欄位名】;
2).修改列的型別或約束
	alter table 表名 modify column 列名 新型別 【新約束】;
3).修改列名
	alter table 表名 change column 舊列名 新列名 型別;
4).刪除列
	alter table 表名 drop column 列名;
5).修改表名(重命名錶)
	alter table 表名 rename 【to】 新表名;	
*/
#示例:在學生表中新增一列用於顯示email(郵箱)	
	alter table students add column email varchar(20);
#示例:將學生表中的電話號碼型別改為int
	alter table students modify column phone int;
#示例:將學生表中的name列名稱改為stu_name
	alter table students change column name stu_name varchar(20);
#示例:將學生表中的email列刪除
	alter table students drop column email;
#示例:將學生表名改為stu_tables
	alter table students rename to stu_tables;

3. 刪除表 drop table

#語法:drop table【if exists】 表名;

4. 複製表

/*
1)、複製表的結構
	create table 表名 like 舊錶;
2)、複製表的結構+資料
	create table 表名 
	select 查詢列表 
	from 舊錶
	【where 篩選】;
*/

② 常見型別

/*
✳整型:tineint、smallint、mediumint、int/integer、bigint
	特點:
		①都可以設定無符號和有符號,預設有符號,通過unsigned設定無符號
		②如果超出了範圍,會報out or range異常,插入臨界值
		③長度可以不指定,預設會有一個長度,長度代表顯示的最大寬度,如果不夠則左邊用0填充,
		 但需要搭配zerofill,並且預設變無符號整型
✳小數:
	浮點型:double(M,D),float(M,D)
	定點型:decimal(M,D)或者簡寫為dec(M,D)
	特點:
		①M代表整數部位+小數部位的個數,D代表小數部位
		②如果超出範圍,則報out or range異常,並且插入臨界值
		③M和D都可以省略,但對於定點數,M預設為10,D預設為0
		④如果精度要求較高,則優先考慮使用定點數
✳字元型:char、varchar、binary、varbinary、enum、set、text、blob
	特點:
		①char:固定長度的字元,寫法為char(M),最大長度不能超過M,其中M可以省略,預設為1
		②varchar:可變長度的字元,寫法為varchar(M),最大長度不能超過M,其中M不可以省略
✳日期型:year年、date日期、time時間、datetime 日期+時間、timestamp 日期+時間
*/

③ 常見約束

/*含義:一種限制,用於限制表中的資料,為了保證表中的資料的準確和可靠性
✳常見約束:
	✔NOT NULL:非空,該欄位的值必填
	✔UNIQUE:唯一,該欄位的值不可重複
	✔DEFAULT:預設,該欄位的值如果不插入會有預設值
	✔CHECK:檢查,mysql不支援
	✔PRIMARY KEY:主鍵,該欄位的值不可重複並且非空  unique+not null
	✔FOREIGN KEY:外來鍵,該欄位的值引用了另外的表的欄位
主鍵與唯一的區別:
	①、一個表至多有一個主鍵,但可以有多個唯一;  
	②、主鍵不允許為空,唯一可以為空。
	
✳建立表時新增約束
	CREATE TABLE 表名(
		欄位名 欄位型別 列級約束,
		欄位名 欄位型別,
		表級約束
	)
	如:
	create table 表名(
		欄位名 欄位型別 not null,	#非空
		欄位名 欄位型別 primary key,	#主鍵
		欄位名 欄位型別 unique,	#唯一
		欄位名 欄位型別 default 值,	#預設
		constraint 約束名 foreign key(欄位名) references 主表(被引用列)
	)
注意:
	①表級約束語法:在各個欄位的最下面【constraint 約束名】 約束型別(欄位名)
         特殊:【constraint 約束名】 foreign key(欄位名) references 主表(被引用列)
         表級約束的constraint 約束名可省略,如可以直接primary key(id)
	②列級約束和表級約束的區別
                              支援型別			    是否可以起約束名			
              列級約束		除了外來鍵			    不可以
              表級約束		除了非空和預設		    可以,但對主鍵無效
	③列級約束可以在一個欄位上追加多個,中間用空格隔開,沒有順序要求

✳修改表時新增或刪除約束
1、非空
	新增非空
		alter table 表名 modify column 欄位名 欄位型別 not null;
	刪除非空
		alter table 表名 modify column 欄位名 欄位型別 ;
2、預設
	新增預設
		alter table 表名 modify column 欄位名 欄位型別 default 值;
	刪除預設
		alter table 表名 modify column 欄位名 欄位型別 ;
3、主鍵
	新增主鍵
		alter table 表名 add【 constraint 約束名】 primary key(欄位名);
	刪除主鍵
		alter table 表名 drop primary key;
4、唯一
	新增唯一
		alter table 表名 add【 constraint 約束名】 unique(欄位名);
	刪除唯一
		alter table 表名 drop index 索引名;
5、外來鍵
	新增外來鍵
		alter table 表名 add【 constraint 約束名】 foreign key(欄位名) references 主表(被引用列);
	刪除外來鍵
		alter table 表名 drop foreign key 約束名;
		
✳自增長列
特點:
	①不用手動插入值,可以自動提供序列值,預設從1開始,步長為1,可以通過下面語句改變步長:
	 set auto_increment_increment=值;
	②一個表至多有一個自增長列
	③自增長列只能支援數值型
	④自增長列必須為一個key
一、建立表時設定自增長列
	create table 表(
		欄位名 欄位型別 約束 auto_increment
	)
二、修改表時設定自增長列
	alter table 表 modify column 欄位名 欄位型別 約束 auto_increment
三、刪除自增長列
	alter table 表 modify column 欄位名 欄位型別 約束 
*/

4. DCL語言的學習

事務:一條或多條sql語句組成一個執行單位,這一組sql語句要麼都執行,要麼都不執行;

事務的特點:(ACID)

原子性(Atomicity):一個事務是一個不可分割的工作單位,其中的操作要麼都做,要麼都不做;如果事務中一個sql語句執行失敗,那麼已執行的語句也會回滾,資料庫退回到事務前的狀態,就像這個事務從來沒有執行過一樣。

一致性(Consistency):事務執行結束後,資料庫的完整性約束沒有被破壞,事務執行的前後都是合法的資料狀態。

隔離性(Isolation):資料庫允許多個併發事務同時對其資料進行讀寫和修改,一個事務的執行不受另外一個事務的干擾。

永續性(Durability ):事務一旦提交後,對資料的修改就是永久的,即便系統故障也不會丟失

事務的使用步驟:

/*
1.隱式事務:沒有明顯的開啟和結束事務的標誌,本身就是一條事務可以自動提交,比如insert、update、delete
2.顯示事務:具有明顯的開啟和結束事務的標誌.
	1)、開啟事務(取消自動提交事務的功能)
		set autocommit=0;
		start transaction; #可以省略
	2)、編寫事務的一組邏輯操作單元(多條sql語句)
		支援insert、update、delete語句
		【savepoint 回滾點名;】 #設定回滾點,可以沒有
	3)、提交事務或回滾事務
		commit; #提交
		rollback; #回滾
		rollback to 回滾點名;
*/

事務的併發問題:

髒讀:事務A訪問資料時,讀取到了事務B修改了但尚未提交的資料。(事務B沒有提交,可能提交成功,但也有可能回滾)
不可重複讀:事務A在訪問資料時,由於事務B對資料進行了修改,使得事務A多次讀取到的資料不一致。(違反了事務的一致性)
幻讀:事務A讀取資料時,事務B進行了插入或刪除,導致第一個事務讀取到了不同數目的資料。

如何避免事務的併發問題?(設定隔離級別)

隔離級別 髒讀 不可重複讀 幻讀
read uncommitted(讀未提交) 可能發生 可能發生 可能發生
read committed(讀已提交) 不可能發生 可能發生 可能發生
repeatable read(可重複讀) 不可能發生 不可能發生 可能發生
serializable(序列化) 不可能發生 不可能發生 不可能發生

設定隔離級別:

set session|global  transaction isolation level 隔離級別名;

檢視隔離級別:

select @@tx_isolation; #mysql預設的隔離級別是repeatable read(可重複讀)