最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

MySQL的事務和視圖使用及說明

 更新時間:2026年01月08日 09:42:46   作者:蘇小瀚  
事務是數(shù)據(jù)庫中一組SQL語句,要么全部執(zhí)行成功,要么全部不執(zhí)行,事務的四個特征為原子性、一致性、持久性和隔離性,隔離性主要解決并發(fā)情況下可能出現(xiàn)的臟讀、不可重復讀和幻讀問題,視圖是一個虛擬表,根據(jù)其他表或視圖的查詢結(jié)果生成,視圖可以創(chuàng)建、修改和刪除

1. 什么是事務

事務就是把多條SQL語句打包成一個整體,里面的sql語句要么全部執(zhí)行成功,要么都不執(zhí)行,這里的都不執(zhí)行,不是說真沒執(zhí)行,而是發(fā)生了回滾操作。

比如說有兩個人A和B,A有 1000, B有1000,

  • 語句一:A給B轉(zhuǎn)賬500,
  • 語句二:B接收轉(zhuǎn)過來的500。

這兩個sql語句需要都執(zhí)行,不能中斷,要成功都成功。

如果執(zhí)行完語句一后,沒有執(zhí)行語句二就會出現(xiàn)回滾現(xiàn)象,執(zhí)行回滾的SQL語句,返回到語句一執(zhí)行前的狀態(tài)。

回滾:

就是事務中的SQL語句執(zhí)行一部分,后面沒執(zhí)行,此時MySQL會執(zhí)行回滾的sql語句將數(shù)據(jù)恢復到該事務執(zhí)行之前的狀態(tài)。

如果執(zhí)行事務執(zhí)行一般斷電了,還會發(fā)生回滾嗎?

當然會,因為MySQL在執(zhí)行事務的時候,會記錄一個日志,來記錄當前事務執(zhí)行到那步了,當恢復電后再進入MySQL,MySQL會根據(jù)日志對之前執(zhí)行的操作進行回滾,回滾完成后刪除該日志,如果事務成功執(zhí)行完也會刪除該日志。

引入事務可以很好的解決原子性問題。

2. 事務的四個特征

2.1 原子性

原子性就是說事務在執(zhí)行SQL語句時候,要么全部執(zhí)行,要么都不執(zhí)行,不存在部分執(zhí)行,部分沒有執(zhí)行的情況,如果存在會觸發(fā)回滾操作。

2.2 一致性

一致性是說事務在執(zhí)行前和執(zhí)行后的數(shù)據(jù)都要符合該業(yè)務的規(guī)則和約束條件。

比如說:銀行轉(zhuǎn)賬業(yè)務中,余額在執(zhí)行完事務后不能是負數(shù)等。

事務在執(zhí)行前是符合一致性的,在執(zhí)行一部分后中斷,發(fā)生回滾回到事務執(zhí)行開始,也是符合一致性的。

有時候,事務回滾到中間某個SQL語句,此時也有可能遵循一致性。

2.3 持久性

持久性是說事務對數(shù)據(jù)做出的修改,應該持久的生效,那么就應該寫入到硬盤中,加上數(shù)據(jù)庫本身存儲數(shù)據(jù)也是存儲在硬盤上的。

硬盤也有壞的風險,我們需要對關(guān)鍵數(shù)據(jù)進行備份。

2.4 隔離性

隔離性主要是談到事務在并發(fā)情況下出現(xiàn)的問題:

2.4.1 臟讀問題

事務1 對某個數(shù)據(jù)進行了修改,但是該事務還沒結(jié)束,如果事務1發(fā)生回滾,事務2 對該數(shù)據(jù)進行訪問,訪問的是修改后的數(shù)據(jù),但實際數(shù)據(jù)是沒有修改的,此時讀到的這個數(shù)據(jù)就是臟數(shù)據(jù)。

如何解決臟讀問題:

  • 我們需要約束事務1執(zhí)行完之后,才允許事務2讀取到修改后的值。
  • 此時如果事務1沒有執(zhí)行完,事務2讀到的數(shù)據(jù)就是修改前的數(shù)據(jù)。

2.4.2 不可重復讀問題

事務1中多次讀取某個值的時候,每次讀取同一個數(shù)據(jù)的值都不一樣,就是不可重復讀。

同一個事務多次讀取一個數(shù)據(jù),得到的結(jié)果相同就是可重復讀。

圖中的事務1就存在不可重復讀問題。

如何解決不可重復讀問題:

我們需要約束,一個事務在進行讀操作的時候,對該數(shù)據(jù)進行加鎖,其他事務不能對該數(shù)據(jù)進行讀和修改的操作。當這個事務對該數(shù)據(jù)執(zhí)行完后,開鎖。

而SQL內(nèi)部處理原理是:事務在執(zhí)行前會創(chuàng)建一個“一致性讀視圖”(快照)(就是事務啟動前的數(shù)據(jù)狀態(tài)),該事務內(nèi)部都會參照這個圖去執(zhí)行語句,不受外部其他事務對數(shù)據(jù)操作的影響。

2.4.3 幻讀問題

同一個事務中,在針對某次查詢時候,前后兩個查詢結(jié)果不同。

在執(zhí)行事務1中第一次查詢時,有3條數(shù)據(jù),再執(zhí)行事務2,在執(zhí)行事務1的第二條查詢,有4條數(shù)據(jù),這就是幻讀問題。

如何解決幻讀問題:

我們就需要服務器進行串行化處理數(shù)據(jù),也就是一個事務一個事務執(zhí)行,可以解決幻讀問題。

2.5 事務的使用

2.5.1創(chuàng)建事務

#開始一個事務
start transaction;
或者
begin;

#結(jié)束一個事務
commit;

#回滾當前事務
bollback;

2.5.2 保存點

保存點是我們在創(chuàng)建事務的時候設置的,可以在回滾的時候,指定保存點進行回滾。使用

bollback to 保存點名字,回滾到保存點。

例如:

create table student(id int primary key, name varchar(20), balance double);
insert into student values(1,'張三',1000), (2,'李四',1500);

#開始事務
begin;

select * from student;

update student set balance = balance + 100 where name = '張三';
update student set balance = balance - 100 where name = '李四';

select * from student;

#設置保存點
savepoint tmp1;

update student set balance = balance + 100 where name = '張三';
update student set balance = balance - 100 where name = '李四';

select * from student;

#回滾到保存點
rollback to tmp1;

select * from student;

#結(jié)束事務
commit;

2.6數(shù)據(jù)庫的隔離級別

MySQL中規(guī)定了四種隔離級別:

  • read uncommitted,讀未提交,此時包含臟讀,不可重復讀,幻讀問題。
  • read committed,讀已提交,此時包含不可重復讀,幻讀問題。
  • repeatable read,可重復讀,這種是數(shù)據(jù)庫默認的級別,此時包含幻讀問題。
  • serializable,串行化,這種就解決了所有的隔離性問題。

2.6.1 修改隔離級別

方法一:

通過SQL語句進行修改:

set [global | session] transaction isolation level  隔離級別 | 訪問模式;

#隔離級別
read uncommintted 
read committed
repeatable read
serializable

#訪問模式
read write #事務對數(shù)據(jù)進行讀寫
read only  #事務對數(shù)據(jù)只進行讀,不能讀寫。
  • global:是對當前的連接以及后續(xù)連接服務器的客戶端都生效。
  • session:只對當前連接服務器的客戶端生效。

這種使用SQL語句修改的方式只是臨時修改,重啟MySQL就失效了。

方法二:

通過配置文件修改:

我們可以找到自己電腦下載的MySQL所在的文件:

右鍵文件找到屬性,里面有一串地址如下:

"C:\Program Files\MySQL\MySQL Server 8.0\bin\mysql.exe" "--defaults-file=C:\ProgramData\MySQL\MySQL Server 8.0\my.ini" "-uroot" "-p" "--default-character-set=utf8mb4"

C:\ProgramData\MySQL\MySQL Server 8.0\my.ini ,這個文件位置就是當前我電腦上的MySQL的配置文件,在里面可以修改隔離等級。

2.6.2 查看隔離級別

我們還可以通過SQL語句查看數(shù)據(jù)庫的隔離級別:

查看全局會話隔離級別:

select @@global.transaction_isolation;

查看當前會話的隔離級別:

select @@global.transaction_isolation;

2.5.3讀未提交(read uncommitted)

這種級別包含臟讀問題,不可重復包含問題和幻讀問題。

臟讀問題:

我們創(chuàng)建第一個連接,SQL語句為,這里包含第一個事務:

create table student(id int primary key, name varchar(20), balance double);
insert into student values(1,'張三',1000), (2,'李四',1500);
select * from student;

#修改當前會話的隔離等級為讀未完成
set session transaction isolation level read uncommitted;

#查詢當前會話的隔離等級
select @@session.transaction_isolation;

#事務1
begin;#1

update student set balance = 2000 where id = 1;#1

commit;

創(chuàng)建第二個連接,SQL語句包含第二個事務:

#修改當前會話的隔離等級為讀未完成
set session transaction isolation level read uncommitted;

#查詢當前會話的隔離等級
select @@session.transaction_isolation;

#事務2
begin; #2

select * from student where id = 1; #2

commit; #2

此時兩個連接的隔離級別是 read uncommitted,此時事務1的SQL語句執(zhí)行前兩行,事務2的SQL語句全部執(zhí)行,事務2查詢的結(jié)果是2000。此時產(chǎn)生臟讀問題。當我們設置隔離等級為read committed就能解決臟讀問題。

我們修改隔離等級為read uncommitted后,再進行上面的步驟,查詢結(jié)果是1000,此時就解決了臟讀問題。

2.5.4讀已提交(read committed)

該隔離等級解決了臟讀問題,包含不可重復讀問題和幻讀問題。

不可重復讀問題:

第一個連接包含事務1:

#事務1
begin; #1

select * from student where id = 1; #3

select * from student where id = 1; #5

commit; #6

第二個連接包含事務2和事務3:

#事務2
begin; #2

update student set balance = 2000 where id = 1; #2

commit; #2


#事務3
begin; #4

update student set balance = 3000 where id = 1; #4

commit; #4

此時兩個連接的隔離級別是read committed,此時按照上面注釋的執(zhí)行順序,事務1中的第一次查詢結(jié)果是2000,第二次查詢結(jié)果是 3000,此時包含不可重復讀問題。

我們可以修改隔離等級為repeatable read ,此時再按照上面順序執(zhí)行,事務1第一次查詢結(jié)果是2000,第二次查詢結(jié)果是2000,解決了不可重復讀問題。

2.5.5可重復讀(repeatable read)

該隔離等級解決了臟讀問題,不可重復讀問題,還包含著幻讀問題。

幻讀問題:

第一個連接包含事務1:

#事務1
begin; #1

select * from student; #1

select * from student; #3

commit; #4

第二個連接包含事務2:

#事務2
begin; #2

insert into student values(3,'王五',2000); #2
select * from student; #2

commit; #2

此時的隔離等級是 repeatable read,事務1第一次查詢沒有王五,在執(zhí)行完事務2后再次查詢也沒有王五。

為什么此時沒有出現(xiàn)幻讀問題呢?

  • 可重復讀問題是在一個事務中多次讀取某個數(shù)據(jù),而該數(shù)據(jù)受到其他事務的修改而導致結(jié)果不一致(這是針對已有的數(shù)據(jù)進行修改)。
  • 幻讀問題是在一個事務中多次相同條件的查詢,而結(jié)果因為其他事務的插入或者刪除操作發(fā)生了修改導致不一致(這是針對新數(shù)據(jù)的插入)。
  • 而MySQL底層解決不可重復讀問題是利用一致性讀視圖(快照)來解決的,而其他事務的插入和刪除操作不會影響快照的內(nèi)容,產(chǎn)生的結(jié)果一致。

下面是產(chǎn)生幻讀問題的語句:

第一個連接包含事務1:

#事務1
begin; #1

select * from student; #1

insert into student values(3,'王五',2000); #3

commit; #4

第二個連接包含事務2:

#事務2
begin; #2

insert into student values(3,'王五',2000); #2
select * from student; #2

commit; #2

此時先執(zhí)行事務1中的查詢,沒有王五,再執(zhí)行事務2后,此時再執(zhí)行事務一的查詢沒有王五,但是在執(zhí)行插入操作時候,會報錯說明王五數(shù)據(jù)已經(jīng)插入其中,因為在插入前,MySQL會查詢該表是否有此元素,此時就產(chǎn)生幻讀錯誤。

下面是事務1報錯信息,這里事務2已經(jīng)執(zhí)行,表中已有元素事務1執(zhí)行就會報錯:

此時我們可以修改隔離級別為serializable,此時在按照上面執(zhí)行的話,就不會存在幻讀問題了。此時事務之間一個一個執(zhí)行。

下面是事務2的報錯,這里事務2等到事務1執(zhí)行完后才執(zhí)行,此時執(zhí)行事務2就會報錯:

2.5.6串行化(serializable)

該隔離級別是解決了臟讀問題,不可重復讀問題和幻讀問題。

隔離級別越高,執(zhí)行效率越低,并發(fā)性越低,數(shù)據(jù)準確性越高。

3. 視圖

3.1 什么是視圖

視圖就是一個虛假的表,不存在于硬盤上,根據(jù)其他表或者視圖的查詢結(jié)果作為數(shù)據(jù)生成的一張“類似于表”的數(shù)據(jù)集。

3.2 創(chuàng)建視圖

create view  視圖名字  as  查詢語句;

這里的查詢語句是指從其他的表或者視圖中查詢的結(jié)果。

我們先創(chuàng)建一個學生表:

create table student(id int primary key, name varchar(20), sno varchar(20), age int, gender varchar(10), class_id int);
insert into student values(1,'張三','1001',20,'男',1), (2,'李四','1002',20,'男',1), (3,'王五','1003',20,'男',2),(4,'周六','1004',20,'男',2);

創(chuàng)建一個視圖:

create view student_class_id as select * from student where class_id = 1;
select * from student_class_id;

該視圖查詢出來結(jié)果包含的就是class_id=1的學生的數(shù)據(jù)。

我們在創(chuàng)建視圖的時候可以給列起指定的名字:

create view student_class_id1 (student_id,student_name) as select id,name from student where class_id = 1;
select * from student_class_id1;

查詢視圖結(jié)果為:

3.3 修改視圖

3.3.1 修改表

修改真實的表的數(shù)據(jù),根據(jù)這個表創(chuàng)建的視圖的數(shù)據(jù)也會被修改。

update student set age = 50 where name = '張三';
select * from student_class_id;

查詢創(chuàng)建的視圖,張三的年齡也被修改成50。

3.3.2 修改視圖

修改視圖的數(shù)據(jù)也會影響到表中的數(shù)據(jù)。

update student_class_id set age = 100 where name = '李四';
select * from student;

查詢表中李四的年齡變成了100。

3.3.3 視圖不可修改

有些情況創(chuàng)建的視圖不能夠修改:

  • 創(chuàng)建視圖的時候使用了聚合函數(shù)的視圖。比如sum,avg等。
  • 創(chuàng)建視圖的時候使用了distinct,對查詢結(jié)果進行了去重,此時修改不知道修改的是表中的那行數(shù)據(jù)。
  • 創(chuàng)建視圖的時候使用了 group by 或者 having,對查詢結(jié)果進行了分組,此時視圖一行數(shù)據(jù)包含表中多條數(shù)據(jù),修改視圖不知道修改表的那條數(shù)據(jù)。
  • 創(chuàng)建視圖的時候使用了union或者union all,合并的查詢來自不同的表時候,不能確定修改視圖的行對應那個表的哪個行。
  • 創(chuàng)建視圖的時候使用了子查詢,簡單的子查詢可以修改視圖,但是復雜的子查詢,子查詢的查詢語句中包含聚合函數(shù)group by之類的不能修改視圖。
  • 創(chuàng)建視圖的時候查詢條件是一個表跟一個不可修改的視圖進行關(guān)聯(lián)查詢。

3.4 刪除視圖

drop view student_class_id1;

總結(jié)

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • MySQL8.0.3 RC版即將發(fā)布 先來看看有哪些變化

    MySQL8.0.3 RC版即將發(fā)布 先來看看有哪些變化

    MySQL8.0.3 RC版即將發(fā)布,這篇文章主要介紹了MySQL8.0.3 RC版的一些新變化,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-09-09
  • 用SQL實現(xiàn)統(tǒng)計報表中的"小計"與"合計"的方法詳解

    用SQL實現(xiàn)統(tǒng)計報表中的"小計"與"合計"的方法詳解

    本篇文章是對使用SQL實現(xiàn)統(tǒng)計報表中的"小計"與"合計"的方法進行了詳細的分析介紹,需要的朋友參考下
    2013-06-06
  • 淺談MySQL8和MySQL5.7在自增計數(shù)上的區(qū)別

    淺談MySQL8和MySQL5.7在自增計數(shù)上的區(qū)別

    MySQL數(shù)據(jù)庫是一款非常流行的開源數(shù)據(jù)庫,其版本升級迅速,在使用過程中也發(fā)現(xiàn)了不同版本之間存在著一些區(qū)別,本文主要介紹了MySQL8和MySQL5.7在自增計數(shù)上的區(qū)別,感興趣的可以了解一下
    2023-10-10
  • mysql密碼過期導致連接不上mysql

    mysql密碼過期導致連接不上mysql

    mysql密碼過期了,今天遇到了連接mysql,總是連接不上去,下面有兩種錯誤現(xiàn)象,有類似問題的朋友可以參考看看,或許對你有所幫助
    2013-05-05
  • MySQL數(shù)據(jù)庫的卸載與安裝(Linux?Centos)

    MySQL數(shù)據(jù)庫的卸載與安裝(Linux?Centos)

    如果大家曾經(jīng)安裝過MySQL,現(xiàn)在想要更新MySQL的版本或者因為某些原因?qū)е滦枰匮bMySQL,請記住重裝之前一定要把之前的MySQL版本卸載干凈,這篇文章主要給大家介紹了關(guān)于MySQL數(shù)據(jù)庫的卸載與安裝的相關(guān)資料,需要的朋友可以參考下
    2024-05-05
  • MySQL常用客戶端工具的用途和詳細說明

    MySQL常用客戶端工具的用途和詳細說明

    MySQL是一個廣泛使用的開源關(guān)系數(shù)據(jù)庫管理系統(tǒng)(RDBMS),它為開發(fā)者和數(shù)據(jù)庫管理員提供了一套完整的客戶端工具和功能,這篇文章主要介紹了MySQL常用客戶端工具的用途和詳細說明的相關(guān)資料,需要的朋友可以參考下
    2025-09-09
  • MySQL中int最大值深入講解

    MySQL中int最大值深入講解

    這篇文章主要給大家介紹了關(guān)于MySQL中int最大值的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面來一起學習學習吧
    2019-02-02
  • log引起的mysql不能啟動的解決方法

    log引起的mysql不能啟動的解決方法

    今天服務器掛了原來服務器的硬盤進行了數(shù)據(jù)轉(zhuǎn)移 弄到mysql的時候發(fā)現(xiàn)里面log日志文件高達900MB
    2008-07-07
  • MySQL高可用集群部署與運維超完整手冊(推薦!)

    MySQL高可用集群部署與運維超完整手冊(推薦!)

    高可用性是數(shù)據(jù)庫系統(tǒng)的核心要求之一,MySQL提供了多種部署架構(gòu)和高可用機制來確保數(shù)據(jù)庫服務的連續(xù)性和數(shù)據(jù)的安全性,這篇文章主要介紹了MySQL高可用集群部署與運維的相關(guān)資料,需要的朋友可以參考下
    2026-01-01
  • MySQL 百萬級數(shù)據(jù)的4種查詢優(yōu)化方式

    MySQL 百萬級數(shù)據(jù)的4種查詢優(yōu)化方式

    本文講解了MySQL 百萬級數(shù)據(jù)的4種查詢優(yōu)化方式,大家可以根據(jù)自身需求,選擇適合自己的優(yōu)化方式
    2021-06-06

最新評論

长武县| 德格县| 桐庐县| 灌阳县| 昂仁县| 塔城市| 安新县| 茶陵县| 卓资县| 延长县| 寿阳县| 和林格尔县| 六盘水市| 恩施市| 新绛县| 娄底市| 雷波县| 黎平县| 蛟河市| 汾阳市| 临漳县| 白银市| 大冶市| 四平市| 沙雅县| 铅山县| 遂川县| 铜鼓县| 延川县| 孟津县| 奎屯市| 元阳县| 衡南县| 新营市| 海口市| 伊吾县| 稻城县| 丰宁| 桐庐县| 神农架林区| 吉安县|