欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

詳解MySQL的數(shù)據(jù)行和行溢出機(jī)制

 更新時(shí)間:2020年11月25日 15:29:01   作者:賜我白日夢(mèng)  
在前面的文章中,白日夢(mèng)曾不止一次的提及到:InnoDB從磁盤(pán)中讀取數(shù)據(jù)的最小單位是數(shù)據(jù)頁(yè)。 而你想得到的id = xxx的數(shù)據(jù),就是這個(gè)數(shù)據(jù)頁(yè)眾多行中的一行。 這篇文章我們就一起來(lái)看一下數(shù)據(jù)行設(shè)計(jì)的多么巧妙。

一、行 有哪些格式?

你可以像下面這樣看一下你的MySQL行格式設(shè)置。

其實(shí)MySQL的數(shù)據(jù)行有兩種格式,一種就是圖中的 Compact格式,還有一種是Redundant格式。

Compact是一種緊湊的行格式,設(shè)計(jì)的初衷就是為了讓一個(gè)數(shù)據(jù)頁(yè)中可以存放更多的數(shù)據(jù)行。

你品一品,讓一個(gè)數(shù)據(jù)頁(yè)中可以存放更多的數(shù)據(jù)行是一個(gè)多么激動(dòng)人心的事,MySQL以數(shù)據(jù)頁(yè)為單位從磁盤(pán)中讀數(shù)據(jù),如果能做到讓一個(gè)數(shù)據(jù)頁(yè)中有更多的行,那豈不是使用的空間變少了,且整體的效率直線飆升?

官網(wǎng)介紹:Compact能比Redundant格式節(jié)約20%的存儲(chǔ)。

Compact從MySQL5.0引入,MySQL5.1之后,行格式默認(rèn)設(shè)置成 Compact 。所以本文描述的也是Compact格式。

二、緊湊的行格式長(zhǎng)啥樣?

你肯定曉得表中有的列允許為null,有的列是變長(zhǎng)的varchar類型。

那Compact行格式是如何組織描述這些信息的呢?如下圖:

每部分包含的數(shù)據(jù)可能要比我上面標(biāo)注的1、2、3還要多。

為了給大家更直觀的感受和理解我只是挑了一部分展示給大家看。

三、MySQL單行能存多大體量的數(shù)據(jù)?

在MySQL的設(shè)定中,單行數(shù)據(jù)最大能存儲(chǔ)65535byte的數(shù)據(jù)(注意是byte,而不是字符)

但是當(dāng)你像下面這樣創(chuàng)建一張數(shù)據(jù)表時(shí)卻發(fā)生了錯(cuò)誤:

MySQL不允許創(chuàng)建一個(gè)長(zhǎng)度為65535byte的列,因?yàn)閿?shù)據(jù)頁(yè)中每一行中都有我們上圖提到的隱藏列。

所以將varchar的長(zhǎng)度降低到65532byte即可成功創(chuàng)建該表

注意這里的65535指的是字節(jié),而不是字符。

所以如果你將charset換成utf8這種編碼格式,那varchar(N)中的N其實(shí)指的N個(gè)字符,而不是N個(gè)byte。所以如果你像下面這樣創(chuàng)建表就會(huì)報(bào)錯(cuò)。

假如encode=utf8時(shí)三個(gè)byte表示一個(gè)字符。那么65535 / 3 = 21845個(gè)字符。

四、Compact格式是如何做到緊湊的?

MySQL每次進(jìn)行隨機(jī)的IO讀

默認(rèn)情況下,數(shù)據(jù)頁(yè)的大小為16KB。數(shù)據(jù)頁(yè)中存儲(chǔ)著數(shù)行。

那就意味著一個(gè)數(shù)據(jù)頁(yè)中能存儲(chǔ)越多的數(shù)據(jù)行,MySQL整體的進(jìn)行的IO次數(shù)就越少?性能就越快?

Compact格式的實(shí)現(xiàn)思路是:當(dāng)列的類型為VARCHAR、 VARBINARY、 BLOB、TEXT時(shí),該列超過(guò)768byte的數(shù)據(jù)放到其他數(shù)據(jù)頁(yè)中去。

如下圖:

看到這里來(lái)龍去脈是不是很清晰了呢?

MySQL這樣做,有效的防止了單個(gè)varchar列或者Text列太大導(dǎo)致單個(gè)數(shù)據(jù)頁(yè)中存放的行記錄過(guò)少而讓IO飆升的窘境且占內(nèi)存的。

五、什么是行溢出?

那什么是行溢出呢?

如果數(shù)據(jù)頁(yè)默認(rèn)大小為16KB,換算成byte: 16*1024 = 16384 byte

那你有沒(méi)有發(fā)現(xiàn),單頁(yè)能存儲(chǔ)的16384byte和單行最大能存儲(chǔ)的 65535byte 差了好幾倍呢?

也就是說(shuō),假如你要存儲(chǔ)的數(shù)據(jù)行很大超過(guò)了65532byte那么你是寫(xiě)入不進(jìn)去的。假如你要存儲(chǔ)的單行數(shù)據(jù)小于65535byte但是大于16384byte,這時(shí)你可以成功insert,但是一個(gè)數(shù)據(jù)頁(yè)又存儲(chǔ)不了你插入的數(shù)據(jù)。這時(shí)肯定會(huì)行溢出!

其實(shí)在MySQL的設(shè)定中,發(fā)生行溢出并不是達(dá)到16384byte邊緣才會(huì)發(fā)生。

對(duì)于varchar、text等類型的行。當(dāng)這種列存儲(chǔ)的長(zhǎng)度達(dá)到幾百byte時(shí)就會(huì)發(fā)生行溢。

六、行 如何溢出?

還是看這張圖:

在MySQL設(shè)定中,當(dāng)varchar列長(zhǎng)度達(dá)到768byte后,會(huì)將該列的前768byte當(dāng)作當(dāng)作prefix存放在行中,多出來(lái)的數(shù)據(jù)溢出存放到溢出頁(yè)中,然后通過(guò)一個(gè)偏移量指針將兩者關(guān)聯(lián)起來(lái),這就是行溢出機(jī)制。

七、思考一個(gè)問(wèn)題

不知道你有沒(méi)有想過(guò)這樣一個(gè)問(wèn)題:

首先你肯定知道,MySQL使用的是B+Tree的聚簇索引,在這棵B+Tree中非葉子節(jié)點(diǎn)是只存索引不存數(shù)據(jù),葉子節(jié)點(diǎn)中存儲(chǔ)著真實(shí)的數(shù)據(jù)。同時(shí)葉子結(jié)點(diǎn)指向數(shù)據(jù)頁(yè)。

那當(dāng)單行存不下的時(shí)候,為啥不存儲(chǔ)在兩個(gè)數(shù)據(jù)頁(yè)中呢?就像下圖這樣~。

單個(gè)節(jié)點(diǎn)存儲(chǔ)下,我用多個(gè)節(jié)點(diǎn)存總行吧!說(shuō)不定這樣我的B+Tee還能變大長(zhǎng)高(這其實(shí)是錯(cuò)誤的想法)

這個(gè)錯(cuò)誤的描述對(duì)應(yīng)的腦圖如下:

那MySQL不這樣做的原因如下:

MySQL想讓一個(gè)數(shù)據(jù)頁(yè)中能存放更多的數(shù)據(jù)行,至少也得要存放兩行數(shù)據(jù)。否則就失去了B+Tree的意義。B+Tree也退化成一個(gè)低效的鏈表。

你可以品一下這句藍(lán)色的話,他說(shuō)的每個(gè)數(shù)據(jù)頁(yè)至少要存放兩行數(shù)據(jù)的意思不是說(shuō) 數(shù)據(jù)頁(yè)不能只存一行。你確確實(shí)實(shí)可以只往里面寫(xiě)一行數(shù)據(jù),然后去吃個(gè)飯,干點(diǎn)別的。一直讓這個(gè)數(shù)據(jù)頁(yè)中只有一行數(shù)據(jù)。

這句話的意思是,當(dāng)你往這個(gè)數(shù)據(jù)頁(yè)中寫(xiě)入一行數(shù)據(jù)時(shí),即使它很大將達(dá)到了數(shù)據(jù)頁(yè)的極限,但是通過(guò)行溢出機(jī)制。依然能保證你的下一條數(shù)據(jù)還能寫(xiě)入到這個(gè)數(shù)據(jù)頁(yè)中。

正確的腦圖如下:

參考:

https://dev.mysql.com/doc/refman/5.7/en/innodb-row-format.html

https://dev.mysql.com/doc/refman/5.7/en/column-count-limit.html

作者: 賜我白日夢(mèng)

出處:https://www.cnblogs.com/ZhuChangwu/p/14035330.html

以上就是詳解MySQL的數(shù)據(jù)行和行溢出機(jī)制的詳細(xì)內(nèi)容,更多關(guān)于MySQL 數(shù)據(jù)行和行溢出的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 深入理解MySQL數(shù)據(jù)類型的選擇優(yōu)化

    深入理解MySQL數(shù)據(jù)類型的選擇優(yōu)化

    這篇文章主要介紹了深入理解MySQL數(shù)據(jù)類型的選擇優(yōu)化,MySQL數(shù)據(jù)類型是定義列中可以存儲(chǔ)什么數(shù)據(jù)以及該數(shù)據(jù)實(shí)際怎樣存儲(chǔ)的基本規(guī)則,正確的選擇數(shù)據(jù)庫(kù)字段的字段類型對(duì)于數(shù)據(jù)庫(kù)性能有很大的影響
    2022-08-08
  • MySQL8下忘記密碼后重置密碼的辦法(MySQL老方法不靈了)

    MySQL8下忘記密碼后重置密碼的辦法(MySQL老方法不靈了)

    這篇文章主要介紹了MySQL8下忘記密碼后重置密碼的辦法,MySQL的密碼是存放在user表里面的,修改密碼其實(shí)就是修改表中記錄,重置的思路是是想辦法不用密碼進(jìn)入系統(tǒng),然后用數(shù)據(jù)庫(kù)命令修改表user中的密碼記錄
    2018-08-08
  • mysql 數(shù)據(jù)庫(kù)鏈接狀態(tài)確認(rèn)實(shí)驗(yàn)(推薦)

    mysql 數(shù)據(jù)庫(kù)鏈接狀態(tài)確認(rèn)實(shí)驗(yàn)(推薦)

    這篇文章主要介紹了mysql 數(shù)據(jù)庫(kù)鏈接狀態(tài)確認(rèn)實(shí)驗(yàn),通過(guò)本文我選擇 了三種方案給大家詳細(xì)講解,結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2022-09-09
  • 淺談MySQL的B樹(shù)索引與索引優(yōu)化小結(jié)

    淺談MySQL的B樹(shù)索引與索引優(yōu)化小結(jié)

    這篇文章主要介紹了淺談MySQL的B樹(shù)索引與索引優(yōu)化小結(jié),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-03-03
  • MySQL控制流函數(shù)(-if?,elseif,else,case...when)

    MySQL控制流函數(shù)(-if?,elseif,else,case...when)

    這篇文章主要介紹了MySQL控制流函數(shù)(-if?,elseif,else,case...when),文章圍繞主題展開(kāi)詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的朋友可以參考一下
    2022-07-07
  • Mysql基礎(chǔ)知識(shí)點(diǎn)匯總

    Mysql基礎(chǔ)知識(shí)點(diǎn)匯總

    本文給大家匯總介紹了mysql的23個(gè)基礎(chǔ)的知識(shí)點(diǎn),這些都是學(xué)習(xí)mysql的必備知識(shí),小伙伴們可以參考下。
    2015-09-09
  • MySQL服務(wù)啟動(dòng)與關(guān)閉如何操作圖文詳解

    MySQL服務(wù)啟動(dòng)與關(guān)閉如何操作圖文詳解

    這篇文章主要為大家介紹了MySQL服務(wù)啟動(dòng)與關(guān)閉如何操作圖文詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪<BR>
    2023-10-10
  • MySql學(xué)習(xí)筆記之事務(wù)隔離級(jí)別詳解

    MySql學(xué)習(xí)筆記之事務(wù)隔離級(jí)別詳解

    這篇文章主要給大家介紹了關(guān)于MySql學(xué)習(xí)筆記之事務(wù)隔離級(jí)別的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-05-05
  • insert...on?duplicate?key?update語(yǔ)法詳解

    insert...on?duplicate?key?update語(yǔ)法詳解

    本文主要介紹了insert...on?duplicate?key?update語(yǔ)法詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-01-01
  • 解決從集合運(yùn)算到mysql的not like找不出NULL的問(wèn)題

    解決從集合運(yùn)算到mysql的not like找不出NULL的問(wèn)題

    這篇文章主要介紹了解決從集合運(yùn)算到mysql的not like找不出NULL的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2021-01-01

最新評(píng)論