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

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

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

一、行 有哪些格式?

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

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

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

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

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

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

二、緊湊的行格式長啥樣?

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

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

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

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

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

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

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

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

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

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

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

假如encode=utf8時三個byte表示一個字符。那么65535 / 3 = 21845個字符。

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

MySQL每次進行隨機的IO讀

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

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

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

如下圖:

看到這里來龍去脈是不是很清晰了呢?

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

五、什么是行溢出?

那什么是行溢出呢?

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

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

也就是說,假如你要存儲的數(shù)據(jù)行很大超過了65532byte那么你是寫入不進去的。假如你要存儲的單行數(shù)據(jù)小于65535byte但是大于16384byte,這時你可以成功insert,但是一個數(shù)據(jù)頁又存儲不了你插入的數(shù)據(jù)。這時肯定會行溢出!

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

對于varchar、text等類型的行。當這種列存儲的長度達到幾百byte時就會發(fā)生行溢。

六、行 如何溢出?

還是看這張圖:

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

七、思考一個問題

不知道你有沒有想過這樣一個問題:

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

那當單行存不下的時候,為啥不存儲在兩個數(shù)據(jù)頁中呢?就像下圖這樣~。

單個節(jié)點存儲下,我用多個節(jié)點存總行吧!說不定這樣我的B+Tee還能變大長高(這其實是錯誤的想法)

這個錯誤的描述對應(yīng)的腦圖如下:

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

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

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

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

正確的腦圖如下:

參考:

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

作者: 賜我白日夢

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

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

相關(guān)文章

  • MySQL常用的日期時間函數(shù)匯總(附實例)

    MySQL常用的日期時間函數(shù)匯總(附實例)

    日期時間處理對大家來說應(yīng)該都不陌生了,下面這篇文章主要給大家介紹了關(guān)于MySQL常用的日期時間函數(shù),文中通過圖文介紹的非常詳細,對大家學(xué)習或者使用mysql具有一定的參考學(xué)習價值,需要的朋友可以參考下
    2023-03-03
  • windows無法啟動MySQL服務(wù)報錯1067的解決方法

    windows無法啟動MySQL服務(wù)報錯1067的解決方法

    這篇文章主要為大家詳細介紹了windows無法啟動MySQL服務(wù)報錯1067的3種解決方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-01-01
  • MySQL將多條數(shù)據(jù)合并成一條的完整代碼示例

    MySQL將多條數(shù)據(jù)合并成一條的完整代碼示例

    我們在操作數(shù)據(jù)的時候,有時候需要把多行數(shù)據(jù),拼接成一行,下面這篇文章主要給大家介紹了關(guān)于MySQL將多條數(shù)據(jù)合并成一條的完整代碼示例,文中通過圖文介紹的非常詳細,需要的朋友可以參考下
    2024-05-05
  • MySQL索引背后的數(shù)據(jù)結(jié)構(gòu)及算法原理詳解

    MySQL索引背后的數(shù)據(jù)結(jié)構(gòu)及算法原理詳解

    本文以MySQL數(shù)據(jù)庫為研究對象,討論與數(shù)據(jù)庫索引相關(guān)的一些話題。特別需要說明的是,MySQL支持諸多存儲引擎,而各種存儲引擎對索引的支持也各不相同,因此MySQL數(shù)據(jù)庫支持多種索引類型,如BTree索引,哈希索引,全文索引等等
    2016-12-12
  • Mysql查詢所有表和字段信息的方法

    Mysql查詢所有表和字段信息的方法

    這篇文章主要介紹了Mysql查詢所有表和字段信息,本文給大家介紹的非常詳細,對大家的學(xué)習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-04-04
  • Mysql用戶創(chuàng)建以及權(quán)限賦予操作的實現(xiàn)

    Mysql用戶創(chuàng)建以及權(quán)限賦予操作的實現(xiàn)

    在MySQL中,創(chuàng)建新用戶并為其授予權(quán)限是一項常見的操作,本文主要介紹了Mysql用戶創(chuàng)建以及權(quán)限賦予操作的實現(xiàn),具有一定的參考價值,感興趣的可以了解一下
    2023-10-10
  • MySQL數(shù)據(jù)庫下用戶及用戶權(quán)限配置

    MySQL數(shù)據(jù)庫下用戶及用戶權(quán)限配置

    這篇文章主要介紹了MySQL數(shù)據(jù)庫下用戶及用戶權(quán)限配置的相關(guān)資料,非常不錯,具有參考借鑒價值,需要的朋友可以參考下
    2016-08-08
  • Mysql5.5 InnoDB存儲引擎配置和優(yōu)化

    Mysql5.5 InnoDB存儲引擎配置和優(yōu)化

    本文介紹一下Mysql5.5 InnoDB存儲引擎配置和優(yōu)化的方法
    2013-11-11
  • mysql詳細分析講解子查詢的使用

    mysql詳細分析講解子查詢的使用

    子查詢指一個查詢語句嵌套在另一個查詢語句內(nèi)部的查詢,這個特性從 MySQL 4.1開始引入,在SELECT子句中先計算子查詢,子查詢結(jié)果作為外層另一個查詢的過濾條件,查詢可以基于一個表或者多個表
    2022-04-04
  • Mysql 命令行模式訪問操作mysql數(shù)據(jù)庫操作

    Mysql 命令行模式訪問操作mysql數(shù)據(jù)庫操作

    這篇文章主要介紹了Mysql 命令行模式訪問操作mysql數(shù)據(jù)庫操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-08-08

最新評論

永新县| 浪卡子县| 扎赉特旗| 龙江县| 湄潭县| 大港区| 唐海县| 东城区| 宿州市| 赤水市| 定结县| 马关县| 泸西县| 巴南区| 镇康县| 巨鹿县| 本溪| 犍为县| 城市| 仙居县| 华阴市| 建湖县| 信丰县| 陈巴尔虎旗| 禄丰县| 水富县| 蒙阴县| 牙克石市| 台山市| 东明县| 大足县| 丰顺县| 潼关县| 公安县| 海南省| 霍林郭勒市| 富川| 镇沅| 五常市| 广汉市| 城固县|