最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊(cè)

25 對(duì)于VARCHAR這種變長字段,在磁盤上到底是如何存儲(chǔ)的?

2023-06-20 10:45 作者:儒猿課堂  | 我要投稿

對(duì)于VARCHAR這種變長字段,在磁盤上到底是如何存儲(chǔ)的?


1、一行數(shù)據(jù)在磁盤上存儲(chǔ)的時(shí)候,包含哪些東西?


上一講我們已經(jīng)告訴了大家,一行數(shù)據(jù)在磁盤上存儲(chǔ)的時(shí)候,其實(shí)不僅僅是包含我們想象的那一點(diǎn)數(shù)據(jù),他還包含了很多其他的信息,之前告訴大家,一行數(shù)據(jù)的存儲(chǔ)格式大致如下所示。


變長字段的長度列表,null值列表,數(shù)據(jù)頭,column01的值,column02的值,column0n的值......


說白了,就是除了每一個(gè)字段的值以外,他還包含了一些額外的信息,這些額外的信息就是用來描述這一行數(shù)據(jù)的。今天我們就詳細(xì)給大家說說這些額外的信息里都是放了什么東西。


2、變長字段在磁盤中是怎么存儲(chǔ)的?


大家都知道,在MySQL里有一些字段的長度是變長的,是不固定的,比如VARCHAR(10)之類的這種類型的字段,實(shí)際上他里面存放的字符串的長度是不固定的,有可能是“hello”這么一個(gè)字符串,也可能是“a”這么一個(gè)字符串。


好,那么現(xiàn)在我們來假設(shè)一下,現(xiàn)在有一行數(shù)據(jù),他的幾個(gè)字段的類型為VRACHAR(10),CHAR(1),CHAR(1),那么他第一個(gè)字段是VARCHAR(10),這個(gè)長度是可能變化的,所以這一行數(shù)據(jù)可能就是類似于:hello a a,這樣子,第一個(gè)字段的值是“hello”,后面兩個(gè)字段的值都是一個(gè)字符,就是一個(gè)a


然后另外一行數(shù)據(jù),同樣也是這幾個(gè)字段,他的第一個(gè)字段的值可能是“hi”,后面兩個(gè)字段也是“a”,所以這一行數(shù)據(jù)可能是類似于:hi a a。一共三個(gè)字段,第一個(gè)字段的長度是是不固定的,后面兩個(gè)字段的長度都是固定的1個(gè)字符。


想必這個(gè)道理大家都能理解吧?


那么現(xiàn)在,我們來假設(shè)你把上述兩條數(shù)據(jù)寫入了一個(gè)磁盤文件里,兩行數(shù)據(jù)是挨在一起的,那么這個(gè)時(shí)候在一個(gè)磁盤文件里可能有下面的兩行數(shù)據(jù):


hello a a hi a a


大家可以看到,兩行數(shù)據(jù)在底層磁盤文件里是不是挨著存儲(chǔ)的?


沒錯(cuò)!其實(shí)平時(shí)你看到的表里的很多行數(shù)據(jù),最終落地到磁盤里的時(shí)候,都是上面那種樣子的,一大坨數(shù)據(jù)放在一個(gè)磁盤文件里都挨著存儲(chǔ)的。


3、存儲(chǔ)在磁盤文件里的變長字段,為什么難以讀???


現(xiàn)在我們來繼續(xù)思考一個(gè)問題,假設(shè)現(xiàn)在我們要讀取上面的磁盤文件里的數(shù)據(jù),要讀取出來hello a a這一行數(shù)據(jù)。那你覺得是那么容易的嗎?


當(dāng)然不是了!這個(gè)過程比你想象的可能要困難一些。


假如現(xiàn)在你要讀取hello a a這行數(shù)據(jù),第一個(gè)問題就是,從這個(gè)磁盤文件里讀取的時(shí)候,到底哪些內(nèi)容是一行數(shù)據(jù)?我不知道??!


因?yàn)檫@個(gè)表里的第一個(gè)字段是VARCHAR(10)類型的,第一個(gè)字段的長度是多少我們是不知道的!


所以有可能你讀取出來“hello a a hi”是一行數(shù)據(jù),也可能是你讀取出來“hello a”是一行數(shù)據(jù),你在不知道一行數(shù)據(jù)的每個(gè)字段到底是多少長度的情況下,胡亂的去讀取是不現(xiàn)實(shí)的,根本不知道磁盤文件里混成一坨的數(shù)據(jù)里,哪些數(shù)據(jù)是你要讀取的一行?


4、引入變長字段的長度列表,解決一行數(shù)據(jù)的讀取問題


所以說才要在存儲(chǔ)每一行數(shù)據(jù)的時(shí)候,都保存一下他的變長字段的長度列表,這樣才能解決一行數(shù)據(jù)的讀取問題。


也就是說,你在存儲(chǔ)“hello a a”這行數(shù)據(jù)的時(shí)候,要帶上一些額外的附加信息,比如第一塊就是他里面的變長字段的長度列表


也就是說,這個(gè)hello是VARCHAR(10)類型的變長字段的值,那么這個(gè)“hello”字段值的長度到底是多少?


我們看到“hello”的長度是5,十六進(jìn)制就是0x05,所以此時(shí)會(huì)在“hello a a”前面補(bǔ)充一些額外信息,首先就是變長字段的長度列表,你會(huì)看到這行數(shù)據(jù)在磁盤文件里存儲(chǔ)的時(shí)候,其實(shí)是類似如下的格式:0x05 null值列表 數(shù)據(jù)頭 hello a a。


你這行數(shù)據(jù)存儲(chǔ)的時(shí)候應(yīng)該是如上所示的!


這個(gè)時(shí)候假設(shè)你有兩行數(shù)據(jù),還有一行數(shù)據(jù)可能就是:0x02 null值列表 數(shù)據(jù)頭 hi a a,兩行數(shù)據(jù)放在一起存儲(chǔ)在磁盤文件里,看起來是如下所示的:


0x05 null值列表 數(shù)據(jù)頭 hello a a 0x02 null值列表 數(shù)據(jù)頭 hi a a


5、引入變長字段長度列表后,如何解決變長字段的讀取問題?


所以假設(shè)此時(shí)你要讀取“hello a a”這行數(shù)據(jù),你首先會(huì)知道這個(gè)表里的三個(gè)字段的類型是VARCHAR(10) CHAR(1) CHAR(1),那么此時(shí)你先要讀取第一個(gè)字段的值,那么第一個(gè)字段是變長的,到底他的實(shí)際長度是多少呢?


此時(shí)你會(huì)發(fā)現(xiàn)第一行數(shù)據(jù)的開頭有一個(gè)變長字段的長度列表,里面會(huì)讀取到一個(gè)0x05這個(gè)十六進(jìn)制的數(shù)字,發(fā)現(xiàn)第一個(gè)變長字段的長度是5,于是按照長度為5,讀取出來第一個(gè)字段的值,就是“hello”


接著你知道后續(xù)兩個(gè)字段都是CHAR(1),長度都是固定的1個(gè)字符,于是此時(shí)就依次按照長度為1讀取出來后續(xù)兩個(gè)字段的值,分別是“a”“a”,于是最終你會(huì)讀取出來“hello a a”這一行數(shù)據(jù)!


接著假設(shè)你要讀取第二行數(shù)據(jù),你先看一下第二行數(shù)據(jù)后的變長字段長度列表,發(fā)現(xiàn)他第一個(gè)變長字段的長度是0x02,于是就讀取長度為2的字段值,就是“hi”,再讀取兩個(gè)長度固定為1的字符值,都是“a”,此時(shí)讀取出來“hi a a”這行數(shù)據(jù)。


6、如果有多個(gè)變長字段,如何存放他們的長度?


接著我們假設(shè),如果說有多個(gè)變長字段,如何存放他們的長度?


比如一行數(shù)據(jù)有VARCHAR(10) VARCHAR(5) VARCHAR(20) CHAR(1) CHAR(1),一共5個(gè)字段,其中三個(gè)是變長字段,此時(shí)假設(shè)一行數(shù)據(jù)是這樣的:hello hi hao a a


此時(shí)在磁盤中存儲(chǔ)的,必須在他開頭的變長字段長度列表中存儲(chǔ)幾個(gè)變長字段的長度,一定要注意一點(diǎn),他這里是逆序存儲(chǔ)的!


也就是說先存放VARCHAR(20)這個(gè)字段的長度,然后存放VARCHAR(5)這個(gè)字段的長度,最后存放VARCHAR(10)這個(gè)字段的長度。


現(xiàn)在hello hi hao三個(gè)字段的長度分別是0x05 0x02 0x03,但是實(shí)際存放在變長字段長度列表的時(shí)候,是逆序放的,所以一行數(shù)據(jù)實(shí)際存儲(chǔ)可能是下面這樣的:


0x03 0x02 0x05 null值列表 頭字段 hello hi hao a a


7、今日思考題


今天讓大家思考一個(gè)問題,為什么MySQL在把一行一行的數(shù)據(jù)存儲(chǔ)在磁盤上的時(shí)候,要采取這種“0x05 null值列表 數(shù)據(jù)頭 hello a a 0x02 null值列表 數(shù)據(jù)頭 hi a a”很多行數(shù)據(jù)都緊緊挨在一起的方式?


為什么MySQL不能用Java里面的序列化的那種方式?把很多行的數(shù)據(jù)做成一個(gè)大的對(duì)象,然后給他序列化一下寫入到磁盤文件里,從磁盤里讀取的時(shí)候壓根兒不用care什么行存儲(chǔ)格式,直接反序列化一下,把數(shù)據(jù)就可以從磁盤文件里拿回來了。


請(qǐng)大家思考一下,MySQL用這種數(shù)據(jù)緊湊挨在一起的方式來存儲(chǔ)數(shù)據(jù),到底有什么好處?可以在評(píng)論區(qū)里發(fā)表你的想法跟大家一起交流。

End


專欄版權(quán)歸公眾號(hào)儒猿技術(shù)窩所有

未經(jīng)許可不得傳播,如有侵權(quán)將追究法律責(zé)任

25 對(duì)于VARCHAR這種變長字段,在磁盤上到底是如何存儲(chǔ)的?的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國家法律
县级市| 株洲市| 体育| 吕梁市| 瓮安县| 灵寿县| 淮北市| 屏东县| 东丽区| 昂仁县| 安丘市| 资中县| 肇州县| 江油市| 韶山市| 福清市| 嵊泗县| 来安县| 孟连| 曲阜市| 大余县| 辛集市| 大化| 前郭尔| 龙游县| 忻州市| 富宁县| 荃湾区| 汝南县| 永仁县| 固安县| 三河市| 义乌市| 灌云县| 吉水县| 东明县| 甘德县| 淮北市| 南宁市| 乐昌市| 漯河市|