<span id="mktg5"></span>

<i id="mktg5"><meter id="mktg5"></meter></i>

        <label id="mktg5"><meter id="mktg5"></meter></label>
        最新文章專題視頻專題問答1問答10問答100問答1000問答2000關鍵字專題1關鍵字專題50關鍵字專題500關鍵字專題1500TAG最新視頻文章推薦1 推薦3 推薦5 推薦7 推薦9 推薦11 推薦13 推薦15 推薦17 推薦19 推薦21 推薦23 推薦25 推薦27 推薦29 推薦31 推薦33 推薦35 推薦37視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關鍵字專題關鍵字專題tag2tag3文章專題文章專題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專題3
        問答文章1 問答文章501 問答文章1001 問答文章1501 問答文章2001 問答文章2501 問答文章3001 問答文章3501 問答文章4001 問答文章4501 問答文章5001 問答文章5501 問答文章6001 問答文章6501 問答文章7001 問答文章7501 問答文章8001 問答文章8501 問答文章9001 問答文章9501
        當前位置: 首頁 - 科技 - 知識百科 - 正文

        SQLSERVER中數據行所占用的最小空間

        來源:懂視網 責編:小采 時間:2020-11-09 07:52:12
        文檔

        SQLSERVER中數據行所占用的最小空間

        SQLSERVER中數據行所占用的最小空間:數據行所占的最小空間是多少呢? 先來看看下面這張經典數據行結構圖(引自Inside Sql Server) 因為可變長度類型的列會有額外的空間開銷,所以不考慮可變長度的字段。 現在計算一下除去實際數據后每個數據行所需要占用的空間: 狀態位A占一個字節,狀態位B占
        推薦度:
        導讀SQLSERVER中數據行所占用的最小空間:數據行所占的最小空間是多少呢? 先來看看下面這張經典數據行結構圖(引自Inside Sql Server) 因為可變長度類型的列會有額外的空間開銷,所以不考慮可變長度的字段。 現在計算一下除去實際數據后每個數據行所需要占用的空間: 狀態位A占一個字節,狀態位B占

        數據行所占的最小空間是多少呢? 先來看看下面這張經典數據行結構圖(引自Inside Sql Server) 因為可變長度類型的列會有額外的空間開銷,所以不考慮可變長度的字段。 現在計算一下除去實際數據后每個數據行所需要占用的空間: 狀態位A占一個字節,狀態位B占

        數據行所占的最小空間是多少呢?

        先來看看下面這張經典數據行結構圖(引自Inside Sql Server)



        因為可變長度類型的列會有額外的空間開銷,所以不考慮可變長度的字段。 現在計算一下除去實際數據后每個數據行所需要占用的空間:

        狀態位A占一個字節,狀態位B占1個字節,用于標識固定字段長度的占2個字節,標識固定列數量的占去2個字節,NULL位圖至少占用1個字節。
        這樣算下來:1+1+2+2+1=7。 也就是在不考慮實際數據的情況下一個數據行最少要占用7個字節。如果實際數據長度為1,那么每一行所占用的空間就為8個字節。真的是這樣嗎?

        現在做個實驗驗證一下,在下文中如果沒有特殊的說明,所有的敘述都是以數據表沒有建立聚集索引為前提的。

        創建一個表:
        Create Table table1
        (
        col1 char(1)
        )

        插入2行數據:
        insertinto table11 values('a')
        insertinto table11 values('b')

        然后使用DBCC PAGE命令察看表的結構(為了方便察看,我只保留了Data和Offset Table部分)

        DATA:

        Slot 0, Offset 0x60, Length 9, DumpStyle BYTE

        Record Type = PRIMARY_RECORD Record Attributes = NULL_BITMAP

        Memory Dump @0x44EFC060

        00000000: 10000500 610100fe 08†††††††††††††††††....a....

        Slot 1, Offset 0x69, Length 9, DumpStyle BYTE

        Record Type = PRIMARY_RECORD Record Attributes = NULL_BITMAP

        Memory Dump @0x44EFC069

        00000000: 10000500 620100fe 08†††††††††††††††††....b....

        OFFSET TABLE:

        Row - Offset

        1 (0x1) - 105 (0x69)

        0 (0x0) - 96 (0x60)


        Length 后面為9,也就是說每個數據行占了9個字節,通過offset table部分我們也可以計算出每個數據行占用了9個字節。而不是我們所計算的8個字節。現在察看以下數據行到底存儲了什么內容,我們以slot0為例:

        10000500 610100fe 08†††††††††††††††††....a....

        前兩位10表示沒有可變長度的字段,后面兩位00在sqlserver 2005中沒有用到;0500表示固定長度的字段所占的長度為5(實際長度加4);61轉換為十進制數位97,表示小寫字母a。后面的0100表示固定長度的字段數量為1;剩下fe就是NULL位圖了,翻譯成2進制數為1111 1110,這說明該行中沒有字段為NULL,這和實際情況也是相符的。那么最后兩位08代表什么呢?在公開答案之前再作一個試驗


        創建一個表:
        Create Table table1
        (
        col1 char(2)
        )

        像表內插入2行數據:
        insertinto table11 values('aa')
        insertinto table11 values('bb')

        然后使用DBCC PAGE命令察看表的結構(為了方便察看,我只保留了Data和Offset Table部分)

        DATA:

        Slot 0, Offset 0x60, Length 9, DumpStyle BYTE

        Record Type = PRIMARY_RECORD Record Attributes = NULL_BITMAP

        Memory Dump @0x4500C060

        00000000: 10000600 61610100 fe†††††††††††††††††....aa...

        Slot 1, Offset 0x69, Length 9, DumpStyle BYTE

        Record Type = PRIMARY_RECORD Record Attributes = NULL_BITMAP

        Memory Dump @0x4500C069

        00000000: 10000600 62620100 fe†††††††††††††††††....bb...

        OFFSET TABLE:

        Row - Offset

        1 (0x1) - 105 (0x69)

        0 (0x0) - 96 (0x60)



        現在看一下char(2)的存儲情況,通過Length和offset table 可以看到,數據行的長度仍然為9。分析一下具體的數據行,仍然以slot 0為例:
        10000600 61610100 fe†††††††††††††††††....aa...

        前兩位10表示沒有可變長度的字段,后面兩位00在sqlserver 2005中沒有用到;0600表示固定長度的字段所占的長度為5(實際長度加4);61轉換為十進制數位97,表示小寫字母a。后面的0100表示固定長度的字段數量為1;剩下fe就是NULL位圖了,翻譯成2進制數為1111 1110,這說明該行中沒有字段為NULL,這和實際情況也是相符的。

        通過上面兩個實驗可以看出:只有一個字段,并且類型和長度為char(1)的表的數據行所占用的空間和只有一個字段,并且類型和長度為char(2)的表的數據行所占用的空間是相等的。為什么會出現這種情況呢?

        實際上,如果一個數據行的長度沒有達到規定的最小長度(9 bytes),SQL SERVER會自動在該行的后面填充一個字節,將長度擴展到9。這就是我們之前看到的那個08出現的原因。所以SQLSERVER數據行最小的長度為9,而不是8。

        您可能要問了:為什么SQL SERVER會有這樣的規定呢?

        這個規定是為了更新操作(update)建立的龜腚。我們知道RID用來標識數據頁數據行,當數據頁中的某一行數據被更新以至于現有的數據頁無法再容納該行時,SQLSERVER會將該行移動到新的數據頁中。原有的數據行位置并不被其他的數據行占用,而是替換成一個forwarding pointer。該pointer指向那個被更新的數據行的新的位置。而這個pointer大小為9 byte(header占一byte,RID占8byte,RID的構成:4個字節的pageID,2個字節的fileID,2個字節的slotID)。所以sql server為了保證能夠成功地將數據行替換成forwarding pointer,規定每個數據行要最少要占用9個byte。

        您可能又要問了,為什么需要那個鳥forwarding pointer呢,直接移動不就ok了。反正數據頁和數據頁之間是沒有關系的,數據頁中的數據行又是無序的。要那個forwarding pointer有啥用???

        原因是這樣的,當數據頁中的某一行數據被更新以至于現有的數據頁無法再容納該行時,SQLSERVER會將該行移動到新的數據頁中。之后就出現了兩個選擇:

        1 更新原有數據頁中所有數據行的RID,這可能是個非常昂貴的操作(可能有249個索引)。
        2 不更新數據頁中的RID,將那個空缺的位置替換成一個forwarding pointer。在以后的查詢時按照這個pointer查找紀錄。



        您可能還有疑問:如果表建立了聚集索引,每個數據行也要占用9byte嗎
        是這樣的。雖然聚集索引的更新操作有所不同,但是為了方便b-tree轉換成heap,也需要保持9個byte



        http://www.cnblogs.com/stswordman/archive/2007/08/22/865425.html

        聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

        文檔

        SQLSERVER中數據行所占用的最小空間

        SQLSERVER中數據行所占用的最小空間:數據行所占的最小空間是多少呢? 先來看看下面這張經典數據行結構圖(引自Inside Sql Server) 因為可變長度類型的列會有額外的空間開銷,所以不考慮可變長度的字段。 現在計算一下除去實際數據后每個數據行所需要占用的空間: 狀態位A占一個字節,狀態位B占
        推薦度:
        標簽: 空間 數據 用的
        • 熱門焦點

        最新推薦

        猜你喜歡

        熱門推薦

        專題
        Top
        主站蜘蛛池模板: 亚洲综合色在线观看亚洲| 亚洲免费精彩视频在线观看| 日韩免费三级电影| 亚洲第一区二区快射影院| 亚洲免费观看在线视频| 四虎最新永久免费视频| 亚洲国产视频一区| av无码久久久久不卡免费网站| 免费一级大黄特色大片| 美女视频黄频a免费| 免费人成年轻人电影| 一个人看的免费视频www在线高清动漫 | 人人鲁免费播放视频人人香蕉| 无码人妻精品中文字幕免费| 亚洲卡一卡2卡三卡4卡无卡三| 蜜桃传媒一区二区亚洲AV| 国产大片51精品免费观看| 一级毛片正片免费视频手机看 | 国产高清免费观看| 美女被免费视频网站a| 亚洲日韩VA无码中文字幕| 77777午夜亚洲| 国产成人aaa在线视频免费观看 | 亚洲黑人嫩小videos| 一个人免费观看在线视频www| 久久久久久久综合日本亚洲| 老汉精品免费AV在线播放| 亚洲一级毛片免费看| 免费网站看av片| 亚洲AV成人一区二区三区在线看 | 亚洲欧洲成人精品香蕉网| 91精品全国免费观看含羞草| 国产亚洲一区二区手机在线观看| 美美女高清毛片视频黄的一免费 | 日韩大片在线永久免费观看网站| 大学生一级毛片免费看| 亚洲一区影音先锋色资源| 麻豆精品国产免费观看| 岛国精品一区免费视频在线观看| 亚洲熟妇少妇任你躁在线观看无码| 亚洲熟女www一区二区三区|