1 DDL、DML、DCL 分別指什么
ans: DML, Data Manipulation Language, 對(duì)數(shù)據(jù)進(jìn)行操作的語(yǔ)句,如 select, insert, update
DDL,Data Definition Language,定義或改變表結(jié)構(gòu)、數(shù)據(jù)類型、表之間的鏈接和約束等工作,如 create、alter、drop
DCL,Data Control Language,用來(lái)設(shè)置或更改數(shù)據(jù)庫(kù)用戶或角色權(quán)限的語(yǔ)句,如 GRANT, COMMIT, ROLLBACK
參考:https://blog.csdn.net/level_level/article/details/4248685
2 數(shù)據(jù)庫(kù)的幾大范式
ans: 第一范式(1NF): 每個(gè)屬性必須是原子項(xiàng)目
第二范式(2NF):滿足第一范式,且有唯一主鍵在表中保證每一行都具有唯一性。
第三范式(3NF):滿足第一、二范式,且每一列數(shù)據(jù)都和主鍵直接相關(guān),而不能間接相關(guān)。
參考:http://www.cnblogs.com/linjiqin/archive/2012/04/01/2428695.html
3 說(shuō)說(shuō)分庫(kù)與分表設(shè)計(jì),分庫(kù)與分表帶來(lái)的分布式困境與對(duì)應(yīng)之策
ans:對(duì)于大型互聯(lián)網(wǎng)應(yīng)用,數(shù)據(jù)庫(kù)的單表數(shù)據(jù)量可能達(dá)到千萬(wàn)級(jí)甚至億級(jí),此時(shí)即使采用主從模式的架構(gòu)壓力也會(huì)比較大,而且主從模式也只能提升讀性能,寫(xiě)數(shù)據(jù)仍然受到master性能的限制。
通常會(huì)采用分庫(kù)分表的手段優(yōu)化這個(gè)問(wèn)題,分表是將數(shù)據(jù)從邏輯上橫向的拆分成多張表,這樣可以減少每張表的記錄條數(shù),減少檢索時(shí)間;分庫(kù)是在物理層面將表橫向拆分,每個(gè)庫(kù)都有自己的master,從而提升寫(xiě)性能。分庫(kù)分表也可以結(jié)合使用。
但是分庫(kù)分表也帶來(lái)幾個(gè)問(wèn)題:
(1)數(shù)據(jù)遷移與擴(kuò)容,連續(xù)分表可能導(dǎo)致熱點(diǎn)問(wèn)題,而隨機(jī)分表在擴(kuò)展時(shí)又涉及到數(shù)據(jù)遷移問(wèn)題。
(2)表關(guān)聯(lián)問(wèn)題,分庫(kù)分表情況下,多表聯(lián)合查詢可能導(dǎo)致跨庫(kù)關(guān)聯(lián),最好將數(shù)據(jù)放在程序中品種,或者采用反范式設(shè)計(jì)。
(3)分頁(yè)與排序問(wèn)題,與表關(guān)聯(lián)同樣存在跨庫(kù)的問(wèn)題。
(4)分布式事務(wù),分庫(kù)分表場(chǎng)景下如何保證數(shù)據(jù)的一致性就成為一個(gè)難題。目前分布式事務(wù)并沒(méi)有很好的解決方案,難以滿足數(shù)據(jù)強(qiáng)一致性,一般情況下,使存儲(chǔ)數(shù)據(jù)盡可能達(dá)到用戶一致,保證系統(tǒng)經(jīng)過(guò)一段較短的時(shí)間的自我恢復(fù)和修正,數(shù)據(jù)最終達(dá)到一致。
(5)分布式全局唯一ID,在單庫(kù)單表的情況下,直接使用數(shù)據(jù)庫(kù)自增特性來(lái)生成主鍵ID已經(jīng)不再適合,需要使用全局唯一 ID。
一般在項(xiàng)目一開(kāi)始不采用分庫(kù)與分表設(shè)計(jì),而是隨著業(yè)務(wù)的增長(zhǎng),在無(wú)法繼續(xù)優(yōu)化的情況下,再考慮分庫(kù)與分表提高系統(tǒng)的性能。
4 存儲(chǔ)引擎的 InnoDB 與 MyISAM 區(qū)別、優(yōu)缺點(diǎn)、使用場(chǎng)景
ans: 區(qū)別:
- InnoDB支持事務(wù)、外部鍵等高級(jí),MyISAM不支持
- MyISAM執(zhí)行數(shù)度比InnoDB類型更快
- InnoDB不支持FULLTEXT類型的索引,不保存表的行數(shù)。因此在執(zhí)行count(*) 時(shí)需要全表掃描
- 對(duì)于自增長(zhǎng)的字段,InnoDB中必須包含只有該字段的索引,但是在MyISAM表中可以和其他字段一起建立聯(lián)合索引
- 清空整個(gè)表時(shí),InnoDB是一行一行的刪除,效率非常慢。MyISAM則會(huì)重建表。
- InnoDB支持行鎖。
優(yōu)缺點(diǎn): - MyISAM,查詢數(shù)據(jù)相對(duì)較快,適合大量的select,可以全文索引;但不支持事務(wù),不支持外鍵,并發(fā)量較小,不適合大量update
- InnoDB,支持事務(wù),支持外鍵,并發(fā)量較大,適合大量update;查詢數(shù)據(jù)相對(duì)較慢,不適合大量的select
使用場(chǎng)景:MyISAM適合查詢以及插入為主的應(yīng)用,InnoDB適合頻繁修改以及涉及到安全性較高的應(yīng)用。
參考:https://www.cnblogs.com/wt645631686/p/6868678.html
5 SQL關(guān)鍵字的執(zhí)行順序
ans: FROM -> ON -> OUTER -> WHERE -> GROUP BY -> HAVING -> SELECT -> DISTINCT -> ORDER BY -> TOP
參考:https://www.designcise.com/web/tutorial/what-is-the-order-of-execution-of-an-sql-query
6 explain 命令,包含哪些列,Type列有哪幾種值。
ans: EXPLAIN命令是查看優(yōu)化器如何決定執(zhí)行查詢的主要方法。
列信息包括:
(1)id,包含一組數(shù)字,表示查詢中執(zhí)行select子句或操作表的順序;如果是子查詢,id的序號(hào)會(huì)遞增,id值越大優(yōu)先級(jí)越高,越先被執(zhí)行;id如果相同,可以認(rèn)為是一組,從上往下順序執(zhí)行。
(2)select_type,查詢中每個(gè)select子句的類型
- SIMPLE,查詢中不包含子查詢或者UNION
- 查詢中若包含任何復(fù)雜的子部分,最外層查詢則被標(biāo)記為PRIMARY
- 在SELECT或WHERE列表中包含了子查詢,該子查詢被標(biāo)記為:SUBQUERY
- 在FROM列表中包含的子查詢被標(biāo)記為:DERIVED(衍生)
- 若第二個(gè)SELECT出現(xiàn)在UNION之后,則被標(biāo)記為UNION;
- 從UNION表獲取結(jié)果的SELECT被標(biāo)記為:UNION RESULT
(3)type,表示MySQL在表中找到所需行的方式,又稱“訪問(wèn)類型”,ALL->index->range->ref->eq_ref->const->system->NULL,性能依次提升。
(4)possible_keys,指出MySQL能使用哪個(gè)索引在表中找到記錄,查詢涉及到的字段上若存在索引,則該索引將被列出,但不一定被查詢使用。
(5)key,顯示MySQL在查詢中實(shí)際使用的索引,若沒(méi)有使用索引,顯示為NULL。
(6)key_len,表示索引中使用的字節(jié)數(shù),可通過(guò)該列計(jì)算查詢中使用的索引的長(zhǎng)度(key_len顯示的值為索引字段的最大可能長(zhǎng)度,并非實(shí)際使用長(zhǎng)度,即key_len是根據(jù)表定義計(jì)算而得,不是通過(guò)表內(nèi)檢索出的)
(7)ref,表示上述表的連接匹配條件,即哪些列或常量被用于查找索引列上的值。
(8)rows,表示MySQL根據(jù)表統(tǒng)計(jì)信息及索引選用情況,估算的找到所需的記錄所需要讀取的行數(shù)。
(9)Extra,包含不適合在其他列中顯示但十分重要的額外信息。 - Using index,該值表示相應(yīng)的select操作中使用了覆蓋索引(Covering Index)
- Using where 表示mysql服務(wù)器將在存儲(chǔ)引擎檢索行后再進(jìn)行過(guò)濾。
- Using temporary 表示MySQL需要使用臨時(shí)表來(lái)存儲(chǔ)結(jié)果集,常見(jiàn)于排序和分組查詢。
- Using filesort MySQL中無(wú)法利用索引完成的排序操作稱為“文件排序”。
- Using join buffer 強(qiáng)調(diào)了在獲取連接條件時(shí)沒(méi)有使用索引,并且需要連接緩沖區(qū)來(lái)存儲(chǔ)中間結(jié)果。
- Impossible where 強(qiáng)調(diào)了where語(yǔ)句會(huì)導(dǎo)致沒(méi)有符合條件的行。
- Select tables optimized away 這個(gè)值意味著僅通過(guò)使用索引,優(yōu)化器可能僅從聚合函數(shù)結(jié)果中返回一行。
- Index merges 當(dāng)MySQL 決定要在一個(gè)給定的表上使用超過(guò)一個(gè)索引的時(shí)候,就會(huì)出現(xiàn)以下格式中的一個(gè),詳細(xì)說(shuō)明使用的索引以及合并的類型。Using sort_union(...)、Using union(...)、Using intersect(...)
參考:http://www.cnblogs.com/gomysql/p/3720123.html
7 SQL怎么進(jìn)行優(yōu)化
參考:https://blog.csdn.net/jie_liang/article/details/77340905
8 limit 20000 加載很慢怎么解決
ans: 記錄上一次檢索的最大值,加入本次檢索的where條件中,利用索引快速定位到開(kāi)始檢索的位置。
9 有哪幾種索引,什么時(shí)候該(不該)建索引,
ans: 主鍵索引(Primary Key)、唯一索引(UNIQUE index)、普通索引(index)、全文索引(FullText index)
- 當(dāng)需要快速查找匹配where條件的時(shí)候,為了盡量避免全表檢索,應(yīng)當(dāng)建立索引。
- 即使存在索引,但有些情況下數(shù)據(jù)庫(kù)可能無(wú)法使用:帶有or條件且部分條件無(wú)索引;存在組合索引但未使用第一個(gè)字段;like以“%”開(kāi)頭;對(duì)索引字段有數(shù)據(jù)計(jì)算或函數(shù)調(diào)用
- 不適合建立索引的幾種場(chǎng)景:
(1) 數(shù)據(jù)唯一性差(一個(gè)字段的取值只有幾種時(shí))的字段不要使用索引
(2)頻繁更新的字段不要使用索引
(3)字段不在where語(yǔ)句出現(xiàn)時(shí)不要添加索引, 或者含IS NULL /IS NOT NULL/ like ‘%輸入符%’等條件,不建議使用索引
(4)where 子句里對(duì)索引列使用不等于(<>),使用索引效果一般
參考:http://www.cnblogs.com/tommy-huang/p/4483684.html
https://blog.csdn.net/kaka1121/article/details/53395628
10 聚集索引與非聚集索引的區(qū)別
ans: 聚集索引:索引中鍵值的邏輯順序決定了表中相應(yīng)行的物理順序(索引中的數(shù)據(jù)物理存放地址和索引的順序是一致的)
非聚集索引:索引的邏輯順序與磁盤(pán)上的物理存儲(chǔ)順序不同。
- 對(duì)于MySQL的InnoDB引擎,如果一個(gè)主鍵被定義了,那么這個(gè)主鍵就是作為聚集索引
- 如果沒(méi)有,那么該表的第一個(gè)唯一非空索引被作為聚集索引
- 如果沒(méi)有主鍵也沒(méi)有合適的唯一索引,那么innodb內(nèi)部會(huì)生成一個(gè)隱藏的主鍵作為聚集索引,這個(gè)隱藏的主鍵是一個(gè)6個(gè)字節(jié)的列,改列的值會(huì)隨著數(shù)據(jù)的插入自增。
參考:https://www.cnblogs.com/duzhentong/p/8639223.html
11 Mysql索引的數(shù)據(jù)結(jié)構(gòu),為什么要用 B+tree 作為 MySql
ans: B tree 是多叉查找樹(shù),對(duì)于一顆階數(shù)為m的B-tree:
- 根結(jié)點(diǎn)要么是一個(gè)葉子結(jié)點(diǎn),要么是一個(gè)至少有2個(gè)子結(jié)點(diǎn)的父結(jié)點(diǎn)
- 根結(jié)點(diǎn)的key個(gè)數(shù)至少1個(gè),至多m-1個(gè)
- 非根結(jié)點(diǎn)key個(gè)數(shù)至少 m/2(向上取整)-1 個(gè),至多m-1個(gè)
- 所有葉節(jié)點(diǎn)具有相同的深度
- 結(jié)點(diǎn)最左邊的指針指向的子結(jié)點(diǎn)的key全部小于該結(jié)點(diǎn),右邊大于
B+tree 是B tree的變種,主要區(qū)別在于: - 每個(gè)節(jié)點(diǎn)如果有n個(gè)子結(jié)點(diǎn),就有n個(gè)key
- 每個(gè)非葉子結(jié)點(diǎn)不保存數(shù)據(jù),只用來(lái)索引,所有數(shù)據(jù)都保存在葉子節(jié)點(diǎn)。
- 帶有順序訪問(wèn)指針的B+Tree 還會(huì)在葉子結(jié)點(diǎn)維護(hù)一個(gè)指向相鄰葉子節(jié)點(diǎn)的指針,這就形成了順序訪問(wèn)的鏈表,目的是為了提高區(qū)間訪問(wèn)的性能。
B tree適用于數(shù)據(jù)庫(kù)存取和查找文件,這是由于索引本身也很大,不可能全部存儲(chǔ)在內(nèi)存中,因此索引往往以索引文件的形式存儲(chǔ)的磁盤(pán)上。因此每次查詢就需要從硬盤(pán)IO,而IO的性能是無(wú)法與內(nèi)存相比的,因此查詢硬盤(pán)次數(shù)越少,效率就越高。而B(niǎo) tree的復(fù)雜度為O(logdN),樹(shù)的高度比較低,適合用于這類場(chǎng)景。B+樹(shù)由于其內(nèi)部結(jié)點(diǎn)相對(duì)B樹(shù)更小,一次讀入內(nèi)存的索引信息更多,所以更適合實(shí)際應(yīng)用中操作系統(tǒng)的文件索引和數(shù)據(jù)庫(kù)索引。
MyISAM引擎使用B+Tree作為索引結(jié)構(gòu),葉節(jié)點(diǎn)的data域存放的是數(shù)據(jù)記錄的地址,索引文件和數(shù)據(jù)文件是分離的。這種索引也被稱為“非聚集索引”
InnoDB的數(shù)據(jù)文件本身就是索引文件,這個(gè)索引的key是數(shù)據(jù)表的主鍵,即“聚集索引”。且InnoDB的輔助索引data域存儲(chǔ)相應(yīng)記錄主鍵的值而不是地址,也就是說(shuō)使用輔助索引檢索數(shù)據(jù)后,還需要用主鍵再去查找需要的數(shù)據(jù)。
12 哈希索引,自適應(yīng)哈希索引(AHI)
ans:哈希索引,就是采用哈希算法把鍵值換算成新的哈希值,檢索時(shí)不需要類似B+樹(shù)那樣從根節(jié)點(diǎn)到葉子節(jié)點(diǎn)逐級(jí)查找,只需一次哈希算法即可立刻定位到相應(yīng)的位置,速度非??臁5珕?wèn)題在于哈希索引對(duì)等值查詢的速度很快,非等值查詢就無(wú)能為力了,且不能利用索引完成排序。在有大量重復(fù)鍵值情況下,還會(huì)存在哈希碰撞問(wèn)題。
自適應(yīng)哈希: InnoDB存儲(chǔ)引擎會(huì)監(jiān)控對(duì)表上二級(jí)索引的查找,如果發(fā)現(xiàn)某二級(jí)索引被頻繁訪問(wèn),InnoDB就會(huì)使用索引鍵的前綴建立一個(gè)哈希索引。將索引值轉(zhuǎn)換為一種指針,便于直接訪問(wèn),帶來(lái)速度的提升。
參考:https://www.cnblogs.com/bonelee/p/6224698.html
http://www.notedeep.com/note/38/page/221
13 mysql 最大鏈接數(shù)
ans:mysql可以自定義最大鏈接上限 max_connections,默認(rèn)值是151
參考:https://dev.mysql.com/doc/refman/8.0/en/too-many-connections.html
14 數(shù)據(jù)庫(kù)事務(wù)特性
ans: ACID:
- 原子性(Atomicity):即事務(wù)是不可分割的最小工作單元,事務(wù)內(nèi)的操作要么全做,要么全不做;
- 一致性(Consistency):在事務(wù)執(zhí)行前數(shù)據(jù)庫(kù)的數(shù)據(jù)處于正確的狀態(tài),而事務(wù)執(zhí)行完成后數(shù)據(jù)庫(kù)的數(shù)據(jù)還是應(yīng)該處于正確的狀態(tài),即數(shù)據(jù)完整性約束沒(méi)有被破壞;如銀行轉(zhuǎn)帳,A轉(zhuǎn)帳給B,必須保證A的錢一定轉(zhuǎn)給B,一定不會(huì)出現(xiàn)A的錢轉(zhuǎn)了但B沒(méi)收到,否則數(shù)據(jù)庫(kù)的數(shù)據(jù)就處于不一致(不正確)的狀態(tài)。
- 隔離性(Isolation):并發(fā)事務(wù)執(zhí)行之間互不影響,在一個(gè)事務(wù)內(nèi)部的操作對(duì)其他事務(wù)是不產(chǎn)生影響,這需要事務(wù)隔離級(jí)別來(lái)指定隔離性;
- 持久性(Durability):事務(wù)一旦執(zhí)行成功,它對(duì)數(shù)據(jù)庫(kù)的數(shù)據(jù)的改變必須是永久的,不會(huì)因比如遇到系統(tǒng)故障或斷電造成數(shù)據(jù)不一致或丟失。
15 MySQL如何保持事務(wù)隔離性
ans: MySQL的InnoDB引擎支持表鎖、行鎖,默認(rèn)隔離級(jí)別是可重復(fù)讀 ( REPEATABLE READ)
(1)MySQL實(shí)現(xiàn)的鎖種類:
- InnoDB實(shí)現(xiàn)了標(biāo)準(zhǔn)的底層行級(jí)鎖,共享鎖(S)& 獨(dú)占鎖(X)
- 意向鎖(Intention Locks),意圖共享鎖(IS)& 意圖獨(dú)占鎖(IX),意圖鎖是表級(jí)鎖,指示事務(wù)稍后對(duì)表中的行需要哪種類型的鎖(共享或獨(dú)占),申請(qǐng)順序必須為 IS -> S, IX -> X。
使用意圖鎖定的主要目的,是為了向后到的鎖請(qǐng)求顯示當(dāng)前表已被鎖定了一行,或者準(zhǔn)備鎖定表中的一行。 - 記錄鎖,是索引記錄上的鎖,即使表沒(méi)有定義任何索引。InnoDB會(huì)創(chuàng)建一個(gè)隱藏的索引來(lái)鎖定記錄。
- 間隙鎖,對(duì)索引記錄之間的間隙的鎖,間隙可能跨越單個(gè)索引值、多個(gè)索引值,甚至是空的。使用間隙鎖的目的是防止其他事務(wù)插入到已經(jīng)鎖定的間隙當(dāng)中。
- next-key,記錄鎖和索引記錄前的間隙上的間隙鎖的組合。
(2)四種隔離級(jí)別&實(shí)現(xiàn)原理:
- READ UNCOMMITTED(未提交讀):事務(wù)未提交前,就可被其他事務(wù)讀?。〞?huì)出現(xiàn)幻讀、臟讀、不可重復(fù)讀),所有操作都不加鎖。
- READ_COMMITTED(提交讀):一個(gè)事務(wù)提交后才能被其他事務(wù)讀取到。
對(duì)于讀操作,每次都會(huì)讀最新版本的快照;
對(duì)于update、delete等寫(xiě)操作僅鎖定匹配的索引記錄,而不鎖定記錄前的間隙,因此允許在鎖定的記錄旁邊自由插入新記錄。所以會(huì)造成幻讀、不可重復(fù)讀。 - REPEATABLE_READ(可重復(fù)讀):保證在一個(gè)事務(wù)中多次讀取同一個(gè)數(shù)據(jù)時(shí),其值都和事務(wù)開(kāi)始時(shí)候的內(nèi)容是一致。這是InnoDB的默認(rèn)隔離級(jí)別。
讀操作每次讀事務(wù)開(kāi)始前版本的快找,寫(xiě)操作如果帶唯一搜索條件且使用唯一索引,就只鎖定找到的索引記錄,而不鎖定記錄前的間隙。
對(duì)于其他搜索條件,InnoDB鎖定掃描的索引范圍,使用間隙鎖或next-key鎖來(lái)阻止其他會(huì)話插入到范圍覆蓋的間隙中。會(huì)出現(xiàn)幻讀(在 SQL 標(biāo)準(zhǔn)中,RR 是無(wú)法避免幻讀問(wèn)題的,但是 InnoDB 實(shí)現(xiàn)的 RR 避免了幻讀問(wèn)題) - SERIALIZABLE(序列化):讀用共享鎖,寫(xiě)用互斥鎖,讀鎖和寫(xiě)鎖互斥,代價(jià)最高最可靠的隔離級(jí)別(能防止臟讀、不可重復(fù)讀、幻讀)。
(3)關(guān)于幾種隔離級(jí)別下存在的問(wèn)題
- 臟讀:如果一個(gè)事務(wù)對(duì)數(shù)據(jù)進(jìn)行了更新,尚未提交的情況下另一個(gè)事務(wù)“看到了”這個(gè)未提交的結(jié)果,這可能造成的問(wèn)題是,當(dāng)事務(wù)回滾,那么第二個(gè)事務(wù)看到的數(shù)據(jù)就是臟數(shù)據(jù)。
- 不可重復(fù)讀:是指在一個(gè)事務(wù)過(guò)程中,對(duì)同一個(gè)數(shù)據(jù)進(jìn)行多次讀取,每次的結(jié)果都不同,如事務(wù)1第一次讀取數(shù)據(jù),事務(wù)2尚未更新,而第二次讀物數(shù)據(jù)時(shí)事務(wù)2已經(jīng)更新了數(shù)據(jù)。
- 幻讀:幻讀針對(duì)的是多筆記錄,與不可重復(fù)讀類似,都是在一個(gè)事務(wù)過(guò)程中多次讀取結(jié)果不同,幻讀針對(duì)的是結(jié)果集有差異,可能多或少了一些記錄。
需要注意的是,RR并沒(méi)有完全解決幻讀,參考(https://segmentfault.com/a/1190000012669504),完全解決幻讀仍然需要采用加鎖的方式,實(shí)際上是將操作序列化了。
參考:https://zxytech.com/mysql/mysql5/storage-engines.html#innodb-transaction-model
https://dev.mysql.com/doc/refman/8.0/en/innodb-transaction-isolation-levels.html
https://blog.csdn.net/matt8/article/details/53096405
http://database.51cto.com/art/201901/591260.htm
16 mvcc 如何保證在RR級(jí)別下避免幻讀
ans: MVCC 即 Multi-Version Concurrency Control,多版本的并發(fā)控制協(xié)議。
它的主要原理是:

- MySql InnoDB 引擎 的數(shù)據(jù)結(jié)構(gòu)中,包含兩列特殊的字段:DB_TRX_ID和DB_ROLL_PTR。其中DB_TRX_ID表示修改該行事務(wù)的事務(wù)ID,而DB_ROLL_PTR表示指向該行回滾段的指針,該行記錄上所有版本數(shù)據(jù),在undo中都通過(guò)鏈表形式組織,該值實(shí)際指向undo中該行的歷史記錄鏈表。
- 確定某個(gè)事務(wù)的影響是否在當(dāng)前事務(wù)可見(jiàn)的原則:
(1)如果這個(gè)事務(wù)的標(biāo)號(hào) < read_view 中 trx_id 最小的事務(wù),那么認(rèn)為此事務(wù)已經(jīng)提交,更改可見(jiàn)
(2)如果這個(gè)事務(wù)的標(biāo)號(hào) > read_view 中 trx_id 最大的事務(wù),那么認(rèn)為此事務(wù)是在當(dāng)前事務(wù)之后開(kāi)啟的,更改不可見(jiàn)
(3)如果這個(gè)事務(wù)的標(biāo)號(hào) 在 read_view 的最大-最小 trx_id 區(qū)間內(nèi),那么再檢查read_view,如果這個(gè)事務(wù)存在其中,說(shuō)明它還沒(méi)有提交,那么更改不可見(jiàn);反之認(rèn)為已經(jīng)提交,更改可見(jiàn)。
RC級(jí)別下,每次select時(shí)都會(huì)更新read_view,因此可能出現(xiàn)幻讀的情況。
RR級(jí)別下,只有第一次select才會(huì)生成read_view,后續(xù)不再變更,直到事務(wù)結(jié)束。此時(shí)當(dāng)前事務(wù)不會(huì)感知到在事務(wù)過(guò)程中其他事務(wù)的變化,因此不會(huì)出現(xiàn)幻讀(有爭(zhēng)議)。
RR級(jí)別下如果要嚴(yán)格意義避免幻讀,那么應(yīng)當(dāng)使用“當(dāng)前讀”語(yǔ)句(select...for update)。例如一個(gè)帶有unique key = id 的表,session A 讀取 id>0 的數(shù)據(jù),隨后session B向表中插入id=2的數(shù)據(jù),在RR級(jí)別,session A中不論什么時(shí)候讀取數(shù)據(jù),都不會(huì)看到session B插入的數(shù)據(jù),但session A如果自己也插入插入id=2時(shí)就會(huì)發(fā)生Duplicate entry錯(cuò)誤。使用“當(dāng)前讀”語(yǔ)句就可以避免這樣的問(wèn)題,這些語(yǔ)句會(huì)為id>0的數(shù)據(jù)加入間隙鎖(gap lock),控制這個(gè)區(qū)間不被其他事務(wù)插入。
參考:http://hbasefly.com/2017/08/19/mysql-transaction/
17 數(shù)據(jù)庫(kù)連接池的作用
ans: 維護(hù)一定數(shù)量的連接,減少創(chuàng)建連接的時(shí)間
更快的響應(yīng)時(shí)間
統(tǒng)一的管理
參考: https://blog.csdn.net/qq_22222499/article/details/79060495
18 最左匹配原則
ans :最左匹配原則是針對(duì)索引的。
舉例來(lái)說(shuō):兩個(gè)字段(name,age)建立聯(lián)合索引,如果where age=12這樣的話,是沒(méi)有利用到索引的,這里我們可以簡(jiǎn)單的理解為先是對(duì)name字段的值排序,然后對(duì)age的數(shù)據(jù)排序,如果直接查age的話,這時(shí)就沒(méi)有利用到索引了,查詢條件where name=’xxx’ and age=xx 這時(shí)的話,就利用到索引了,再來(lái)思考下where age=xx and name=’xxx‘ 這個(gè)sql會(huì)利用索引嗎,按照正常的原則來(lái)講是不會(huì)利用到的,但是優(yōu)化器會(huì)進(jìn)行優(yōu)化,把位置交換,這個(gè)sql也能利用到索引了
18 如何實(shí)現(xiàn) update的樂(lè)觀鎖, select悲觀鎖
ans:
(1)樂(lè)觀鎖:mysql 語(yǔ)法不支持樂(lè)觀鎖,需要自己實(shí)現(xiàn): 通過(guò)比較版本號(hào)/舊值
(2)悲觀鎖:select -> select ... for update
參考:https://www.cnblogs.com/zhiqian-ali/p/6200874.html
https://stackoverflow.com/questions/17431338/optimistic-locking-in-mysql