十年網(wǎng)站開發(fā)經(jīng)驗 + 多家企業(yè)客戶 + 靠譜的建站團隊
量身定制 + 運營維護+專業(yè)推廣+無憂售后,網(wǎng)站問題一站解決
篇幅所限本文只寫了MySQL25題,像其他的Redis,SSM框架,算法,計網(wǎng)等技術(shù)棧的面試題后面會持續(xù)更新,個人整理的1000余道面試八股文會放在文末給大家白嫖,最近有面試需要刷題的同學(xué)可以直接翻到文末領(lǐng)取。

創(chuàng)新互聯(lián)公司是一家專業(yè)提供桂林企業(yè)網(wǎng)站建設(shè),專注與網(wǎng)站建設(shè)、網(wǎng)站設(shè)計、H5網(wǎng)站設(shè)計、小程序制作等業(yè)務(wù)。10年已為桂林眾多企業(yè)、政府機構(gòu)等服務(wù)。創(chuàng)新互聯(lián)專業(yè)網(wǎng)站建設(shè)公司優(yōu)惠進行中。
如果表使用自增主鍵,那么每次插入新的記錄,記錄就會順序添加到當(dāng)前索引節(jié)點的后續(xù)位置,當(dāng)一頁寫滿,就會自動開辟一個新的頁。如果使用非自增主鍵(如果身份證號或?qū)W號等),由于每次插入主鍵的值近似于隨機,因此每次新紀(jì)錄都要被插到現(xiàn)有索引頁得中間某個位置, 頻繁的移動、分頁操作造成了大量的碎片,得到了不夠緊湊的索引結(jié)構(gòu),后續(xù)不得不通過OPTIMIZE TABLE(optimize table)來重建表并優(yōu)化填充頁面。
Server層按順序執(zhí)行sql的步驟為:
簡單概括:
可以分為服務(wù)層和存儲引擎層兩部分,其中:
服務(wù)層包括連接器、查詢緩存、分析器、優(yōu)化器、執(zhí)行器等 ,涵蓋MySQL的大多數(shù)核心服務(wù)功能,以及所有的內(nèi)置函數(shù)(如日期、時間、數(shù)學(xué)和加密函數(shù)等),所有跨存儲引擎的功能都在這一層實現(xiàn),比如存儲過程、觸發(fā)器、視圖等。
存儲引擎層負(fù)責(zé)數(shù)據(jù)的存儲和提取 。其架構(gòu)模式是插件式的,支持InnoDB、MyISAM、Memory等多個存儲引擎。現(xiàn)在最常用的存儲引擎是InnoDB,它從MySQL 5.5.5版本開始成為了默認(rèn)的存儲引擎。
Drop、Delete、Truncate都表示刪除,但是三者有一些差別:
Delete 用來刪除表的全部或者一部分?jǐn)?shù)據(jù)行,執(zhí)行Delete之后,用戶需要提交(commmit)或者回滾(rollback)來執(zhí)行刪除或者撤銷刪除,會觸發(fā)這個表上所有的delete觸發(fā)器。
Truncate 刪除表中的所有數(shù)據(jù),這個操作不能回滾,也不會觸發(fā)這個表上的觸發(fā)器,TRUNCATE比Delete更快,占用的空間更小。
Drop 命令從數(shù)據(jù)庫中刪除表,所有的數(shù)據(jù)行,索引和權(quán)限也會被刪除,所有的DML觸發(fā)器也不會被觸發(fā),這個命令也不能回滾。
因此,在不再需要一張表的時候,用Drop;在想刪除部分?jǐn)?shù)據(jù)行時候,用Delete;在保留表而刪除所有數(shù)據(jù)的時候用Truncate。
隔離級別臟讀不可重復(fù)讀幻影讀 READ-UNCOMMITTED 未提交讀 READ-COMMITTED 提交讀 REPEATABLE-READ 重復(fù)讀 SERIALIZABLE 可串行化讀
MySQL InnoDB 存儲引擎的默認(rèn)支持的隔離級別是 REPEATABLE-READ (可重讀)
這里需要注意的是 :與 SQL 標(biāo)準(zhǔn)不同的地方在于InnoDB 存儲引擎在 REPEATABLE-READ(可重讀)事務(wù)隔離級別 下使用的是 Next-Key Lock 鎖 算法,因此可以避免幻讀的產(chǎn)生,這與其他數(shù)據(jù)庫系統(tǒng)(如 SQL Server)是不同的。所以 說InnoDB 存儲引擎的默認(rèn)支持的隔離級別是 REPEATABLE-READ(可重讀) 已經(jīng)可以完全保證事務(wù)的隔離性要 求,即達到了 SQL標(biāo)準(zhǔn)的SERIALIZABLE(可串行化)隔離級別。
因為隔離級別越低,事務(wù)請求的鎖越少,所以大部分?jǐn)?shù)據(jù)庫系統(tǒng)的隔離級別都是READ-COMMITTED(讀取提交內(nèi) 容):,但是你要知道的是InnoDB 存儲引擎默認(rèn)使用 REPEATABLE-READ(可重讀)并不會有任何性能損失 。
InnoDB 存儲引擎在分布式事務(wù) 的情況下一般會用到SERIALIZABLE(可串行化)隔離級別。
主要原因:B+樹只要遍歷葉子節(jié)點就可以實現(xiàn)整棵樹的遍歷,而且在數(shù)據(jù)庫中基于范圍的查詢是非常頻繁的,而B樹只能中序遍歷所有節(jié)點,效率太低。
文件與數(shù)據(jù)庫都是需要較大的存儲,也就是說,它們都不可能全部存儲在內(nèi)存中,故需要存儲到磁盤上。而所謂索引,則為了數(shù)據(jù)的快速定位與查找,那么索引的結(jié)構(gòu)組織要盡量減少查找過程中磁盤I/O的存取次數(shù),因此B+樹相比B樹更為合適。數(shù)據(jù)庫系統(tǒng)巧妙利用了局部性原理與磁盤預(yù)讀原理,將一個節(jié)點的大小設(shè)為等于一個頁,這樣每個節(jié)點只需要一次I/O就可以完全載入,而紅黑樹這種結(jié)構(gòu),高度明顯要深的多,并且由于邏輯上很近的節(jié)點(父子)物理上可能很遠,無法利用局部性。
最重要的是,B+樹還有一個最大的好處:方便掃庫。
B樹必須用中序遍歷的方法按序掃庫,而B+樹直接從葉子結(jié)點挨個掃一遍就完了,B+樹支持range-query非常方便,而B樹不支持,這是數(shù)據(jù)庫選用B+樹的最主要原因。
B+樹查找效率更加穩(wěn)定,B樹有可能在中間節(jié)點找到數(shù)據(jù),穩(wěn)定性不夠。
B+tree的磁盤讀寫代價更低:B+tree的內(nèi)部結(jié)點并沒有指向關(guān)鍵字具體信息的指針(紅色部分),因此其內(nèi)部結(jié)點相對B 樹更小。如果把所有同一內(nèi)部結(jié)點的關(guān)鍵字存放在同一塊盤中,那么盤塊所能容納的關(guān)鍵字?jǐn)?shù)量也越多。一次性讀入內(nèi)存中的需要查找的關(guān)鍵字也就越多,相對來說IO讀寫次數(shù)也就降低了;
B+tree的查詢效率更加穩(wěn)定:由于內(nèi)部結(jié)點并不是最終指向文件內(nèi)容的結(jié)點,而只是葉子結(jié)點中關(guān)鍵字的索引,所以,任何關(guān)鍵字的查找必須走一條從根結(jié)點到葉子結(jié)點的路。所有關(guān)鍵字查詢的路徑長度相同,導(dǎo)致每一個數(shù)據(jù)的查詢效率相當(dāng);
視圖是一種虛擬的表,通常是有一個表或者多個表的行或列的子集,具有和物理表相同的功能 游標(biāo)是對查詢出來的結(jié)果集作為一個單元來有效的處理。一般不使用游標(biāo),但是需要逐條處理數(shù)據(jù)的時候,游標(biāo)顯得十分重要。
而在 MySQL 中,恢復(fù)機制是通過回滾日志(undo log)實現(xiàn)的,所有事務(wù)進行的修改都會先記錄到這個回滾日志中,然后在對數(shù)據(jù)庫中的對應(yīng)行進行寫入。當(dāng)事務(wù)已經(jīng)被提交之后,就無法再次回滾了。
回滾日志作用:1)能夠在發(fā)生錯誤或者用戶執(zhí)行 ROLLBACK 時提供回滾相關(guān)的信息 2) 在整個系統(tǒng)發(fā)生崩潰、數(shù)據(jù)庫進程直接被殺死后,當(dāng)用戶再次啟動數(shù)據(jù)庫進程時,還能夠立刻通過查詢回滾日志將之前未完成的事務(wù)進行回滾,這也就需要回滾日志必須先于數(shù)據(jù)持久化到磁盤上,是我們需要先寫日志后寫數(shù)據(jù)庫的主要原因。
InnoDB
MyISAM
總結(jié)
數(shù)據(jù)庫并發(fā)會帶來臟讀、幻讀、丟棄更改、不可重復(fù)讀這四個常見問題,其中:
臟讀 :在第一個修改事務(wù)和讀取事務(wù)進行的時候,讀取事務(wù)讀到的數(shù)據(jù)為100,這是修改之后的數(shù)據(jù),但是之后該事務(wù)滿足一致性等特性而做了回滾操作,那么讀取事務(wù)得到的結(jié)果就是臟數(shù)據(jù)了。
幻讀 :一般是T1在某個范圍內(nèi)進行修改操作(增加或者刪除),而T2讀取該范圍導(dǎo)致讀到的數(shù)據(jù)是修改之間的了,強調(diào)范圍。
丟棄修改 :兩個寫事務(wù)T1 T2同時對A=0進行遞增操作,結(jié)果T2覆蓋T1,導(dǎo)致最終結(jié)果是1 而不是2,事務(wù)被覆蓋
不可重復(fù)讀 :T2 讀取一個數(shù)據(jù),然后T1 對該數(shù)據(jù)做了修改。如果 T2 再次讀取這個數(shù)據(jù),此時讀取的結(jié)果和第一次讀取的結(jié)果不同。
第一個事務(wù)首先讀取var變量為50,接著準(zhǔn)備更新為100的時,并未提交,第二個事務(wù)已經(jīng)讀取var為100,此時第一個事務(wù)做了回滾。最終第二個事務(wù)讀取的var和數(shù)據(jù)庫的var不一樣。
T1 讀取某個范圍的數(shù)據(jù),T2 在這個范圍內(nèi)插入新的數(shù)據(jù),T1 再次讀取這個范圍的數(shù)據(jù),此時讀取的結(jié)果和和第一次讀取的結(jié)果不同。
T1 和 T2 兩個事務(wù)都對一個數(shù)據(jù)進行修改,T1 先修改,T2 隨后修改,T2 的修改覆蓋了 T1 的修改。例如:事務(wù)1讀取某表中的數(shù)據(jù)A=50,事務(wù)2也讀取A=50,事務(wù)1修改A=A+50,事務(wù)2也修改A=A+50,最終結(jié)果A=100,事務(wù)1的修改被丟失。
T2 讀取一個數(shù)據(jù),T1 對該數(shù)據(jù)做了修改。如果 T2 再次讀取這個數(shù)據(jù),此時讀取的結(jié)果和第一次讀取的結(jié)果不同。
悲觀鎖,先獲取鎖,再進行業(yè)務(wù)操作,一般就是利用類似 SELECT … FOR UPDATE 這樣的語句,對數(shù)據(jù)加鎖,避免其他事務(wù)意外修改數(shù)據(jù)。當(dāng)數(shù)據(jù)庫執(zhí)行SELECT … FOR UPDATE時會獲取被select中的數(shù)據(jù)行的行鎖,select for update獲取的行鎖會在當(dāng)前事務(wù)結(jié)束時自動釋放,因此必須在事務(wù)中使用。
樂觀鎖,先進行業(yè)務(wù)操作,只在最后實際更新數(shù)據(jù)時進行檢查數(shù)據(jù)是否被更新過。Java 并發(fā)包中的 AtomicFieldUpdater 類似,也是利用 CAS 機制,并不會對數(shù)據(jù)加鎖,而是通過對比數(shù)據(jù)的時間戳或者版本號,來實現(xiàn)樂觀鎖需要的版本判斷。
分庫與分表的目的在于,減小數(shù)據(jù)庫的單庫單表負(fù)擔(dān),提高查詢性能,縮短查詢時間。
通過分表 ,可以減少數(shù)據(jù)庫的單表負(fù)擔(dān),將壓力分散到不同的表上,同時因為不同的表上的數(shù)據(jù)量少了,起到提高查詢性能,縮短查詢時間的作用,此外,可以很大的緩解表鎖的問題。分表策略可以歸納為垂直拆分和水平拆分:
水平分表 :取模分表就屬于隨機分表,而時間維度分表則屬于連續(xù)分表。如何設(shè)計好垂直拆分,我的建議:將不常用的字段單獨拆分到另外一張擴展表. 將大文本的字段單獨拆分到另外一張擴展表, 將不經(jīng)常修改的字段放在同一張表中,將經(jīng)常改變的字段放在另一張表中。對于海量用戶場景,可以考慮取模分表,數(shù)據(jù)相對比較均勻,不容易出現(xiàn)熱點和并發(fā)訪問的瓶頸。
庫內(nèi)分表 ,僅僅是解決了單表數(shù)據(jù)過大的問題,但并沒有把單表的數(shù)據(jù)分散到不同的物理機上,因此并不能減輕 MySQL 服務(wù)器的壓力,仍然存在同一個物理機上的資源競爭和瓶頸,包括 CPU、內(nèi)存、磁盤 IO、網(wǎng)絡(luò)帶寬等。
分庫與分表帶來的分布式困境與應(yīng)對之策 數(shù)據(jù)遷移與擴容問題----一般做法是通過程序先讀出數(shù)據(jù),然后按照指定的分表策略再將數(shù)據(jù)寫入到各個分表中。分頁與排序問題----需要在不同的分表中將數(shù)據(jù)進行排序并返回,并將不同分表返回的結(jié)果集進行匯總和再次排序,最后再返回給用戶。
不可重復(fù)讀的重點是修改,幻讀的重點在于新增或者刪除。
視圖是虛擬的表,與包含數(shù)據(jù)的表不一樣,視圖只包含使用時動態(tài)檢索數(shù)據(jù)的查詢;不包含任何列或數(shù)據(jù)。使用視圖可以簡化復(fù)雜的 sql 操作,隱藏具體的細(xì)節(jié),保護數(shù)據(jù);視圖創(chuàng)建后,可以使用與表相同的方式利用它們。
視圖不能被索引,也不能有關(guān)聯(lián)的觸發(fā)器或默認(rèn)值,如果視圖本身內(nèi)有order by 則對視圖再次order by將被覆蓋。
創(chuàng)建視圖:create view xxx as xxxx
對于某些視圖比如未使用聯(lián)結(jié)子查詢分組聚集函數(shù)Distinct Union等,是可以對其更新的,對視圖的更新將對基表進行更新;但是視圖主要用于簡化檢索,保護數(shù)據(jù),并不用于更新,而且大部分視圖都不可以更新。
B+tree的磁盤讀寫代價更低,B+tree的查詢效率更加穩(wěn)定 數(shù)據(jù)庫索引采用B+樹而不是B樹的主要原因:B+樹只要遍歷葉子節(jié)點就可以實現(xiàn)整棵樹的遍歷,而且在數(shù)據(jù)庫中基于范圍的查詢是非常頻繁的,而B樹只能中序遍歷所有節(jié)點,效率太低。
B+樹的特點
在最頻繁使用的、用以縮小查詢范圍的字段,需要排序的字段上建立索引。不宜:1)對于查詢中很少涉及的列或者重復(fù)值比較多的列 2)對于一些特殊的數(shù)據(jù)類型,不宜建立索引,比如文本字段(text)等。
如果一個索引包含(或者說覆蓋)所有需要查詢的字段的值,我們就稱 之為“覆蓋索引”。
我們知道在InnoDB存儲引 擎中,如果不是主鍵索引,葉子節(jié)點存儲的是主鍵+列值。最終還是要“回表”,也就是要通過主鍵再查找一次,這樣就 會比較慢。覆蓋索引就是把要查詢出的列和索引是對應(yīng)的,不做回表操作!
舉例 :
學(xué)號姓名性別年齡系別專業(yè) 20020612李輝男20計算機軟件開發(fā) 20060613張明男18計算機軟件開發(fā) 20060614王小玉女19物理力學(xué) 20060615李淑華女17生物動物學(xué) 20060616趙靜男21化學(xué)食品化學(xué) 20060617趙靜女20生物植物學(xué)
主鍵為候選鍵的子集,候選鍵為超鍵的子集,而外鍵的確定是相對于主鍵的。
原文鏈接:
基本原理流程,3個線程以及之間的關(guān)聯(lián);
(1)、varchar與char的區(qū)別
(2)、varchar(50)中50的涵義
(3)、int(20)中20的涵義
(4)、mysql為什么這么設(shè)計
2.InnoDB支持行級鎖,而MyISAM支持表級鎖
3.InnoDB支持MVCC, 而MyISAM不支持
4.InnoDB支持外鍵,而MyISAM不支持
5.InnoDB不支持全文索引,而MyISAM支持。
(2)、innodb引擎的4大特性
插入緩沖(insert buffer),二次寫(double write),自適應(yīng)哈希索引(ahi),預(yù)讀(read ahead)
(3)、2者selectcount(*)哪個更快,為什么 myisam更快,因為myisam內(nèi)部維護了一個計數(shù)器,可以直接調(diào)取。
(1)、您是選擇拆成子表,還是繼續(xù)放一起;
(2)、寫出您這樣選擇的理由。
開放性問題:據(jù)說是騰訊的
select
t1.non_seller,
t3.coupon,
ifnull(sum(t2.bal),0)
from
(select seller,coupon from
(select distinct seller from t2) c,
(select distinct coupon from t2) d
) t3
left join t2 on
t3.seller=t2.seller and t3.coupon=t2.coupon
join t1
on t1.seller=t3.seller
group by
t1.non_seller,t3.coupon
order by t3.coupon,t1.non_seller
Student(Sid,Sname,Sage,Ssex)學(xué)生表
Sid:學(xué)號
Sname:學(xué)生姓名
Sage:學(xué)生年齡
Ssex:學(xué)生性別
Course(Cid,Cname,Tid)課程表
Cid:課程編號
Cname:課程名稱
Tid:教師編號
SC(Sid,Cid,score)成績表
Sid:學(xué)號
Cid:課程編號
score:成績
Teacher(Tid,Tname)教師表
Tid:教師編號:
Tname:教師名字
1、插入數(shù)據(jù)
2、刪除課程表所有數(shù)據(jù)
3、將學(xué)生表中的姓名 張三修改為張大山
或者
4、查詢姓’李’的老師的個數(shù):
5、查詢所有課程成績小于60的同學(xué)的學(xué)號、姓名:
6、查詢沒有學(xué)全所有課的同學(xué)的學(xué)號、姓名
7、查詢平均成績大于60分的同學(xué)的學(xué)號和平均成績
8、查詢學(xué)過“100”并且也學(xué)過編號“101”課程的同學(xué)的學(xué)號、姓名
9、查詢“100”課程比“101”課程成績高的所有學(xué)生的學(xué)號
10、查詢課程編號“100”的成績比課程編號“101”課程高的所有同學(xué)的學(xué)號、姓名
11、查詢學(xué)過“魯迅”老師所教的所有課的同學(xué)的學(xué)號、姓名
12、查詢所有同學(xué)的學(xué)號、姓名、選課數(shù)、總成績
13、查詢至少有一門課與學(xué)號為“1”同學(xué)所學(xué)相同的同學(xué)的學(xué)號和姓名
14、把“SC”表中“魯迅”老師教的課的成績都更改為此課程的平均成績,
錯誤
15、查詢和“2”學(xué)號的同學(xué)學(xué)習(xí)的課程完全相同的其他同學(xué)學(xué)號和姓名
16、刪除學(xué)習(xí)“魯迅”老師課的SC表記錄
17、向SC表中插入一些記錄,這些記錄要求符合以下條件:沒有上過編號“003”課程的同學(xué)學(xué)號、002號課的平均成績
18、查詢各科成績最高和最低的分:以如下的形式顯示:課程ID,最高分,最低分
19、按各科平均成績從低到高和及格率的百分?jǐn)?shù)從高到低順序
20、查詢?nèi)缦抡n程平均成績和及格率的百分?jǐn)?shù)(用”1行”顯示): 數(shù)學(xué)(100),語文(101),英語(102)
22、查詢不同老師所教不同課程平均分從高到低顯示
23、查詢?nèi)缦抡n程成績第3名到第6名的學(xué)生成績單:數(shù)學(xué)(100),語文(101),英語(102)
23、統(tǒng)計下列各科成績,各分?jǐn)?shù)段人數(shù):課程ID,課程名稱,[100-85],[85-70],[70-60],[ 小于60]
24、查詢學(xué)生平均成績及其名次
25、查詢各科成績前三名的記錄(不考慮成績并列情況)
26、查詢每門課程被選修的學(xué)生數(shù)
27、查詢出只選修一門課程的全部學(xué)生的學(xué)號和姓名
28、查詢男生、女生人數(shù)
29、查詢姓“張”的學(xué)生名單
30、查詢同名同姓的學(xué)生名單,并統(tǒng)計同名人數(shù)
31、1981年出生的學(xué)生名單(注:student表中sage列的類型是datetime)
32、查詢平均成績大于85的所有學(xué)生的學(xué)號、姓名和平均成績
33、查詢每門課程的平均成績,結(jié)果按平均成績升序排序,平均成績相同時,按課程號降序排列
34、查詢課程名稱為“英語”,且分?jǐn)?shù)低于60的學(xué)生名字和分?jǐn)?shù)
35、查詢所有學(xué)生的選課情況
36、查詢?nèi)魏我婚T課程成績在70分以上的姓名、課程名稱和分?jǐn)?shù)
37、查詢不及格的課程,并按課程號從大到小的排列
38、查詢課程編號為“101”且課程成績在80分以上的學(xué)生的學(xué)號和姓名
39、求選了課程的學(xué)生人數(shù):
40、查詢選修“魯迅”老師所授課程的學(xué)生中,成績最高的學(xué)生姓名及其成績
41、檢索至少選修兩門課程的學(xué)生學(xué)號
42、查詢?nèi)繉W(xué)生都選修的課程的課程號和課程名(1.一個課程被全部的學(xué)生選修,2.所有的學(xué)生選擇的所有課程)
43、查詢沒學(xué)過“魯迅”老師講授的任一門課程的學(xué)生姓名
44、查詢兩門以上不及格課程的同學(xué)的學(xué)號及其平均成績
45、檢索“101”課程分?jǐn)?shù)小于60,按分?jǐn)?shù)降序排列的同學(xué)學(xué)號
46、刪除“2”同學(xué)的“101”課程的成績
題目:請闡述Mysql Innodb引擎的4個隔離級別
難度:三星
面試頻率:五星
這道題真的是一道數(shù)據(jù)庫的高頻題,數(shù)據(jù)庫題除了索引的原理之外就是這道題的面試頻率最高。
1.Read uncommitted(讀未提交):,最低的隔離級別,可以一個事務(wù)讀到其他事務(wù)沒有提交的數(shù)據(jù),也稱臟讀,這個隔離級別很少人用
2.Read committed(讀已提交):相比于讀未提交,這個隔離級別只能讀到其他事物已經(jīng)提交了的數(shù)據(jù),這個隔離級別用得比較多。但是不是Mysql默認(rèn)的隔離級別
3.Repeatable read(可重復(fù)讀): 在讀已提交隔離級別中,2次讀取同一個變量如果其他事務(wù)修改了它的值,會讀到的不一樣。而在這個隔離級別中,顧名思義,一個事務(wù)開始讀了。多次讀到的值可以保證是一樣的
4.Serializable 序列化 在這個隔離級別下,所有的事務(wù)都將串行操作,是隔離級別最高的也是效率最低的,很少人用
面試官追問:Innodb引擎默認(rèn)隔離級別是哪個
答:可重復(fù)讀
面試官追問:可重復(fù)讀的實現(xiàn)原理
答:使用了MVCC多版本控制(類似樂觀鎖),Innodb引擎會給每一行數(shù)據(jù)加一個版本號信息,當(dāng)一個事務(wù)修改一個數(shù)據(jù)時會增加它的版本號+1,當(dāng)一個事務(wù)開始的時候會緩存下此時的版本號,后面讀取的時候只會讀取這個版本號的數(shù)據(jù),因此別的事務(wù)提交了修改數(shù)據(jù)的版本號大于它,因此不會被讀到
面試官追問:事務(wù)的隔離級別如何設(shè)置:
答:在Mysql命令行下調(diào)用命令 set global.tx_isolation,但這樣Mysql重啟失效,修改my.cnf來永久設(shè)置
面試官追問:可重讀讀有什么問題
答:會出現(xiàn)幻讀,幻讀是指事務(wù)讀取到一個值無法準(zhǔn)確繼續(xù)后續(xù)操作。例如讀取一個值,沒有則插入,但是等插入的時候其他事務(wù)已經(jīng)插入了,這就會導(dǎo)致插入失敗,解決辦法:sql語句顯示加鎖 :select xxxx for update,其他事務(wù)修改數(shù)據(jù)則會阻塞
什么是數(shù)據(jù)庫事務(wù),MySQL 為什么會使用 InnoDB 作為默認(rèn)選項?
1.原子性(一個原子事務(wù)中的所有操作要么全部成功,要么全部失敗) 實現(xiàn)主要基于undo log(回滾日志)
2.一致性(數(shù)據(jù)庫總是從一個一致性的狀態(tài)轉(zhuǎn)換到另一個一致性的狀態(tài))
3. 隔離性(針對并發(fā)事務(wù)而言,事務(wù)必須在不干擾其他進程或事務(wù)的前提下獨立執(zhí)行)
4.持久性(一旦事務(wù)提交成功,它對于數(shù)據(jù)的修改就會永久保存到數(shù)據(jù)庫中)
也就是我們常說的事務(wù)ACID,這樣才能保證事務(wù)中數(shù)據(jù)的正確性。
InnoDB支持事務(wù)安全,InnoDB支持表、行(默認(rèn))級鎖,而MyISAM支持表級鎖;