存储引擎-存储结构之一:行
周未電影推薦:
《小時代》:講述四位女生步入社會所面臨的各種情感,生存問題。播放地址:http://947kan.com/movie/juqing/51068/
SQLServer中,數(shù)據(jù)的存儲是按記錄行來存儲的,每一行包含數(shù)據(jù)的所有的列,這樣的存儲,是非常有利數(shù)據(jù)的查詢的,
但也正因為如此,LOB頁,行溢出頁,表結(jié)構(gòu)修改都極易產(chǎn)生空洞,形成磁盤碎片。
我們做個例子分析下:
測試范圍->沒有聚集索引,沒有非聚集索引,含有定長列和變長列的堆
/*
Slot 0, Offset 0x60, Length 44, DumpStyle BYTE
Record Type = PRIMARY_RECORD???????? Record Attributes =? NULL_BITMAP VARIABLE_COLUMNS
Record Size = 44??????????????????? ?
Memory Dump @0x000000000FFEA060
0000000000000000:?? 30001a00 01000000 00000000 3a9d0000 ?0...........:...
0000000000000010:?? 31323320 20202020 20200500 00020026 ?123?????? .....&
0000000000000020:?? 002c0041 42436100 62006300 ??????????.,.ABCa.b.c.????
*/
| 記錄行 | 狀態(tài)位A | 狀態(tài)位B | 列偏移 | 定長數(shù)據(jù) | 表總列數(shù) | NULL位圖 | 變長列的數(shù)目 | 第一變長列數(shù)據(jù)終止位置 | 第二變長列數(shù)據(jù)終止位置 | 第一列變長列的數(shù)據(jù) | 第二列變長列的數(shù)據(jù) | ? |
| 值 | 0x30 | 0x00 | 0x1a00 | 0x01000000-2020 2020 | 0x0500 | 0x00 | 0x0200 | 0x2600 | 0x2c00 | 0x41 4243 | 0x6100 62006300 | ? |
| 說明 | 00110000 行屬性 | 未啟用 | =26 | 定長數(shù)據(jù)部分 (col1,col3,col4) | =5 | 0 | =2 | =38 | =44 | ='ABC' | ='abc' | ? |
解釋:
狀態(tài)位A:行屬性的位圖 從高位存到地位(右邊第一位是bit0).
bit0:版本信息,SQL2005/08總是為
bit1-3: 0=(primary record);1=(forwarded record);2=(forwarding stud);3=(index record);4=(溢出數(shù)據(jù));5=(ghost索引記錄);6=(ghost數(shù)據(jù)記錄)
bit4:表示存在NULL位圖(在數(shù)據(jù)行里SQL2005/08總存在NULL位圖)
bit5:表示存在變長列
bit6:未啟用
bit7:表示存在幽靈記錄
?
定長數(shù)據(jù)部分(col1,col3,col4):
01000000->00000000 00000000 00000000 00000001=1<col1的值,4字節(jié)>
00000000 3a9d0000->1001110100111010 0...0 =40250 <col3值,8字節(jié)>
31323320 20202020 2020->'123??? ???'<col4的值,char(10),10字節(jié)>
ps:注意這里的col3的類型是datetime類型,這個類型在內(nèi)部存貯并不是你們想象的那樣.
?? 我簡單來說就是它將這個類型的存儲分成個部分,date部分和time部分
?? 我們的例子中 表示的時間部分,3a9d0000表示的時候date部分
?? 因為第一部分time默認(rèn)是:00:00 所以值為 3a9d0000換算成十進制為
? ?你可以通過
select CONVERT(int,SUBSTRING(CONVERT(varbinary(8),cast('2013-07-14' as datetime)),1,4)),--40250CONVERT(int,SUBSTRING(CONVERT(varbinary(8),cast('2013-07-14' as datetime)),5,4))—0?
0500->00000000 00000101=5 表示該表有列
00->00000000 因為該表只有列 所以只需要看后面?zhèn)€,0表示該行的對應(yīng)列不為NULL
0200->00000000 00000010=2 表示該表有列 (col2,col5)
2600->00000000 00100110=38=1+1+2+(4+8+10)+2+ceiling(5/8)+2+2+2+len('ABC')
2c00->00000000 00101100=44 因為一共就列變長列 所以它的結(jié)束位置就是行的最終長度 LENGTH 44
41 4243->01000001 01000010 01000011='ABC'
6100 62006300->01100001 00..00 01100010 00..00 01100011 00..00='abc' 這里用六個字節(jié)是因為它是NVARCHAR類型 2個字節(jié)才能存一個字符
轉(zhuǎn)載于:https://www.cnblogs.com/lwqhp/p/3189198.html
總結(jié)
以上是生活随笔為你收集整理的存储引擎-存储结构之一:行的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 商品房买卖合同备案
- 下一篇: PL/pgSQL的anyelement例