初識mysql

複習總結

day05-----------------MySql

1、mysql存儲引擎

1. MyISAM
2. InnoDB

查看當前存儲引擎:
1. ☆ show variables like '%storage_engine%'---------查看當前存儲引擎
2. show engines

2、對比MyISAM和InnoDB

	 對比項		 MyISAM		  Innodb(默認)
1. ☆   主外鍵			不支持		    支持
2. ☆   事務           不支持        支持
3. ☆   行表鎖	        表鎖          行鎖
4.      緩存           只緩存索引    緩存索引和數據
5.      表空間          小           大
6.     關注點          性能         事務
7.      默認安裝        是           是

表鎖:即使操作一條記錄也鎖住整張表,不適合高併發
行鎖:操作時只鎖一行,適合高併發

3、Mysql性能下降sql慢,執行時間長,等待時間長

1. sql語句寫的爛
2. 索引失效
3. 關聯查詢太多join
4. 服務器調優以及各個參數設置

4、mysql幾種連接

4.1 等值連接

select u.* from user u ,address a where u.id = a.user_id;

4.2 內連接

1. inner join: select a.*,b.* from user a inner join address b on a.id = b.user_id;

2. join: select a.*,b.* from user a join address b on a.id = b.user_id;

4.3 左外連接:left join

   select a.*, b.* from user a left join address b on a.id = b.user_id;

4.4 右外連接:right join

   select a.*, b.* from user a right join address b on a.id = b.user_id;

4.5 左連接:left join + where B.key is null

select a.*, b.* from user a left join address b on a.id = b.user_id where b.user_id is null;

4.6 右連接:right join + where A.key is null

select a.*, b.* from user a right join address b on a.id = b.user_id where a.id is null;

4.7 全連接 == 左外 union 右外

select a.*, b.* from user a left join address b on a.id = b.user_id
union
select a.*, b.* from user a right join address b on a.id = b.user_id;

4.8 兩張表中都沒有出現的數據集 == 左連 union 右連

select a.*, b.* from user a left join address b on a.id = b.user_id where b.user_id is null
union
select a.*, b.* from user a right join address b on a.id = b.user_id where a.id is null;

5、索引

5.1 什麼是索引 以及如何查看索引

數據庫中一個排好序的數據結構,以實現快速查詢、更新數據庫中的數據

查看索引:show index from table_name;

5.2 索引的分類

5.2.1. 普通索引

5.2.2. 唯一索引

5.2.3. 主鍵索引

5.2.4. 組合索引

5.2.5. 全文索引

5.3 索引的優勢與缺點

5.3.1 優勢

1. 提高了數據檢索的效率,降低了數據庫的IO成本
2. 降低了數據排序的成本,降低了CPU的消耗

5.3.2 缺點

1. 降低更新表的速度,因爲更新時不僅要保存數據,還要保存索引文件
2. 佔用空間

5.4 索引失效問題

1. 全值匹配我最愛,最左前綴要遵守;
2. 帶頭大哥不能死,中間兄弟不能斷;
3. 索引列上少計算,範圍之後全失效;
4. like百分寫最右,覆蓋索引不寫星;
5. 不等空值還有or,索引失效要少用。

5.5 什麼時候需要創建索引,什麼時候不需要創建

5.5.1 需要創建

1. 主鍵自動建立
2. 頻繁作爲查詢條件的字段
3. 

5.5.2 不需要創建

1. 頻繁更新的字段
2. where條件裏用不到的字段
3. 表記錄太少
4. 經常增刪改的表
5. 某個數據列包含許多重複的值

5.6 索引的工作原理 以二叉樹爲例

1. 索引鍵值key
2. 指向對應數據記錄物理地址的指針

5.7 索引優化

1. mysql無法利用range類型後面的字段進行查詢
2. 左連接索引加右表,右連接索引加左表
3. 永遠使用小結果集驅動大的結果集
4. 優先優化內層循環
5. 保證join語句中被驅動表上join條件字段已經被索引

6.數據庫範式

6.1 第一範式(1NF):無重複的列

1. 第一範式是關係型模式的基本要求,不滿足第一範式的數據庫就不是關係型數據庫。

2. 第一範式是指數據庫表的每一列都是不可分割的基本數據項,
   實體中的某個屬性不能有多個值或者不能有重複的屬性。

3. 在第一範式中,表的每一行只能包含一個實例的信息。

4. 簡而言之,第一範式就是無重複的列。

6.2 第二範式(2NF):非主屬性要完全依賴於主關鍵字

1. 第二範式是在第一範式的基礎上建立起來的,即滿足第二範式必須先滿足第一範式。

2. 第二範式要求數據庫表中每一個實例或行必須被唯一的區分。
   爲實現區分通常需要爲表加上一個列,以儲存各個實例的唯一標識,
   這個唯一屬性列被稱爲主鍵。

3. 第二範式要求實體的屬性完全依賴於主鍵。
   所謂完全依賴與主鍵是指不能存在僅依賴主鍵一部分的屬性,
   如果存在,那麼這個屬性和主關鍵字的這一部分就應該分離出來形成一個新的實體。

4. 簡而言之,第二範式就是非主屬性要完全依賴於主關鍵字。

6.3 第三範式(3NF):屬性不依賴於其它非主屬性—消除冗餘

1. 第三範式必須先滿足第二範式。

2. 第三範式要求一個數據表中非主屬性不存在傳遞函數依賴,
   例如員工表中有了部門編號之後,就不要再將部門名稱、
   部門簡介等與部門相關的屬性再添加到員工表裏了,
   可以單獨建一張部門表,因爲這些屬性之間存在傳遞函數依賴。

7、drop,delete與truncate的區別

1. drop:DDL,操作即生效,不能回滾,刪除整個表(結構和數據)。

2. delete:DML,只刪除數據,但是其佔用的存儲空間還在,還可以支持回滾。

3. truncate:DDL,操作即生效,不能回滾,只刪除數據,會釋放數據佔用的存儲空間。

8、談一談鎖機制

8.1 什麼是鎖機制

1. 鎖是計算協調多個進程或線程併發訪問某一資源的機制

2. 在數據庫中,除傳統的計算資源的競爭以外,數據也是一種供許多用戶共享的資源。

3. 如何保證數據併發訪問的一致、有效性是所有數據庫必須解決的一個問題,
   鎖衝突也是影響數據庫併發訪問性能的一個重要因素。

8.2 鎖的分類

8.2.1 從對數據操作的類型(讀/寫)分

1. 讀鎖(共享鎖):針對同一種數據,多個讀操作可以同時進行而不會互相影響。

2. 寫鎖(排它鎖):當前寫操作沒完成前,會阻斷其他讀鎖和寫鎖。

8.2.2 從對數據操作的粒度分

1. 表鎖:偏向MyIsam存儲引擎,開銷小,加鎖快,
        無死鎖,鎖定粒度大,發生鎖衝突的概率最高,併發粒度低。

2. 行鎖:偏向InnoDb存儲引擎,開銷大,加鎖慢,
        有死鎖;鎖定粒度小,發生鎖衝突的概率最低,併發粒度高。

8.3 讀鎖

1. 終端1給A表加了讀鎖,終端1和終端2都可以對A表進行查操作。

2. 終端1不可以對其他沒有鎖定的表進行增刪改查操作,
   終端2可以對其他沒有鎖定的表進行增刪改查操作。

3. 終端1對A表進行增刪改操作都會報錯,
   終端2對A表進行增刪改操作需要等待終端1釋放讀鎖。


1. 終端1給A表加了寫鎖,終端1可以對A表進行增刪改查操作,
   終端2對A表進行增刪改查操作需要等待終端1釋放寫鎖。

2. 終端1不可以對其他沒有鎖定的表進行增刪改查操作,
   終端2可以對其他沒有鎖定的表進行增刪改查操作。

8.4 寫鎖


8.5 如何分析表鎖定

1. Table_locks_immediate:產生表級鎖定的次數,
                         表示可以立即獲取鎖的查詢次數,每立即獲取值加1

2. Table_locks_waited   :出現表級鎖定爭用而發生等待的次數
						(不能立即獲取鎖的次數,每等待一次鎖值加1),
						 此值高則說明存在較嚴重的表級鎖爭用的情況。

9、事務




10、談一談SQL優化

10.1 explain

1. 查看執行計劃
2. explain + SQL

10.2 談一談explain的幾個屬性

10.2.1 id----表的讀取順序

表示查詢中執行select子句或者操作表的順序 
1. id相同:執行順序由上往下
2. id不同:id值越大,優先級越高,越先被執行

10.2.2 select_type----數據讀取操作的操作類型

1. simple:簡單的select語句,不包含子查詢或者union
2. primary:查詢中若包含任何的子部分,最外層被標記爲primary
3. subquery:包含了子查詢
4. derived:在from列表中包含了子查詢被標記爲derived(衍生)
5. union
6. union result

10.2.3 type----查詢使用了何種類型---------------非常重要####

從最好到最差依次是:

system>const>eq_ref>ref>range>index>all

1. system:表只有一行記錄(等於系統表),平時基本不會出現

2. const:表示通過索引一次就找到了,只匹配了一行數據。

3. eq_ref:唯一性索引掃描,對於每個索引鍵,表中只有一條記錄與之匹配。

4. req:非唯一性索引掃描,返回匹配某一個單獨值的所有行,本質上也是一種索引訪問

5. range:只檢索給定範圍的行,使用一個索引來選擇行

6. index:只遍歷索引樹,全索引掃描

7. all:全表掃描

10.2.4 possible_keys----可能使用的索引

10.2.5 key----實際使用的索引-------------------非常重要

10.2.6 key_len----索引中使用的字節數

10.2.7 ref----索引中哪一列被使用

一般是一個常數--const

10.2.8 rows

大致計算出找到所需記錄需要讀取的行數

10.2.9 extra------不適合在其他列中顯示,但是十分重要的信息

1. using filesort:說明mysql會對數據使用一個外部的索引排序,
   而無法按照表內的索引順序進行排序-----------------出現的話儘快優化

2. using temporary:使用了臨時表  常見於order by 
   和 group by ---------出現的話儘快優化

3. using index:使用了覆蓋索引-------------說明效率不錯
   1. 同時出現了using where:表明索引被用來執行查找動作
   2. 沒有出現using where:表明索引只是用來讀取數據

4. using where

5. using join buffer

6. impossible where:where子句總是false

11、比較exists和in

12、談一談慢查詢

13、存儲過程和函數的區別

1. 函數必須有返回值,存儲過程沒有
2. 函數的參數只能是IN,存儲過程可以是IN、OUT、INOUT
3. 函數可以嵌入SQL語句,存儲過程一般是作爲一個獨立的部分來執行
4. 存儲過程在創建時進行了預編譯,執行速度比函數快

13.1 函數

13.1.1 定義形式

create function 函數名 (形參1 類型1 ,形參2 類型2 ...)

returns 返回值類型

begin

  #這裏寫完整的函數語句

  return XX值

end

注意:必須有return語句,且返回的類型要跟設定的類型一致。

13.1.2 調用形式

1. 跟調用內部函數一樣:select func1();
2. 在編程語句中:set @v1 = func1();

13.1.3 創建一個函數

函數目標:獲取三個數中的最大值

create function getMaxValue(p1 float,p2 float,p3 float)
returns float
begin
	declare result float;
	if(p1 >= p2 and p1 >= p3) then
	begin
		set result = p1;
	end;
	elseif(p2 >= p1 and p2 >= p3) then
	begin
		set result = p2;
	end;
	else
	begin
		set result = p3;
	end;
	end if;
	return result;
end;

13.1.4 刪除函數

drop function 函數名

注意:
1. 在函數內部,可以用各種變量和流程控制的使用
2. 在函數內部,也可以由各種增刪改語句

13.2 存儲過程

其本質還是函數,只是沒有返回值

13.2.1 定義形式

create procedure 存儲過程名 ([in] [out] [inout] 形參1 類型1,

							[in] [out] [inout] 形參2 類型2...)

begin

	# 這裏寫完整的過程中語句
	# 其中可以有各種的流程控制
	# 還可以有增刪改查等等
	# 其中查詢語句(select)會作爲存儲過程調用的結果,返回結果集
end;

13.2.2 創建一個存儲過程

目標:將3個數據寫入到列表test,並返回該表中的第一個字段的前3個大值的行

create procedure getDate(p1 int,p2 int,p3 int)
begin
	insert into test(f1,f2,f3) values (p1,p2,p3);
	select * from test order by f1 desc limit 0,3;
end;

調用存儲過程:
call 存儲過程名(實參1,實參2...)

13.2.3 說明

1. in:用於設定變量,用於來"接收實參數據",即"傳入",默認不寫就是in
2. out:用於設定變量,用於來"存儲存儲過程中的數據",即"傳出",即存儲過程中必須對它賦值
3. inout:是in和out的結合,具有雙向作用。
4. ☆ 注意:對於out和inout的設定,對應的實參就必須是一個變量,因爲該變量是用於接收傳出數據

創建一個存儲過程,使用 in out inout

create procedure pro1 (in p1 int,out p2 int,inout p3 int)
begin
	set p2 = p1 * 2;
	set p3 = p3 + p1 * 3;
	insert into test(f1,f2,f3) values (p1,p2,p3)
end;

調用:
call pro1(1,2,3)  XXXX	該存儲過程第2、3個參數有out,對應的實參必須爲變量,這麼調會報錯!!!

set @v1 = 1
set @v2 = 2
call pro1(1,@v1,@v2)  √√√√

13.3 觸發器

13.3.1 定義形式

create trigger 觸發器名 觸發時機 觸發事件 on 表名
for each row
begin
...
end;

說明:
1. 觸發時機: before、after
2. 觸發事件: insert、update、delete
3. 即觸發器的含義是:在某個表上進行insert/update/delete之前/後,會執行其中寫好的語句,即每個表只有6個可能情形會調用該觸發器。

13.3.2 寫一個觸發器

增加:insert

create trigger t1 before insert on emp1
for each row
begin
insert into emp2(name) values (new.name);
end;

修改:update

create trigger t2 before update on dept1
for each row
begin
update dept2 set name = new.name where name = old.name;
end;

刪除:delete

create trigger t3 before delete on user1
for each row
begin
delete from user2 where name = old.name;
end;

注意:在觸發器內部,有兩個關鍵字
1. new:代表當前正要執行的insert或update的時候,"新行"的數據,他可以獲得這一新行數據的任意一個字段的值,形式爲new.id、new.name。

2. old:代表當前正要執行的update或delete的時候,"舊行"的數據,他可以獲得這一舊行數據的任意一個字段的值,形式爲old.id、old.name。

14、mysql變量

14.1 普通變量 ----------------不帶@符號

1. 定義形式:declare 變量名 類型名 【default 默認值】
2. 賦值:set 變量名 = 值
3. 使用環境:只能在函數、存儲過程、觸發器中使用。

14.2 會話變量 ----------------帶@符號

1. 定義形式:set @變量名 = 值
2. 使用環境:任何地方

14.3 變量賦值有如下形式

1. 針對普通變量:set 變量名 = 值(表達式); 注:此變量必須先用declare聲明
2. 針對會話變量:set @變量名 = 值(表達式); 注:此變量不需要用declare聲明
3. 針對會話變量:select @變量名 := 值(表達式); 注:會給該變量賦值的同時,還會作爲一個"select"語句輸出結果集。
4. 針對會話變量:select  值(表達式) into @變量名; 注:會給該變量賦值的同時,但不會作爲一個"select"語句輸出結果集。

15 mysql編程

15.1 流程控制語句

15.1.1 if 條件語句

if 條件語句 then
	begin
		語句塊
	end;
elseif 條件語句 then
	begin
		語句塊
	end;
else
	begin
		語句塊
	end;
end if;

15.1.2 case 語句

例如:
select name ,
	case sex 
		when 1 then '男' 
		when 0 then '女' 
	end as '性別' 
from user;

例如:
update user set state = 
		case 
			when state = 1 then 0
			when state = 0 then 1
		end;

15.1.3 loop 語句

[標識符:] loop
	begin
		...
	end;
end loop [標識符]

注意:內部必須有一個"退出循環機制" : 
	if ()  then
		begin
			leave 標識符;
		end;

15.1.4 while 循環

[標識符:] while 條件 do
	...
end while [標識符]	

15.1.5 repeat 循環

[標識符:] repeat
	...
until 條件
end repeat [標識符]

15.1.6 leave 語句

leave 標識符
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章