Java面試題031:一文深入了解MySQL(3)

Java面試題029:一文深入了解MySQL(1)

Java面試題030:一文深入了解MySQL(2)

1、MySQL多表查詢

(1)內連接?inner join

????????返回兩個表中完全匹配的行,即只保留兩個表連接字段值相等的行。

(2)外連接

????????左外連接

????????LEFT JOIN 或 LEFT OUTER JOIN 左外連接返回左表中的所有行,以及右表中滿足連接條件的行(如果左表中的某行在右表中沒有匹配的行,那么結果集中該行的右表列將包含 NULL 值)。

????????右外連接

????????右外連接(RIGHT JOIN 或 RIGHT OUTER JOIN):右外連接返回右表中的所有行,以及左表中滿足連接條件的行(如果右表中的某行在左表中沒有匹配的行,那么結果集中該行的左表列將包含 NULL 值)。

(3)UNION UNION ALL

-- UNION 語法
SELECT column1, column2 FROM table1
UNION
SELECT column1, column2 FROM table2;
-- 這里使用了 column1, column2將字段一一列出來,如果 table1和table2字段的順序一致,可以直接寫為 select * ,下方 UNION ALL 同理
select * from table1
UNION
SELECT * FROM table2;-- UNION ALL 語法
SELECT column1, column2 FROM table1
UNION ALL
SELECT column1, column2 FROM table2;
或
select * from table1
UNION ALL
SELECT * FROM table2;

(1)列數一致:所有 SELECT 語句的列數必須相同;
(2)數據類型兼容:對應列的數據類型需兼容(如 VARCHAR 與 TEXT 兼容);
(3)列名規則:最終結果集的列名以第一個 SELECT 的列名為準;

  • 字段相同,順序相同

user1:

user2:

使用UNION查詢 會自動去重,合并后的結果就是7條數據:

UNION ALL 不會自動去重,而是將兩張表的全部數據合并,一共十條數據:

  • 字段相同,順序不同

user1:

user4:

????????此時不能直接使用?select?* ,否則不管是 UNION,還是UNION ALL,最終的表字段順序會以第一張表 user1 的字段順序為準,就會產生一個問題,?user4 表中,passwor 和 username 順序是反著的,會導致查詢結果中,user4 表用戶的密碼 password 被當作 username,用戶的 username 被當作 password;造成數據錯誤。

?

此時就需要將字段一一對應。

?

  • 字段數量不同

user3:與user1對比,user3 少了一個 age 年齡字段

?

????????此時查詢的時候就需要"補列字段" ,可以使用 "NULL AS age"對查詢結果中 user3 的age字段進行填充,使其全部為 NULL(也可以使用具體數據)。

2、笛卡爾積

????????假設有兩個集合A和B。A的元素是{a1, a2, …},B的元素是{b1, b2, …}。那么,A和B的笛卡爾積就是從A中取一個元素,和從B中取一個元素,形成一個有序對,這樣的所有有序對構成的集合就是笛卡爾積。數學上表示為:A × B = {(a1, b1), (a1, b2), …, (a2, b1), (a2, b2), …}。

????????在數據庫中,當你進行表連接操作時,如果沒有指定任何連接條件(如使用WHERE子句),就會產生兩個表的笛卡爾積。這意味著第一個表中的每一行都會與第二個表中的每一行配對,產生巨大數量的數據行。

(1)產生條件

? ? ? ? 兩表關聯查詢語句中沒有指定連接條件。

表Employees中有兩條數據:

表Departments中有兩條數據:?

?不加查詢條件進行查詢,會發現出現4條數據,而且兩個表的字段全部進行了展示

(2)避免笛卡爾積

????????為了避免笛卡爾積,我們應該使用適當的連接條件。

使用顯式的連接類型

  • INNER JOIN: 使用INNER JOIN并指定連接條件,可以確保只連接相關的行。
  • LEFT/RIGHT OUTER JOIN: 這些連接類型允許連接兩個表,并包括左表/右表中的所有行,即使它們在右表/左表中沒有匹配項。
  • FULL OUTER JOIN: 它結合了LEFT和RIGHT JOIN的特點,如果左表或右表中的行沒有匹配項,它也會被包含在結果中。

使用WHERE子句
????????添加過濾條件: 在WHERE子句中明確指定連接條件可以防止產生笛卡爾積,因為它會限制只返回滿足特定條件的行。

使用子查詢
????????子查詢作為連接條件: 在連接的ON子句或WHERE子句中使用子查詢,可以精確控制要返回的行。

使用聚合函數和GROUP BY
????????分組和聚合: 當需要根據某個字段進行分組時,使用GROUP BY子句可以避免笛卡爾積,尤其是在進行統計計算時。

使用DISTINCT關鍵字
????????消除重復行: 如果查詢產生了重復行(這在某些類型的笛卡爾積中可能發生),使用DISTINCT關鍵字可以移除重復的結果集。

使用LIMIT子句
????????限制返回行數: 在進行初步測試和調試時,使用LIMIT子句可以限制查詢結果的行數,從而避免大量的輸出,尤其是在處理可能產生笛卡爾積的復雜查詢時。

3、SQL 查詢語句的執行順序

(8)Select
(9)distinct 字段名1,字段名2,
(6)[fun(字段名)]  
(1)from 表1
(3)<join類型>join 表2 
(2)on <join條件> 
(4)where <where條件> 
(5)group by <字段> 
(7)having <having條件> 
(10)order by <排序字段> 
(11)limit <起始偏移量,行數>

1. FROM:對 FROM 子句中的表1和表2執行笛卡兒積,產生虛擬表VT1

2. ON:對虛擬表 VT1 應用 ON 篩選,只有那些符合join條件的行才被插入虛擬表 VT2

3. JOIN:如果指定了 OUTER JOIN(如 LEFT JOINRIGHT JOIN),那么保留表中未匹配的行

作為外部行添加到虛擬表 VT2 中,產生虛擬表 VT3。如果 FROM 子句包含兩個以上表,則對上一個連接生成的結果表 VT3 和下一個表重復執行步驟 1~步驟 3,直到處理完所有的表為止

4. WHERE:對虛擬表 VT3 應用 WHERE 過濾條件,只有符合條件的記錄才被插入虛擬表 VT4

5. GROUP BY:根據 GROUP BY 子句中的列,對 VT4 中的記錄進行分組操作,產生 VT5

6. 聚合函數:對表 VT5 進行 CUBE ROLLUP 操作,產生表 VT6

7. HAVING:對虛擬表 VT6 應用 HAVING 過濾?,只有符合條件的記錄才被插入虛擬表 VT7中。

8. SELECT:第二次執行 SELECT 操作,選擇指定的列,插入到虛擬表 VT8

9. DISTINCT:去除重復數據,產生虛擬表 VT9

10. ORDER BY:將虛擬表 VT9 中的記錄按照排序字段進行排序操作,產生虛擬表 VT10。

11. LIMIT:取出指定行的記錄,產生虛擬表 VT11,并返回給查詢?用戶

舉例:

用戶表user :

訂單表orders :

目標:查詢來自北京,并且訂單數少于2的客戶。

SELECT a.user_id,COUNT(b.order_id) as total_orders
FROM  user as a
LEFT JOIN orders as b
ON a.user_id = b.user_id
WHERE a.city = 'beijing'
GROUP BY a.user_id
HAVING COUNT(b.order_id) < 2
ORDER BY total_orders desc

(1)FROM語句對兩個表執行笛卡爾積,會得到一個虛擬表,VT1(vitual table 1)

(2)執行ON過濾

根據ON中指定的條件,去掉那些不符合條件的數據,得到VT2如下:

select * from user as a inner JOIN orders as b ON a.user_id = b.user_id;

(3)執行left join子句:user表作為保留表,未匹配的記錄添加到VT2中形成VT3

(4)執行where條件過濾:對添加了外部行的數據進行where條件過濾,執行WHERE a.city = 'beijing'??得到VT4如下:

(5)執行group by分組語句:執行GROUP BY a.user_id?得到VT5如下:

(6)執行having:HAVING子句主要和GROUP BY子句配合使用,對分組得到VT5的數據進行條件過濾,執行?HAVING COUNT(b.order_id) < 2,得到VT6如下:

(7)select列表:執行測試語句中的SELECT a.user_id,user_name,COUNT(b.order_id) as total_orders,從VT6中選擇出我們需要的內容,得到VT7如下:

(8)執行distinct去重復數據:如果在查詢中指定了DISTINCT子句,則會創建一張內存臨時表(如果內存放不下,就需要存放在硬盤了)。這張臨時表的表結構和上一步產生的虛擬表是一樣的,不同的是對進行DISTINCT操作的列增加了一個唯一索引,以此來除重復數據。

(9)執行order by字句:對虛擬表VT7中的內容按照指定的列進行排序,然后返回一個新的虛擬表

(10)執行limit字句:

LIMIT子句從上一步得到的虛擬表中選出從指定位置開始的指定行數據,常用來做分頁;

MySQL數據庫的LIMIT支持如下形式的選擇:limit n,m

表示從第n條記錄開始選擇m條記錄。對于小數據,使用LIMIT子句沒有任何問題,當數據量非常大的時候,使用LIMIT n, m是非常低效的。因為LIMIT的機制是每次都是從頭開始掃描,如果需要從第60萬行開始,讀取3條數據,就需要先掃描定位到60萬行,然后再進行讀取,而掃描的過程是一個非常低效的過程。

4、count(1)count(*) count(列名) 的區別

(1)count(1) and count(*)


????????當表的數據量大些時,對表作分析之后,使用count(1)還要比使用count()用時多了!
????????從執行計劃來看,count(1)和count()的效果是一樣的。但是在表做過分析之后,count(1)會比count(*)的用時少些(1w以內數據量),不過差不了多少。

????????如果count(1)是聚索引,id,那肯定是count(1)快,但是差的很小的。
????????因為count(),自動會優化指定到那一個字段。所以沒必要去count(1),用count(),sql會幫你完成優化的,因此:count(1)和count(*)基本沒有差別!

(2)count(1) and count(字段)


????????count(1) 會統計表中的所有的記錄數,包含字段為null 的記錄。
????????count(字段) 會統計該字段在表中出現的次數,忽略字段為null 的情況。即不統計字段為null 的記錄。

(3)執行效率:

  • 列名為主鍵,count(列名)會比count(1)快。

  • 列名不為主鍵,count(1)會比count(列名)快。

  • 如果有主鍵,則 select count(主鍵)的執行效率是最優的。

5、?in exists 的區別

(1)exists

????????exists對外表用loop逐條查詢,每次查詢都會查看exists的條件語句,當exists里的條件語句能夠返回記錄行時(無論記錄行是的多少,只要能返回),條件就為真,返回當前loop到的這條記錄;反之,如果exists里的條件語句不能返回記錄行,則當前loop到的這條記錄被丟棄,exists的條件就像一個bool條件,當能返回結果集則為true,不能返回結果集則為false。

select * from user where exists (select 1);

????????對user表的記錄逐條取出,由于子條件中的select 1永遠能返回記錄行,那么user表的所有記錄都將被加入結果集,所以與select * from user;是一樣的。

select * from user where exists (select * from user where user_id = 0);

????????user表進行loop時,檢查條件語句(select * from user where user_id = 0),由于user_id永遠不為0,所以條件語句永遠返回空集,條件永遠為false,那么user表的所有記錄都將被丟棄。

????????如果A表有n條記錄,那么exists查詢就是將這n條記錄逐條取出,然后判斷n遍exists條件。

(2)in

????????in查詢就是先將子查詢條件的記錄全都查出來,假設結果集為B,共有m條記錄,然后再將子查詢條件的結果集分解成m個,再進行m次查詢。

????????in查詢相當于多個or條件的疊加。

select * from user where user_id in (1, 2, 3);等效于select * from user where user_id = 1 or user_id = 2 or user_id = 3;

(3)性能對比

  • IN查詢在內部表和外部表上都可以使用到索引。

  • Exists查詢僅在內部表上可以使用到索引。

  • 當子查詢結果集很大,而外部表較小的時候,Exists的Block Nested Loop(Block 嵌套循環)的作用開始顯現,并彌補外部表無法用到索引的缺陷,查詢效率會優于IN。

  • 當子查詢結果集較小,而外部表很大的時候,Exists的Block嵌套循環優化效果不明顯,IN 的外表索引優勢占主要作用,此時IN的查詢效率會優于Exists。

  • 表的規模不是看內部表和外部表,而是外部表和子查詢結果集。

歡迎大家關注我的專欄,該專欄會持續更新,從原理角度覆蓋Java知識體系的方方面面。

一文吃透JAVA知識體系(面試題)https://blog.csdn.net/wuxinyan123/category_7521898.html?fromshare=blogcolumn&sharetype=blogcolumn&sharerId=7521898&sharerefer=PC&sharesource=wuxinyan123&sharefrom=from_link

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/86878.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/86878.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/86878.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

springboot小區物業管理系統

目 錄 第一章 緒 論 1.1背景及意義 1 1.2國內外研究概況 2 1.3 研究的內容 2 第二章 關鍵技術的研究 2.1 相關技術 3 2.2 Java技術 3 2.3 MySQL數據庫 4 2.4 Tomcat介紹 4 2.5 Spring Boot框架 5 第三章 系統分析 3.1 系統設計目標 6 3.2 系統可行性分析 6 3.3 系統功能分析…

微信小程序云開發--環境共享

1、創建配置文件 // utils/cloudConfig.js // 云開發環境配置// 當前小程序配置 const currentConfig {env: "cloudbase-6goxxxxxxd6c75e0", // 當前小程序環境 IDappid: "wxdexxxxx5dbcf04", // 當前小程序 AppID };// 共享云開發環境配置 const shared…

SpringBoot+ShardingSphere-分庫分表教程(一)

日常使用數據庫的時候&#xff0c;更多的時間是在關心業務功能的實現&#xff0c;為了盡快完成新版本的發布上線&#xff0c;通常在項目初期不太會去在意數據庫的壓力和性能問題。在服務上線一段時間之后&#xff0c;就會發現當初設計存在著很多的不足&#xff0c;這都是項目研…

INA226 電流計 功率計電路圖轉PCB制作

上次發布了TI的INA226電路圖&#xff0c;今天抽了點時間&#xff0c;把電路圖生成了PCB。 帖出來&#xff0c;不足之處&#xff0c;請兄弟們留言指正。 沒什么問題就可以去嘉立創白嫖了。^_^

Vcpkg 經典模式完整遷移方案

&#x1f680; 從零開始&#xff1a;高效使用 Vcpkg 安裝 Qt WebEngine&#xff08;經典模式 緩存優化 性能釋放&#xff09; &#x1f9e9; 背景簡介 在使用 Vcpkg 安裝 Qt 系列庫時&#xff0c;特別是龐大的 qtwebengine 模塊&#xff0c;編譯量極大&#xff0c;耗時可達…

FPGA產品

FPGA產品 文章目錄 FPGA產品1. Xilinx公司FPGA產品2. Altera公司FPGA產品3. FPGA產品的工業等級簡介4. FPGA產品的速度等級簡介總結 1. Xilinx公司FPGA產品 Xilinx公司是FPGA芯片的發明者&#xff0c;因此是一家骨灰級的老牌FPGA公司&#xff0c;同時也是目前最大的可編程邏輯…

205-06-26 Python深度學習1——安裝Anaconda與PyTorch庫(Win11+WSL2+Ubuntu24.04版)

文章目錄 1 安裝 wsl1.1 開啟 Windows 支持1.2 安裝 wsl1.3 移動 wsl 至其他盤1.4 其他事項 2 安裝 Anaconda3 安裝 Python 環境3.1 創建 Conda 環境3.2 安裝 Pytorch 庫&#xff08;gpu&#xff09; 4 安裝 Pycharm4.1 Toolbox App 安裝4.2 安裝 Pycharm4.3 配置 Pycharm 5 測…

Redis 數據遷移同步:應對大 Key 同步挑戰

在企業級的數據同步和遷移場景中&#xff0c;Redis 憑借高性能和靈活的數據結構&#xff0c;常被用于緩存和高頻讀寫場景。隨著業務數據的積累&#xff0c;Redis 中不可避免會出現包含大量元素的“大 Key”&#xff0c;如包含幾十萬條數據的 List、Set 或 Hash 類型。在進行全量…

視頻關鍵幀提取

&#x1f39e;? 視頻關鍵幀提取與特征分析指南 &#x1f4cc; 抽幀數量建議 視頻時長推薦抽幀數原因短視頻&#xff08;≤15秒&#xff09;3&#xff5e;5 幀覆蓋不同場景即可中長視頻&#xff08;1&#xff5e;3分鐘&#xff09;5&#xff5e;10 幀內容跨度大長視頻&#xf…

協作機器人優化自動化工作流程,提升工作效率

無損檢測(NDT)是一種檢查方法&#xff0c;用于識別材料中的裂紋或缺陷&#xff0c;或者在不損壞材料的情況下確定材料的元素組成。Olympus擁有多種NDT設備&#xff0c;這些設備具有多種多樣的測量功能&#xff0c;允許最終用戶對各種行業中使用的金屬、塑料、陶瓷和復合材料進行…

復用對象Aspose.Words 中 DocumentBuilder 的狀態管理解析

doc manager.LoadDocument(filePath) builder.Document doc 是不是builder就自動清空重建了,不需要清理builder Aspose.Words 中 DocumentBuilder 的狀態管理解析 在您的代碼中&#xff0c;builder.Document doc 這行代碼不會自動清空或重建DocumentBuilder的狀態。Docume…

(LeetCode 面試經典 150 題 ) 134. 加油站 (貪心)

題目&#xff1a;134. 加油站 思路&#xff1a;貪心&#xff0c;時間復雜度0(n)。 當前點i來到下一個點i1,那么油的變化量是gas[i]-cost[i]。 先統計遍歷完所有點后&#xff0c;油的變化量sum。如果sum<0&#xff0c;說明不可能繞行一周&#xff1b;sum>0&#xff0c;說…

Java 線程池總結

一、寫在前面 參考阿里開發規約,創建線程池一般用ThreadPoolExecutor 在高并發程序中&#xff0c;頻繁創建與銷毀線程是一種極其低效且不可控的行為。為了解決這個問題&#xff0c;Java 提供了線程池&#xff08;ThreadPoolExecutor&#xff09;這一強大的并發框架。它不僅提…

【3.3】Pod詳解——容器探針部署第一個pod

文章目錄 容器探針小知識-控制平面Pod實戰聲明式模型&命令模式 部署第一個pod編寫pod清單文件kubectl命令將清單文件post到api-server驗證pod刪除pod 容器探針 上面已經講到容器狀態,那么這些容器的狀態是怎么檢測到的呢?實際上在pod中有三種探針&#xff0c;存活探針(li…

Insar 相位展開真實的數據集的生成與下載(隨機矩陣放大,zernike 仿真包裹相位)

1.真實的數據集下載: Delta-X: UAVSAR L1B Interferometric Products, MRD, Louisiana, 2021 | NASA Earthdata 注意下載的時候需要注冊登錄一下哦 2. 適用于 深度學習訓練的數據集 通過網盤分享的文件:InSAR-DLPU.rar 鏈接: https://pan.baidu.com/s/1CRWAuNYwCHP_iqCeIhf…

C++ 多線程深度解析:掌握并行編程的藝術與實踐

在現代軟件開發中&#xff0c;多線程&#xff08;multithreading&#xff09;已不再是可選項&#xff0c;而是提升應用程序性能、響應速度和資源利用率的核心技術。隨著多核處理器的普及&#xff0c;如何讓代碼有效地利用這些硬件資源&#xff0c;成為每個 C 開發者必須掌握的技…

(線性代數)矩陣的奇異值Singular Value

矩陣的奇異值是矩陣分析中一個非常重要的概念&#xff0c;尤其是在數值線性代數、數據降維&#xff08;如PCA&#xff09;、圖像處理等領域有著廣泛應用。奇異值分解&#xff08;SVD, Singular Value Decomposition&#xff09;是一種強大的工具&#xff0c;可以將任意形狀的矩…

數據結構復習4

第四章 串 一些面試題 12. 介紹一下KMP算法。★★★ KMP算法是一種高效的字符串匹配算法&#xff0c;用于在一個文本串中查找一個模式串的出現位置。KMP算法通過利用模式串自身的信息&#xff0c;在匹配過程中避免不必要的回溯&#xff0c;從而提高匹配效率。 KMP算法的核心思…

【八股消消樂】消息隊列優化—消息有序

&#x1f60a;你好&#xff0c;我是小航&#xff0c;一個正在變禿、變強的文藝傾年。 &#x1f514;本專欄《八股消消樂》旨在記錄個人所背的八股文&#xff0c;包括Java/Go開發、Vue開發、系統架構、大模型開發、具身智能、機器學習、深度學習、力扣算法等相關知識點&#xff…

2D寫實交互數字人如何重塑服務體驗?

在數字化浪潮席卷全球的當下&#xff0c;人機交互模式正經歷著前所未有的變革。從早期的文本命令行界面&#xff0c;到圖形用戶界面&#xff08;GUI&#xff09;的普及&#xff0c;再到如今語音交互、手勢識別等多模態交互技術的興起&#xff0c;我們與機器之間的溝通方式愈發自…