MySQL查詢優化與事務實戰指南

本節用到的員工信息管理表結構放到資源中,需要的同學自取。本節內容以此表為示例:

?

?

?

面試題:innodb與myisam的區別。

外鍵,事務

特性InnoDBMyISAM
事務支持支持不支持
外鍵支持不支持
鎖粒度行級鎖表級鎖
索引結構聚簇索引非聚簇索引
崩潰恢復支持不支持
空間效率較高(但占用更多空間)較低(但更緊湊)
寫性能高(行級鎖)低(表級鎖)
適用場景事務、高并發寫靜態數據、讀密集型

一、簡單查詢

語法:

select [?去重關鍵字distinct] 字段?from 表格名稱;

字段:*代表所有字段

select 字段? as "字段別名"... from 表格名稱;

as可以省略不寫,后面空格直接跟別名。

?查詢所有員工的編號,姓名,薪資

select empno"員工編號",ename"員工姓名",sal"員工薪資" from emp;

二、限定查詢

語法:

select [?去重關鍵字distinct] 字段?from 表格名稱 [限定語法]

where >, < ,>= ,<= ,!=, between...and...,

查詢公司中工資高于2000的員工

select * from emp where sal > 2000;

查詢公司中工資1000到3000的員工

select * from emp where sal between 1000 and 3000;
select * from emp where sal > 1000 and sal < 3000;

查詢有獎金的員工信息

select * from emp where comm > 0

查詢沒有獎金的員工信息

select * from emp where comm IS null or comm = 0

查詢名稱中以S開頭 模糊匹配 %通配所有 _通配一位

select * from emp where ename like "s%" 以s開頭select * from emp where ename like "%s" 以s結尾select * from emp where ename like "%s%" 名稱中包含sselect * from emp where ename like "_o%" 第二位為o,其余無所謂

查詢1981年入職的員工信息

select * from emp where HIREDATE BETWEEN '1981-01-01' and '1981-12-31'select * from emp where HIREDATE like '%1981%'

查詢員工編號為7499,7521的員工信息

select * from emp where EMPNO = 7499 or EMPNO = 7521select * from emp where EMPNO in (7499,7521)

三、排序查詢

語法:

select [?去重關鍵字distinct] 字段?from 表格名稱 [限定語法][排序條件]

排序關鍵字:order by

升序:asc

降序:desc

查詢員工信息,根據薪資做倒序排序

select * from emp order by asl desc;

查詢員工信息,根據入職日期做降序排序,?日期一致則按薪資升序排序。

select * from emp order by hiredate desc ,sal asc;

四、多表查詢

語法:select [去重關鍵字DISTINCT] 字段 from 表格名稱 , 表格名稱 [限定語法][排序條件];

查詢所有員工信息,包含部門信息

select * from emp,dept

以上查詢方式將兩張表進行簡單堆積,查詢中有無用的冗余數據,這種現象稱之為笛卡爾積效應

在查詢過程中,添加關聯條件,用來在顯示上消除笛卡爾積效應

select * from emp,dept where emp.deptno = dept.deptnoselect e.*,d.DNAME,d.loc from emp e,dept d where e.deptno = d.deptno

查詢所有員工信息,包含員工編號、員工姓名、員工薪資、領導編號、領導姓名、領導薪資

確定需要的表格:emp e1,emp e2

確定需要的字段:e1.empno '員工編號',e1.ename '員工姓名',e1.sal '員工薪資',e2.empno '領導編號',e2.ename '領導姓名',e2.sal '領導薪資'

確定需要的關聯條件:e1.mgr = e2.empno

組裝sql:
?

SELECT
e1.empno '員工編號',
e1.ename '員工姓名',
e1.sal '員工薪資',
e2.empno '領導編號',
e2.ename '領導姓名',
e2.sal '領導薪資'
FROM
emp e1, emp e2
WHERE
e1.mgr = e2.empno;

以上sql查詢完之后,顯示13條結果,KING這條數據沒有顯示(邊界值無法查詢),如果向解決邊界值問題,需要使用連接查詢

五、連接查詢

語法:

select [去重關鍵字DISTINCT] 字段 from 表格名稱 [連接條件] 表格名稱 [限定語法][排序條件];
左(外)連接:left(outer) join ...on...
右(外)連接:right(outer) join ...on...
以哪個表為重點就哪邊連接;

?查詢所有員工信息,包含員工編號、員工姓名、員工薪資、領導編號、領導姓名、領導薪資

SELECT e1.empno AS '員工編號',e1.ename AS '員工姓名',e1.sal AS '員工薪資',e2.empno AS '領導編號',e2.ename AS '領導姓名',e2.sal AS '領導薪資'
FROM emp e1
LEFT JOIN emp e2 ON e1.mgr = e2.empno;

?

拓展語法:SQL1999語法

交叉連接:select * from emp join dept; 類似于“,”進行笛卡爾積, 查詢顯示56條結果

自然連接:select * from emp natural join dept; 自動組合共同字段,查詢顯示14條結果

join...on+條件:select * from emp join dept on emp.deptno = dept.deptno; 查詢顯示14條結果

join...using(兩邊表的共同字段):select * from emp join dept using(deptno); 查詢顯示14條結果

六、分組查詢

分組前提:需要分組的字段有重復值

語法:

select [去重關鍵字DISTINCT] 字段 from 表格名稱 [限定語法][分組條件][排序條件];
分組關鍵字:group by

注意事項:
1.一旦出現分組條件,那么select后邊只允許出現統計函數和分組字段
2.分組之后如果還想使用限定條件篩選,那么不允許使用where,需要使用having

?查詢每一個部門的平均工資

確定需要的表:emp
確定需要的字段:avg(sal)
確定需要的分組條件:group by deptno
組裝sql:select avg(sal) from emp group by deptno

優化sql:select deptno,avg(sal) from emp group by deptno

發現上述sql中沒有40部門(邊界值)
確定需要的表:emp e,dept d
確定需要的字段:d.deptno,avg(sal)
確定需要的分組條件:group by d.deptno
組裝sql:

SELECT d.deptno, IFNULL(AVG(sal), 0) '平均工資' 
FROM emp e 
RIGHT JOIN dept d ON e.deptno = d.deptno 
GROUP BY d.deptno;

查詢部門的平均薪資,要求顯示平均薪資高于2000的信息

SELECT d.deptno, IFNULL(AVG(e.sal), 0) AS '平均工資' 
FROM dept d 
LEFT JOIN emp e ON d.deptno = e.deptno 
GROUP BY d.deptno 
HAVING IFNULL(AVG(e.sal), 0) > 2000;  -- 確保在過濾時處理 NULL 值AVG(sal) > 2000

七、統計查詢

平均avg? ?最大值max? ?最小值min? ?統計數量 count? ?求和 sum

拓展技術:

單行函數參考單行函數文檔。

八、子查詢

where 子查詢

當查詢的結果為單行單列或多行單列的時候

查詢比smith工資高的所有員工信息。

SELECT *
FROM emp
WHERE sal > (SELECT sal FROM emp WHERE ename = 'SMITH');

?查詢公司中和經理一樣工資的員工信息

SELECT *
FROM emp
WHERE sal in (SELECT sal FROM emp WHERE job = 'manager')

?小貼士:

=ang? ? ? ? 等同于? ? ? ?in

<ang? ? ? ? 等同于? ? ? ? 比最大值小的數據

>ang? ? ? ? 等同于? ? ? ? 比最小值大的數據

<all? ? ? ? 等同于? ? ? ? 比最小值小的數據

>all? ? ? ? 等同于? ? ? ? 比最大值大的數據

?from 子查詢

當查詢的結果為多行多列

查詢部門編號、部門名稱、部門位置、部門人數、部門平均薪資

第一步:查詢部門單表信息(4條結果)

select * from dept

第二步:查詢員工表,得到部門人數、部門平均(3條結果)

確定需要的表格:emp e
確定需要的字段:e.deptno deptno,count(e.empno) num,avg(e.sal) sal
確定需要的分組條件:group by e.deptno
組裝sql:
select e.deptno deptno,count(e.empno) num,avg(e.sal) sal from emp e group by e.deptno

第三步:將上述sql進行左右連接查詢

確定需要的表格:
dept d,
(select e.deptno deptno,count(e.empno) num,avg(e.sal) sal from emp e group by e.deptno) temp
確定需要的字段:d.deptno,d.dname,d.loc,temp.num,temp.sal
確定需要的關聯條件:d.deptno = temp.deptno
?
組裝sql:
SELECT d.deptno,d.dname,d.loc,temp.num,temp.sal
FROM dept d
LEFT JOIN (SELECT e.deptno AS deptno,COUNT(e.empno) AS num,AVG(e.sal) AS salFROM emp eGROUP BY e.deptno) temp 
ON d.deptno = temp.deptno;

九、分頁查詢

為什么需要分頁查詢?

語法:select [去重關鍵字DISTINCT] 字段 from 表格名稱 [限定語法][分組條件][排序條件][分頁條件]
分頁:limit n,m
n:數據索引,從0開始
m:每一頁顯示多少條

查詢第一頁員工數據,一頁顯示10條

select * from emp limit 0,10;

當n為0的時候,可以省略不寫:select * from emp limit 10;

第二頁:

select * from emp limit 10,10;

?事務

? 數據庫事務( transaction)是訪問并可能操作各種數據項的一個數據庫操作序列,這些操作要么全部執行,要么全部不執行,是一個不可分割的工作單位。事務由事務開始與事務結束之間執行的全部數據庫操作組成。

事務的四大特性:

1、原子性(Atomicity):事務中的全部操作在數據庫中是不可分割的,要么全部完成,要么全部不執行。?

2、一致性(Consistency):幾個并行執行的事務,其執行結果必須與按某一順序 串行執行的結果相一致。?

3、隔離性(Isolation):事務的執行不受其他事務的干擾,事務執行的中間結果對其他事務必須是透明的。?

4、持久性(Durability):對于任意已提交事務,系統必須保證該事務對數據庫的改變不被丟失,即使數據庫出現故障。?

臟讀 幻讀

MySQL數據庫事務測試

mysql的事務是默認提交機制

事務提交機制有兩種:自動提交,手動提交

修改數據庫事務提交機制:
關閉自動提交:set autocommit = 0;

開啟自動提交:set autocommit = 1;

如果關閉自動提交,那么在發生增刪改以后需要程序員提交(commit)或回滾(rollback)

? MySQL數據庫事務隔離級別

MySQL 提供了四種事務隔離級別,以確保數據的一致性和完整性。這四種隔離級別分別是:讀未提交(Read Uncommitted)、讀已提交(Read Committed)、可重復讀(Repeatable Read)和可串行化(Serializable)

讀未提交(Read Uncommitted):
????????定義:事務可以讀取其他未提交事務的更改。

????????問題:可能導致臟讀(Dirty Read)

????????適用場景:對數據一致性要求不高的場景。


讀已提交(Read Committed):(oracle默認級別)

????????定義:事務只能讀取其他已提交事務的更改。

????????問題:避免了臟讀,但可能導致不可重復讀(Non-repeatable Read)

????????適用場景:大多數數據庫系統的默認隔離級別,如oracle。


可重復讀(Repeatable Read):(MySQL默認級別)

????????定義:在同一事務中多次讀取相同數據時,結果一致。

????????問題:避免了臟讀和不可重復讀,但可能導致幻讀(Phantompead)。

????????適用場景:MySQL 的默認隔離級別,適用于大部分應用。


可串行化(serializable):
????????定義:最高的隔離級別,事務按順序逐個執行,完全隔離。
????????問題:避免了臟讀、不可重復讀和幻讀,但并發性能最差。
????????適用場景:對數據一致性要求極高的場景。

臟讀(Dirty Read)?。

? ?定義?:讀取到其他事務未提交的修改數據,若該事務回滾則導致數據無效
? ?示例?:事務A修改賬戶余額后未提交,事務B讀取到該臨時值;若事務A回滾,事務B基于臟數據操作將引發錯誤

不可重復讀(Non-repeatable Read)?

? ?定義?:同一事務內多次讀取同一數據,因其他事務已提交的修改導致結果不一致
? ?示例?:事務A第一次查詢余額為1000元,事務B修改為800元并提交后,事務A再次查詢結果變為800元

幻讀(Phantom Read)?

? ?定義?:同一事務內兩次范圍查詢的結果行數不同,因其他事務插入或刪除數據
? ?示例?:事務A首次查詢年齡>30的用戶共10人,事務B新增1人后,事務A再次查詢結果為11人

隔離級別測試:

數據庫默認隔離級別查看:?

  • 查看全局默認隔離級別(5.7版本之前):SELECT @@global.tx_isolation;
  • 查看全局默認隔離級別(5.7版本之后):SELECT @@global.transaction_isolation;
  • 查看當前會話隔離級別(5.7版本之前):SELECT @@session.tx_isolation;
  • 查看當前會話隔離級別(5.7版本之后):SELECT @@session.transaction_isolation;

第一步:修改數據庫隔離級別

SET [GLOBAL|SESSION} TRANSACTION ISOLATION LEVEL 
[READ UNCOMMITTED|READ COMMITTED|REPEATABLE READ|SERIALIZABLE]

第二步:設置手動提交

set autocommit = 0;

第三步:開啟事務

start transaction;

第四步:測試業務

update t_person set sal = sal-500 where id = 1;update t_person set sal = sal+500 where id = 3;

?索引、優化、b+tree后續再了解。

python連接數據庫

安裝模塊pymysql

第一步:導入模塊

import pymysql

?第二步:創建連接

conn = pymysql.connect
(host='locohost', user='user', password='password', port=3306,database='database')

第三步:創建數據庫對象

cursor = conn.cursor()

?第四步:執行sql語句

sql = "select * from emp"#通過數據庫對象執行sql
cont = cursor.execute(sql)
#執行sql語句,返回查詢結果的行數。
result = cursor.fetchall()
#執行 execute() 后查詢的所有結果

第五步:關閉連接

cursor.close()
conn.close()

傳參問題

  • 方式一:直接字符串拼接
    把變量(如?usernamepasswordid?)拼接到 SQL 語句里,有嚴重 SQL 注入風險?,比如用戶輸入惡意內容可篡改查詢邏輯。
    示例:
    sql = 
    "select * from t_user where username = '"
    +username+
    "' and password = '"
    +password+
    "'"
    
  • 方式二:簡單格式化拼接(仍有風險)
    用?%?做占位符拼接參數,看似規范但本質還是字符串拼接,仍可能被 SQL 注入?(如輸入?lufei' or 1=1 --?可繞過校驗 )
    sql = "select * from t_user where username = '%s' and password = '%s'"%(username,password)
    
  • 方式三:參數化查詢(推薦)
    用?%s?做占位符,但實際執行時由數據庫驅動自動處理參數轉義,可有效避免 SQL 注入?,是安全的傳參方式
    sql = "select * from t_user where username = %(name)s and password = %(pwd)s" 
    cursor.execute(sql, {"name": username, "pwd": password})
    

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

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

相關文章

Windows 10/11 磁盤清理操作指南:徹底解決系統盤空間不足問題

&#x1f9d1; 博主簡介&#xff1a;CSDN博客專家、CSDN平臺優質創作者&#xff0c;高級開發工程師&#xff0c;數學專業&#xff0c;10年以上C/C, C#,Java等多種編程語言開發經驗&#xff0c;擁有高級工程師證書&#xff1b;擅長C/C、C#等開發語言&#xff0c;熟悉Java常用開發…

b-up:Enzo_Mi:深度學習基礎知識

1.最近鄰差值&#xff08;Neareast Neighbor Interpolation&#xff09; 插值算法 &#xff5c; 最近鄰插值法_嗶哩嗶哩_bilibili 上圖中最后一行&#xff0c;第一個圖像&#xff0c;因為目標像素&#xff08;放大后&#xff0c;位于第1行第0列的像素&#xff09;距離它最近的…

微信小程序商品結算功能

整體結算流程概述微信小程序的商品結算涉及前端交互、API調用和數據管理。典型流程包括&#xff1a;用戶交互&#xff1a;用戶選擇商品、填寫地址和時間。數據獲取&#xff1a;從小程序緩存或后端服務器獲取訂單信息。邏輯處理&#xff1a;驗證參數、應用紅包折扣。提交訂單&am…

2025年7月份最新一區算法——向光生長算法

注&#xff1a;該算法已按照智能優化算法APP標準格式進行整改&#xff0c;可直接集成到APP中&#xff0c;方便大家與自己的算法進行對比。&#xff08;近期智能優化算法APP將會迎來超級大更新&#xff01;請時刻保持關注哦&#xff01;&#xff09;向光生長算法&#xff08;Pho…

腳手架新建Vue2/Vue3項目時,項目文件內容的區別

一. package.json vue版本號不同vue2中會多一個依賴&#xff1a;vue-template-compiler&#xff0c;作用是預編譯Vue2模板為渲染函數&#xff0c;減少運行時開銷。vue-template-compiler與vue版本要保持一致&#xff0c;否則會報錯。eslintConfig中的extends不同 eslintConfig…

微信小程序入門實例_____從零開始 開發一個每天記賬的微信小程序

在前面的微信小程序實例中我們開發了體重記錄等實用小程序&#xff0c;今天來嘗試一個和生活消費緊密相關的 ——“每日記賬小程序”。它能幫你隨時記錄收支情況&#xff0c;讓每一筆花費都清晰可查。下面就跟著步驟&#xff0c;一步步構建這個小程序。?體驗一個開發者的快樂。…

2026python實戰——如何利用海外代理ip爬取海外數據

家人們&#xff01;隨著跨境電商的發展&#xff0c;是不是越來越多的小伙伴們也開始搞海外的數據分析了&#xff1f;不過雖然我們已經整天爬蟲、數據采集打交道了&#xff0c;但一到海外數據&#xff0c;還是有不少人掉進坑里。你們是不是也遇到過以下情況&#xff1a;花了一堆…

Spring Boot啟動原理:從main方法到內嵌Tomcat的全過程

Spring Boot的啟動過程是一個精心設計的自動化流程&#xff0c;下面我將詳細闡述從main方法開始到內嵌Tomcat啟動的全過程。 1. 入口&#xff1a;main方法 一切始于一個簡單的main方法&#xff1a; SpringBootApplication public class MyApplication {public static void m…

小白學Python,網絡爬蟲篇(1)——requests庫

目錄 一、網絡爬蟲的介紹 1.網絡爬蟲庫 2.robots.txt 規則 二、requests 庫和網頁源代碼 1.requests 庫的安裝 2.網頁源代碼 三、獲取網頁資源 1.get () 函數 &#xff08;1&#xff09;get() 搜索信息 &#xff08;2&#xff09;get() 添加信息 2.返回 Response 對象…

平板可以用來辦公嗎?從文檔處理到創意創作的全面測評

在快節奏的現代職場&#xff0c;一個核心疑問始終縈繞在追求效率的職場人心中&#xff1a;平板電腦&#xff0c;這個輕薄便攜的設備&#xff0c;真的能替代筆記本電腦&#xff0c;成為值得信賴的辦公伙伴嗎&#xff1f; 答案并非簡單的“是”或“否”&#xff0c;而是一個充滿潛…

docker gitlab 備份 恢復 版本升級(16.1.1到18.2.0)

docker 啟動 # 在線 docker pull gitlab/gitlab-ce:latest # 離線 docker save -o gitlab-ce-latest.tar gitlab/gitlab-ce:latest docker load -i gitlab-ce-latest.tardocker run --detach \--publish 8021:80 --publish 8023:22 \ --name gitlab_test \--restart always \-…

web3 區塊鏈技術與用

#53 敲點算法題 瑞吉外賣day4 調整心態 睡眠 及精神 web3 以下是應北京大學肖臻老師《區塊鏈技術與用》公開課的完整教學大綱&#xff0c;綜合課程內容、技術模塊及前沿擴展&#xff0c;分為核心章節與專題拓展兩部分&#xff0c;引用自公開課資料及學員筆記。 &#x1f4…

Redis1:高并發與微服務中的鍵值存儲利器

redis中存儲的數據格式為鍵值對&#xff08;Key,Value&#xff09;在高并發的項目和微服務的項目會頻繁的用到redisNoSQL型數據庫1.初始Redis1.1認識NoSQLSQL&#xff1a;structure query language關系型數據庫結構化&#xff1a;有固定格式要求&#xff08;表關系&#xff0c;…

/字符串/

字符串 個人模板 5. 最長回文子串 93. 復原 IP 地址 43. 字符串相乘 227. 基本計算器 II

我的開發日志:隨機數小程序

文章目錄前言UI設計代碼前言 為什么我要設計這個程序呢&#xff1f;因為我要用&#xff0c;懶得在網上下載了&#xff0c;于是干脆寫了一個。 UI設計 UI是我凹出來的&#xff0c;你們要使用&#xff0c;直接新建一個UI.ui文件&#xff0c;然后把下面的東西輸進去就可以了。 …

《Oracle SQL:使用 RTRIM 和 TO_CHAR 函數格式化數字并移除多余小數點》

select RTRIM(to_char(1222.11123344,fm9999990.9999),.) from dual 這條 SQL 語句主要用于對數字進行格式化處理&#xff0c;并移除格式化結果右側多余的小數點。下面將詳細拆解該語句的執行過程和各部分作用。語句詳細拆解1. to_char(1222.11123344,fm9999990.9999)函數功能&…

「Java案例」方法重裝求不同類型數的立方

利用方法重裝實現不同類型數值的立方計算 立方計算方法的重載實現 編寫一個程序,要求編寫重載方法xxx cube(xxx value)實現對不同類型數值計算立方。 # 源文件保存為“CubeCalculator.java” public class CubeCalculator {public static void main(String[] args) {// 測試…

API 接口開發與接入實踐:自動化采集淘寶商品數據

在電商數據分析、價格監控等場景中&#xff0c;自動化采集淘寶商品數據具有重要價值。本文將詳細介紹如何通過 API 接口開發實現淘寶商品數據的自動化采集&#xff0c;包含完整的技術方案和代碼實現。 一、淘寶 API 接入基礎 1. 接入流程概述 注冊淘寶賬號獲取 ApiKey 和 Ap…

python-pptx 的layout 布局

一、布局基礎概念 在 PowerPoint 中&#xff0c;布局&#xff08;Layout&#xff09; 決定了幻燈片的占位符&#xff08;如標題、內容、圖片等&#xff09;的排列方式。python-pptx 提供了對布局的編程控制。二、默認布局類型及索引 通過 prs.slide_layouts[index] 訪問&#x…

服務器mysql數據的簡單備份腳本

服務器mysql數據的簡單備份腳本 一個小型項目mysql數據庫數據的定時備份 通過crontab定時執行腳本: 0 1 * * * /home/yuyu/mysqlbak.sh備份文件加入時間戳,防止覆蓋支持刪除超過x天的備份數據文件&#xff0c;防止備份數據文件太多 #!/bin/bash# 配置變量 DB_HOST"127.0.…