MySQL數(shù)據(jù)庫(kù)(review中)

  • 數(shù)據(jù)庫(kù):物理操作系統(tǒng)文件或其他形式文件的集合。
  • 數(shù)據(jù)庫(kù)實(shí)例:MySQL數(shù)據(jù)庫(kù)由后臺(tái)線程以及一個(gè)共享內(nèi)存區(qū)組成。數(shù)據(jù)庫(kù)實(shí)例才是真正用于操作數(shù)據(jù)庫(kù)文件的。

? ? ?當(dāng)啟動(dòng)數(shù)據(jù)庫(kù)實(shí)例時(shí),MySQL數(shù)據(jù)庫(kù)會(huì)去讀取配置文件,根據(jù)配置文件的參數(shù)來(lái)啟動(dòng)數(shù)據(jù)庫(kù)實(shí)例。若無(wú)配置文件,MySQL會(huì)按照編譯時(shí)的默認(rèn)參數(shù)設(shè)置來(lái)啟動(dòng)實(shí)例。多個(gè)配置文件以讀取到的最后一個(gè)配置文件中的參數(shù)為準(zhǔn)。

一.MySQL體系架構(gòu)


? ? ?如圖,MySQL由連接池組件、管理服務(wù)和工具組件、SQL接口組件、查詢分析器組件、優(yōu)化器組件、緩沖組件、插件式存儲(chǔ)引擎、物理文件組成。MySQL插件式的存儲(chǔ)引擎架構(gòu)提供了一系列標(biāo)準(zhǔn)的管理和服務(wù)支持,這些標(biāo)準(zhǔn)與存儲(chǔ)引擎本身無(wú)關(guān),可能是每個(gè)數(shù)據(jù)庫(kù)系統(tǒng)本身都必須的。存儲(chǔ)引擎是基于表的,而不是數(shù)據(jù)庫(kù)。

1.MySQL存儲(chǔ)引擎

? ? ?用戶可以根據(jù)MySQL預(yù)定義的存儲(chǔ)引擎接口編寫(xiě)自己的存儲(chǔ)引擎。
InnoDB引擎和MyISAM引擎的區(qū)別

InnoDB MyISAM
支持行級(jí)鎖(通過(guò)MVCC來(lái)提高高并發(fā)性) 僅支持表級(jí)鎖(影響并發(fā)性能)
支持事務(wù) 不支持事務(wù)
聚簇索引結(jié)構(gòu),5.6版本支持全文索引 支持全文索引
支持崩潰自動(dòng)恢復(fù) 崩潰后無(wú)法自動(dòng)恢復(fù),只能修復(fù),耗時(shí)且存在數(shù)據(jù)丟失
\ MyISAM壓縮表,只讀,減少磁盤(pán)I/O,提高了查詢性能,為行記錄獨(dú)立壓縮

InnoDB存儲(chǔ)引擎
? ? ?InnoDB存儲(chǔ)引擎支持事務(wù),其特點(diǎn)是支持行級(jí)鎖、支持外鍵、支持非鎖定讀,即默認(rèn)讀取操作不會(huì)產(chǎn)生鎖。InnoDB通過(guò)使用多版本并發(fā)控制(MVCC)來(lái)獲得高并發(fā)性,并且實(shí)現(xiàn)了SQL標(biāo)準(zhǔn)的4種隔離級(jí)別,默認(rèn)為Repeatable級(jí)別。同時(shí),使用next-key-locking策略來(lái)避免幻讀現(xiàn)象。
? ? ?除此之外,InnoDB還提供了插入緩沖、二次寫(xiě)、自適應(yīng)哈希索引、預(yù)讀等高性能和高可用的功能。
? ? ?InnoDB對(duì)于其表空間中數(shù)據(jù)的存儲(chǔ),采用聚簇索引的方式,每張表的存儲(chǔ)都是按主鍵的順序進(jìn)行存放。若無(wú)主鍵,則默認(rèn)為每行生成一個(gè)6字節(jié)RowID。

MyISAM存儲(chǔ)引擎
? ? ?MyISAM存儲(chǔ)引擎不支持事務(wù)、僅支持表級(jí)鎖、支持全文索引,其緩沖池只緩沖索引文件,而不緩沖數(shù)據(jù)文件(數(shù)據(jù)文件的緩沖由系統(tǒng)自身完成)。
? ? ?MyISAM存儲(chǔ)引擎表由MYD和MYI組成,MYD用于存放數(shù)據(jù)文件,MYI用于存放索引文件??梢酝ㄟ^(guò)使用myisampack工具來(lái)壓縮數(shù)據(jù),壓縮后表是只讀的,也可通過(guò)myisampack工具來(lái)解壓數(shù)據(jù)文件。

Memory存儲(chǔ)引擎
? ? ?Memory存儲(chǔ)引擎將表中的數(shù)據(jù)存放在內(nèi)存中,如果數(shù)據(jù)庫(kù)重啟或崩潰,表中的數(shù)據(jù)都將消失,其默認(rèn)使用哈希索引,僅支持表鎖,不支持TEXT和BLOB列類(lèi)型,且存儲(chǔ)變長(zhǎng)字段(vachar)時(shí)是按照定長(zhǎng)字段(char)方式進(jìn)行的。
? ? ?MySQL數(shù)據(jù)庫(kù)使用Memory存儲(chǔ)引擎作為臨時(shí)表來(lái)存放查詢的中間結(jié)果集。若中間結(jié)果集大于引擎表容量設(shè)定值或者中間結(jié)果含有TEXT或BLOB列字段類(lèi)型,則MySQL數(shù)據(jù)庫(kù)會(huì)把其轉(zhuǎn)換為MyISAM存儲(chǔ)引擎表而存放在磁盤(pán)中,但MyISAM不緩存數(shù)據(jù)文件,因此這時(shí)產(chǎn)生的臨時(shí)表的性能對(duì)于查詢會(huì)有損失。

2.連接MySQL

? ? ?連接MySQL的操作是一個(gè)連接進(jìn)程與MySQL數(shù)據(jù)庫(kù)實(shí)例j進(jìn)行通信,本質(zhì)上是進(jìn)程通信。常用的進(jìn)程通信的方式有管道、命名管道、命名字、TCP/IP套接字、UNIX域套接字。

TCP/IP
? ? ?TCP/IP套接字方式是MySQL數(shù)據(jù)在任何平臺(tái)下都提供的連接方式,是在TCP/IP連接上建立一個(gè)基于網(wǎng)絡(luò)的連接請(qǐng)求。在通過(guò)TCP/IP連接到MySQL實(shí)例時(shí),MySQL數(shù)據(jù)庫(kù)會(huì)先檢查一張權(quán)限表(user),用于判斷發(fā)起請(qǐng)求的客戶端IP是否允許連接到MySQL實(shí)例。

二.InnoDB存儲(chǔ)引擎

1.InnoDB體系架構(gòu)

InnoDB存儲(chǔ)引擎體系架構(gòu)

InnoDB存儲(chǔ)引擎有多個(gè)內(nèi)存塊,共同組成了一個(gè)大的內(nèi)存池,負(fù)責(zé)如下工作:

  • 維護(hù)所有進(jìn)程/線程需要訪問(wèn)的多個(gè)內(nèi)部數(shù)據(jù)結(jié)構(gòu);
  • 緩存磁盤(pán)上的數(shù)據(jù),方便快速讀取,同時(shí)在對(duì)磁盤(pán)文件的數(shù)據(jù)修改之前在這里緩存;
  • 重做日志(redo log)緩沖;

后臺(tái)線程的主要作用是負(fù)責(zé)刷新內(nèi)存池中的數(shù)據(jù),保證其是最近的數(shù)據(jù),此外將已修改的數(shù)據(jù)文件刷新到磁盤(pán)文件中,同時(shí)保證在數(shù)據(jù)庫(kù)發(fā)生異常時(shí)InnoDB能夠恢復(fù)到正常運(yùn)行狀態(tài)。

后臺(tái)線程

InnoDB存儲(chǔ)引擎是多線程的模型,其后臺(tái)有多個(gè)不同的線程,負(fù)責(zé)處理不同的任務(wù)。

  • Master Thread
    主要負(fù)責(zé)將緩沖池中的數(shù)據(jù)異步刷新到磁盤(pán),保證數(shù)據(jù)一致性,包括臟頁(yè)的刷新、合并插入緩存、UNDO頁(yè)的回收等。
  • IO Thread
    InnoDB存儲(chǔ)引擎大量使用了AIO來(lái)處理寫(xiě)IO請(qǐng)求,而IO Thread主要負(fù)責(zé)這些IO請(qǐng)求的回調(diào)處理。
  • Purge Thread
    ? ? ?事務(wù)提交后,其所使用的undolog可能不再需要,需要Purge Thread回收已經(jīng)使用并分配的undo頁(yè)。(在InnoDB 1.1之前,purge操作僅在Master Thread中完成。而從InnoDB 1.1之后,purge操作可以獨(dú)立到單獨(dú)的線程中進(jìn)行,以此來(lái)減輕Master Thread的工作,從而提高CPU的使用率以及提升存儲(chǔ)引擎的性能)。
  • Page Cleaner Thread
    Page Cleaner Thread是在InnoDB 1.2.x版本中引入的,其作用是將之前版本中臟頁(yè)的刷新操作都放入到單獨(dú)的線程中來(lái)完成。

內(nèi)存

  • 緩沖池
    ? ? ?InnoDB存儲(chǔ)引擎是基于磁盤(pán)存儲(chǔ)的,并將其中的記錄按頁(yè)的方式進(jìn)行管理,因此可將其視為基于磁盤(pán)的數(shù)據(jù)庫(kù)系統(tǒng)。由于CPU速度和磁盤(pán)速度之間的鴻溝,基于磁盤(pán)的數(shù)據(jù)庫(kù)系統(tǒng)常使用緩沖池技術(shù)來(lái)提高數(shù)據(jù)庫(kù)整體性能。
InnoDB內(nèi)存數(shù)據(jù)對(duì)象

? ? ?緩沖池通過(guò)內(nèi)存的速度來(lái)彌補(bǔ)磁盤(pán)速度較慢對(duì)數(shù)據(jù)庫(kù)性能的影響:

①讀操作,將從磁盤(pán)讀到的頁(yè)存放在緩沖池中,下一次再讀相同頁(yè)時(shí),首先判斷該頁(yè)是否在緩沖池中,若在,稱(chēng)該頁(yè)在緩沖池中被命中,直接讀取該頁(yè),否則,讀取磁盤(pán)上的頁(yè)。
②寫(xiě)操作,首先修改緩沖池中的頁(yè),然后再以一定的頻率刷新到磁盤(pán)上。不過(guò)頁(yè)刷新回磁盤(pán)的操作并不是每次頁(yè)發(fā)生更新時(shí)觸發(fā)的,而是通過(guò)一種成為CheckPoint的機(jī)制刷新回磁盤(pán)。

? ? ?從InnoDB 1.0.x版本開(kāi)始,允許有多個(gè)緩沖池實(shí)例 (innodb_buffer_pool_instance, 默認(rèn)值為1)。每個(gè)頁(yè)根據(jù)哈希值平均分配到不同的緩沖池實(shí)例中,這樣減少了數(shù)據(jù)庫(kù)內(nèi)部資源的競(jìng)爭(zhēng),增加數(shù)據(jù)庫(kù)的并發(fā)處理能力。

  • LRU List
    ? ? ?在InnoDB存儲(chǔ)引擎中,緩沖池中頁(yè)的大小默認(rèn)為16KB,通過(guò)LRU(Latest Recent Used,最近最少使用)算法來(lái)進(jìn)行管理。即最頻繁使用的頁(yè)在LRU列表的前端,而最少使用的頁(yè)在LRU列表的尾端。當(dāng)緩沖池不能存放新讀取到的頁(yè)時(shí),將首先釋放列表中尾端的頁(yè)。
    ? ? ?InnoDB存儲(chǔ)引擎在傳統(tǒng)的LRU算法上做了優(yōu)化,在LRU列表中加入了midpoint參數(shù),新讀取到的頁(yè),不直接放入到LRU列表的首部,而是放到midpoint位置(默認(rèn)列表的5/8處)。通過(guò)innodb_old_blocks_time參數(shù),表示頁(yè)讀取到mid位置后需要等待多久才會(huì)被加入到LRU列表的熱端。

  • Free List
    ? ? ?當(dāng)數(shù)據(jù)庫(kù)剛啟動(dòng)時(shí),LRU列表為空,這時(shí)頁(yè)都存放在Free List中。當(dāng)需要從緩沖池中分頁(yè)時(shí),首先從Free列表中查找是否有可用的空閑頁(yè),若有則將該頁(yè)從Free列表中刪除,放入到LRU列表中。否則,根據(jù)LRU算法,淘汰LRU列表末尾的頁(yè),將該內(nèi)存空間分配給新的頁(yè)。

  • Flush List(臟頁(yè)列表)
    ? ? ?在LRU列表中的頁(yè)被修改后,該頁(yè)稱(chēng)為臟頁(yè)(dirty page),即緩沖池中的頁(yè)和磁盤(pán)上的頁(yè)的數(shù)據(jù)產(chǎn)生了不一致。這是數(shù)據(jù)庫(kù)會(huì)通過(guò)CHECKPOINT機(jī)制將臟頁(yè)刷新回磁盤(pán),而Flush列表中的頁(yè)即為臟頁(yè)列表。臟頁(yè)即存在于LRU列表中,也存在于Flush列表中。LRU列表用于管理緩沖池中頁(yè)的可用性,F(xiàn)lush列表用來(lái)管理頁(yè)刷新回磁盤(pán),兩者互不影響。

  • 重做日志緩沖(redo log buffer)
    ? ? ?InnoDB存儲(chǔ)引擎首先將重做日志信息放入到此緩沖區(qū),然后以一定頻率將其刷新到日志文件。其大小由參數(shù)innodb_log_buffer_size控制,默認(rèn)為8Mb。在下列三種情況下,會(huì)將重做日志文件緩沖中的內(nèi)容刷新到外部磁盤(pán)的重做日志文件:
    ①M(fèi)aster Thread每一秒將重做日志緩沖刷新到日志文件;
    ②每個(gè)事務(wù)提交時(shí)會(huì)將重做日志緩沖刷新到日志文件;
    ③當(dāng)重做日志緩沖池剩余空間小于1/2時(shí),將重做日志緩沖刷新到日志文件。

  • 額外的內(nèi)存池
    ? ? ?在InnoDB存儲(chǔ)引擎中,對(duì)內(nèi)存的管理時(shí)通過(guò)內(nèi)存堆的方式進(jìn)行的。在對(duì)一些數(shù)據(jù)結(jié)構(gòu)本身的內(nèi)存進(jìn)行分配時(shí),需要從額外的內(nèi)存池中進(jìn)行申請(qǐng),當(dāng)此區(qū)域內(nèi)存不夠時(shí),會(huì)向緩沖池申請(qǐng),如:幀緩充、緩沖控制對(duì)象(記錄了LRU、鎖、等待等信息)。

2.CheckPoint技術(shù)

? ? ?若每次頁(yè)發(fā)生變化,就將新頁(yè)刷新到磁盤(pán),開(kāi)銷(xiāo)很大,或者若在將新頁(yè)刷新到磁盤(pán)時(shí)發(fā)生了宕機(jī),那么數(shù)據(jù)就無(wú)法恢復(fù)了。因此當(dāng)前事務(wù)數(shù)據(jù)庫(kù)系統(tǒng)采用Write Ahead log策略,即當(dāng)事務(wù)提交時(shí),先寫(xiě)重做日志,再修改頁(yè)。但是當(dāng)數(shù)據(jù)庫(kù)運(yùn)行足夠久時(shí),就算有重做日志,宕機(jī)后數(shù)據(jù)庫(kù)的恢復(fù)時(shí)間也會(huì)很久,因此CheckPoint技術(shù)的目的是解決一下幾個(gè)問(wèn)題:

  • 縮短數(shù)據(jù)庫(kù)的恢復(fù)時(shí)間:當(dāng)數(shù)據(jù)庫(kù)發(fā)生宕機(jī)時(shí),不需要重做所有的日志,CheckPoint之前的頁(yè)都已經(jīng)刷新回磁盤(pán)了;
  • 緩沖池不夠用時(shí),將臟頁(yè)刷新到磁盤(pán):此時(shí)根據(jù)LRU算法會(huì)溢出最近最少使用的頁(yè),若此頁(yè)為臟頁(yè),需強(qiáng)制執(zhí)行CheckPoint,將臟頁(yè)(新頁(yè))刷新到磁盤(pán);
  • 重做日志不可用時(shí),刷新臟頁(yè):當(dāng)前重做日志時(shí)循環(huán)使用的,可重用的重做日志部分是指這部分已經(jīng)不需要,即發(fā)生宕機(jī)時(shí),恢復(fù)數(shù)據(jù)庫(kù)不需要這部分重做日志,因此可以覆蓋重用。而若此時(shí)重做日志還需要使用,必須強(qiáng)制產(chǎn)生CheckPoint,將緩沖池中的頁(yè)至少刷新到當(dāng)前重做日志的位置。

并發(fā)控制

1)讀寫(xiě)鎖
? ? ? 在處理并發(fā)讀或者寫(xiě)時(shí),可以通過(guò)實(shí)現(xiàn)一個(gè)由兩種類(lèi)型組成的鎖系統(tǒng)來(lái)解決問(wèn)題,這兩種類(lèi)型的鎖通常被成為共享鎖和排他鎖,也叫讀鎖和寫(xiě)鎖。
? ? ?讀鎖是共享的,相互不阻塞;寫(xiě)鎖是排他的,寫(xiě)鎖會(huì)阻塞其他寫(xiě)鎖和讀鎖
2)鎖粒度
? ? ? 只鎖定會(huì)修改的數(shù)據(jù)片,鎖定的數(shù)據(jù)量越少,則系統(tǒng)的并發(fā)程度越高,只要相互之間不發(fā)生沖突即可。但加鎖也需要消耗資源,包括獲得鎖、檢查鎖是否解除、釋放鎖等都會(huì)增加系統(tǒng)的開(kāi)銷(xiāo)。
? ? ?a.表鎖,開(kāi)銷(xiāo)最小,粒度最大,鎖定整張表,對(duì)該表的寫(xiě)操作會(huì)阻塞其他用戶的讀寫(xiě)操作(MyISAM)
? ? ? b.行鎖,粒度最小,最大程度支持并發(fā)(InnoDB)
? ? ? 隱式和顯式鎖定:InnoDB會(huì)根據(jù)隔離級(jí)別在需要的時(shí)候自動(dòng)加鎖,在事務(wù)執(zhí)行過(guò)程中,隨時(shí)都可以執(zhí)行鎖定,鎖只有在執(zhí)行Commit/RollBack 的時(shí)候才會(huì)釋放。在SQL后加入Lock table、Unlock table來(lái)對(duì)表進(jìn)行顯式鎖定。
3)多版本并發(fā)控制(MVCC)
? ? ? 通過(guò)保存數(shù)據(jù)在某個(gè)時(shí)間的快照來(lái)實(shí)現(xiàn),典型的有樂(lè)觀和悲觀并發(fā)控制,只在可重復(fù)讀和提交讀兩個(gè)隔離級(jí)別下工作。InnoDB的MVCC是通過(guò)在每行記錄后門(mén)保存兩個(gè)隱藏列來(lái)實(shí)現(xiàn),一列保存行創(chuàng)建時(shí)間,一列保存行過(guò)期時(shí)間(刪除時(shí)間)。并通過(guò)間隙鎖策略防止幻讀,間隙鎖使得InnoDB不僅僅鎖定查詢涉及的行,還會(huì)對(duì)索引中的間隙進(jìn)行鎖定。

2.事務(wù)

? ? ? ?一組原子性的SQL查詢或者一個(gè)單獨(dú)的工作單元。事務(wù)內(nèi)的語(yǔ)句,要么全部執(zhí)行,要么全部執(zhí)行失敗。
(1)事務(wù)屬性(ACID)
? ? ? ?A-atomicity 原子性,一個(gè)事務(wù)必須被視為一個(gè)不可分割的最小工作單元,事務(wù)的操作要么全部提交成功,要么全部失敗并回滾;
? ? ? ?C-consistency 一致性,數(shù)據(jù)庫(kù)總是從一個(gè)一致性狀態(tài)轉(zhuǎn)換到另一個(gè)一致性狀態(tài);
? ? ? ?I-isolation 隔離性,事務(wù)所做的修改在最終提交之前對(duì)其他事務(wù)通常是不可見(jiàn)的;
? ? ? ?D-durability 持久性,事務(wù)一經(jīng)提交,所修改的數(shù)據(jù)將會(huì)永久保存在數(shù)據(jù)庫(kù)中。
(2)事務(wù)隔離級(jí)別
? ? ? ?1)未提交讀(臟讀):事務(wù)中的修改,即使沒(méi)有提交,對(duì)其他事務(wù)也都是可見(jiàn)的。若事務(wù)A已經(jīng)修改數(shù)據(jù),但未提交,而事務(wù)B讀取了修改后的數(shù)據(jù),這時(shí)事務(wù)A回滾,則發(fā)生臟讀,事務(wù)B讀取的數(shù)據(jù)無(wú)效;
? ? ? ?2)提交讀(不可重復(fù)讀):事務(wù)從開(kāi)始到提交,所做的修改對(duì)其他事務(wù)都是不可見(jiàn)。但存在不可重復(fù)讀,即同一事務(wù)中兩次同樣的查詢結(jié)果不一致;
? ? ? ?3)可重復(fù)讀(幻讀):MySQL默認(rèn)事務(wù)隔離級(jí)別,保證在同一個(gè)事務(wù)中多次讀取同樣記錄的結(jié)果是一致的。但未解決幻讀,即當(dāng)事務(wù)A在讀取某個(gè)范圍內(nèi)的記錄時(shí),事務(wù)B又在該范圍插入新的記錄,事務(wù)A再次讀取該范圍的記錄時(shí),會(huì)產(chǎn)生幻讀。
? ? ? ?4)可串行化:最高隔離級(jí)別,強(qiáng)制事務(wù)串行執(zhí)行
(3)事務(wù)日志
? ? ? ?在修改表的數(shù)據(jù)時(shí)只需要修改其內(nèi)存拷貝,再把該修改行為記錄到持久在硬盤(pán)的事務(wù)日志中,而不用每次都將修改的數(shù)據(jù)本身持久到磁盤(pán)。事務(wù)日志采用追加方式,因此寫(xiě)日志的操作是磁盤(pán)上一小塊區(qū)域的順序I/O,而不像隨機(jī)I/O需要在磁盤(pán)多處移動(dòng)磁頭。

4.優(yōu)化的數(shù)據(jù)類(lèi)型

1)更小的通常更好,盡量使用可以正確存儲(chǔ)數(shù)據(jù)的最小數(shù)據(jù)類(lèi)型;
2)簡(jiǎn)單就好,簡(jiǎn)單數(shù)據(jù)類(lèi)型操作通常需要更少的CPU周期;
3)盡量避免NULL

5.索引

索引對(duì)多個(gè)值進(jìn)行排序的依據(jù)是定義索引時(shí)列的順序;

  1. B-Tree索引,按照順序存儲(chǔ)數(shù)據(jù),適用于全值匹配、鍵值范圍或鍵前綴查找,其中鍵前綴查找只適用于根據(jù)最左前綴的查找;

  2. 哈希索引,只有精確匹配索引所有列的查詢才有效。缺陷:無(wú)法排序,不支持部分索引列匹配查詢,只支持等值比較查詢;

  3. 空間數(shù)據(jù)索引(R-Tree),無(wú)需前綴查詢,從所有維度來(lái)索引數(shù)據(jù);

  4. 全文索引,查找文本中的關(guān)鍵詞,可在相同列上同時(shí)創(chuàng)建全文索引和B-Tree索引;

高效索引策略

  1. 獨(dú)立的列,索引列不能是表達(dá)式的一部分,也不能是函數(shù)的參數(shù),應(yīng)將索引列單獨(dú)放在比較符號(hào)的一側(cè);

  2. 前綴索引和索引選擇性,若需要索引很長(zhǎng)的字符串列,可以通過(guò)模擬哈希索引或者索引開(kāi)始的部分字符,索引選擇性值不重復(fù)的索引值與記錄總數(shù)的比值,選擇性越高查詢效率越高;

  3. 多列索引,“索引合并”可以使用表上的多個(gè)單列索引來(lái)定位指定的行,但索引合并往往意味著索引建得很糟糕,通過(guò)需要一個(gè)包含所有相關(guān)列的多列索引而不是多個(gè)獨(dú)立索引列;

  4. 聚簇索引,一種數(shù)據(jù)存儲(chǔ)方式,InnoDB的聚簇索引實(shí)際上是將數(shù)據(jù)放在索引的葉子頁(yè)中,其聚簇索引列為主鍵列,只聚集在同一個(gè)頁(yè)面中的記錄(緊湊存儲(chǔ))
    優(yōu)點(diǎn):相關(guān)數(shù)據(jù)被連續(xù)存放在一起,能夠減少隨機(jī)IO;數(shù)據(jù)訪問(wèn)更快;
    缺點(diǎn):插入速度依賴于插入順序,按照主鍵順序插入速度最快;更新聚簇索引列代價(jià)很高,主鍵更新/插入新行可能面臨“頁(yè)分裂”問(wèn)題;可能導(dǎo)致全表掃描變慢;二級(jí)索引更大,因?yàn)槎?jí)索引葉子節(jié)點(diǎn)保存的是行的主鍵值,需要二次索引查找;

  5. 覆蓋索引,一個(gè)索引包含所有需要查詢的字段的值,也就是通過(guò)多列索引,將需要查詢的列都放進(jìn)索引,使一個(gè)索引包含了查詢所需的所有字段,這樣就不需要回表進(jìn)行二次查詢;

  6. 使用索引掃描來(lái)進(jìn)行排序,只有當(dāng)索引的列順序和ORDER BY子句的順序完全一致,并且所有列的排序方向都一樣時(shí),MySQL才能使用索引來(lái)對(duì)結(jié)果進(jìn)行排序;

6. 數(shù)據(jù)庫(kù)三范式

  1. 1NF(第一范式),符合1NF的關(guān)系中的每個(gè)屬性都不可再分,每個(gè)數(shù)據(jù)庫(kù)表中的每一列都是不可分割的基本數(shù)據(jù)項(xiàng),同一列中不能有多個(gè)值;
  2. 2NF(第二范式),2NF是在1NF的基礎(chǔ)上,消除了非主屬性對(duì)于碼的部分函數(shù)依賴,要求數(shù)據(jù)庫(kù)表中的每個(gè)實(shí)例或行必須被唯一區(qū)分;
  3. 3NF(第三范式),3NF在2NF的基礎(chǔ)上,消除了非主屬性對(duì)于碼的傳遞依賴;

7. 查詢執(zhí)行的流程

  1. 客戶端發(fā)送一條查詢給服務(wù)器,MySQL客戶端和服務(wù)器之間的通信協(xié)議是“半雙工”的;
  2. 通過(guò)對(duì)大小寫(xiě)敏感的哈希查找,檢查緩存命中,若命中則檢查權(quán)限后返回緩存值,整個(gè)過(guò)程無(wú)需解析SQL語(yǔ)句;
  3. 服務(wù)器端通過(guò)關(guān)鍵字對(duì)SQL解析生成解析樹(shù),并使用MySQL語(yǔ)法規(guī)則驗(yàn)證和解析查詢、預(yù)處理驗(yàn)證權(quán)限并進(jìn)一步驗(yàn)證解析樹(shù)是否合理,再由優(yōu)化器生成對(duì)應(yīng)的執(zhí)行計(jì)劃;
    ? ? ? ?MySQL能夠處理的優(yōu)化類(lèi)型:重新定義關(guān)聯(lián)表的順序;將外連接轉(zhuǎn)化為內(nèi)連接;使用等價(jià)變換原則,可以減少合并一些比較;優(yōu)化COUNT()、MIN()和MAX();預(yù)估并轉(zhuǎn)換為常數(shù)表達(dá)式;覆蓋索引掃描;子查詢優(yōu)化;提前終止查詢;等值傳播
  4. MySQL根據(jù)優(yōu)化器生成的執(zhí)行計(jì)劃,調(diào)用存儲(chǔ)引擎的API來(lái)執(zhí)行查詢;
  5. 將結(jié)果返回給客戶端;

8. SQL中各種JOIN的區(qū)別

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容