MySQL學習筆記--MySQL邏輯架構,sql寫與載入順序以及七種JOIN模式圖解
阿新 • • 發佈:2019-02-03
一、MySQL的邏輯架構
MySQL的最大特點是其外掛式的儲存引擎架構將查詢處理和其他的系統任務以及資料的儲存,提取相分離。這種架構可以根據業務的需求和實際需求選擇合適的儲存引擎。正因為外掛式引擎的特點它的架構可以在多種不同的場景中應用併發揮良好的效能。
1. 連線層:
為請求做連線處理,授權認證,安全等。
處理流程:- 每個連線的查詢都在一個程序中的執行緒完成。
- 伺服器負責快取執行緒,所以服務層不需要為每個連線新建執行緒。
認證流程:
2. 服務層:
查詢解析,分析,優化,快取,提供內建函式;儲存過程,觸發器,檢視。
- 在解析查詢之前,伺服器會“詢問”是否進行了查詢快取(只能快取SELECT語句和相應結果)。快取過的直接返回結果,未快取的就需要進行解析查詢,優化,重新執行返回結果。
- 解析查詢時會建立一個內部資料結構(樹),然後對其進行各種優化。
- 優化:重寫查詢,決定查詢的讀表順序,選擇需使用的索引。
3. 引擎層:
不光做儲存和提取資料,而且針對特殊資料引擎還要做事務處理。
最常用的兩個儲存引擎比較:
當向MySQL傳送一個請求的時候,MySQL到底做了些什麼呢?下圖展示了MySQL的查詢過程:
二、SQL語句的讀寫順序與執行順序
讀寫順序:
SELECT DISTINCT <select_list> FROM <left_table> <join_type> JOIN <right_table> ON <join_condition> WHERE <where_condition> GROUP BY <group_by_list> HAVING <having_condition> ORDER BY <order_by_condition> LIMIT <limit_number>
執行順序:
(7) SELECT (8) DISTINCT <select_list> (1) FROM <left_table> (3) <join_type> JOIN <right_table> (2) ON <join_condition> (4) WHERE <where_condition> (5) GROUP BY <group_by_list> (6) HAVING <having_condition> (9) ORDER BY <order_by_condition> (10) LIMIT <limit_number>
附一張圖,解釋MySQL中sql語句的解析順序:
tips:
group by 存在時,select中除了聚集函式外,所有的基本列必須是group by裡面存在的;having基本上同group by一起使用的,having類似於where語句,只是having過濾是基於group by 分組後的資料,having一般通過select語句裡面的聚集函式進行過濾。
三、七種JOIN模式
多表查詢,首先的弄清楚表與表之間的關係---外來鍵約束
然後根據查詢要求選擇JOIN模式
建表:
在這裡呢我們先來建立兩張有外來鍵關聯的張表。
CREATE DATABASE db0206;
USE db0206;
CREATE TABLE `db0206`.`tbl_dept`(
`id` INT(11) NOT NULL AUTO_INCREMENT,
`deptName` VARCHAR(30),
`locAdd` VARCHAR(40),
PRIMARY KEY (`id`)
) ENGINE=INNODB CHARSET=utf8;
CREATE TABLE `db0206`.`tbl_emp`(
`id` INT(11) NOT NULL AUTO_INCREMENT,
`name` VARCHAR(20),
`deptId` INT(11),
PRIMARY KEY (`id`),
FOREIGN KEY (`deptId`) REFERENCES `db0206`.`tb_dept`(`id`)
) ENGINE=INNODB CHARSET=utf8;
/*插入資料*/
INSERT INTO tbl_dept(deptName,locAdd) VALUES('RD',11);
INSERT INTO tbl_dept(deptName,locAdd) VALUES('HR',12);
INSERT INTO tbl_dept(deptName,locAdd) VALUES('MK',13);
INSERT INTO tbl_dept(deptName,locAdd) VALUES('MIS',14);
INSERT INTO tbl_dept(deptName,locAdd) VALUES('FD',15);
INSERT INTO tbl_emp(NAME,deptId) VALUES('z3',1);
INSERT INTO tbl_emp(NAME,deptId) VALUES('z4',1);
INSERT INTO tbl_emp(NAME,deptId) VALUES('z5',1);
INSERT INTO tbl_emp(NAME,deptId) VALUES('w5',2);
INSERT INTO tbl_emp(NAME,deptId) VALUES('w6',2);
INSERT INTO tbl_emp(NAME,deptId) VALUES('s7',3);
INSERT INTO tbl_emp(NAME,deptId) VALUES('s8',4);
1. 內連線
sql語句:
select * from tbl_dept a inner join tbl_emp b on a.id=b.deptId;
查詢結果:
2. 左外連線:
sql語句:
select * from tbl_dept a left join tbl_emp b on a.id=b.depId;
查詢結果:
3. 右外連線
sql語句:
select * from tbl_dept a right join tbl_emp b on a.id=b.deptId;
查詢結果:
4. 左連線:
sql語句:
select * from tbl_dept a left join tbl_emp b on a.id=b.deptId where b.deptId=null;
查詢結果:
5. 右連線:
sql語句:
select * from tbl_dept a right join tbl_emp b on a.id=b.deptId where a.id is null;
查詢結果:
6. 全連線:
sql語句:
select * from tbl_depId a left join tbl_emp b on a.id=b.deptId
union
select * from tbl_depId a right join tbl_emp b on a.id=b.depId;
查詢結果:
7. 兩張表的非公共集合
sql語句:
select * from tbl_deptId a left join tbl_emp b on a.id=b.deptId where a.id is null
union
select * from tbl_deptId a right join tbl_emp b on a.id=b.depId where b.id is null
查詢結果:
參考部落格: