時(shí)間:2015-06-28 00:00:00 來源:IT貓撲網(wǎng) 作者:網(wǎng)管聯(lián)盟 我要評(píng)論(2)
此文章主要向大家探討的是SQL Server BIT類型占用空間的多少,對于一般的INT、CHAR、tinyint等相關(guān)的數(shù)據(jù)類型,他們所占用的存儲(chǔ)空間都是以Byte字節(jié)為單位的,但是BIT類型由于只有0和1或者說false和true。
這種情況只需要一個(gè)Bit位就可以表示了,那么在SQL Server中BIT類型到底占用了多少空間?是不是由一個(gè)Bit位來存儲(chǔ)的?或者可能是使用一個(gè)字節(jié)來存儲(chǔ)的?
這兩個(gè)答案都不正確!實(shí)際上BIT類型占用的空間與BIT類型的列所在表的位置有關(guān),有些情況下BIT占用了一個(gè)字節(jié),有些情況下BIT實(shí)際占用了幾個(gè)位(幾個(gè)BIT類型的列共用一個(gè)字節(jié))。下面就來具體分析一下:
1. 單獨(dú)的BIT類型的列將占用一個(gè)字節(jié)。
所謂單獨(dú)就是指一個(gè)BIT類型的列的左邊定長列和右邊定長列都不是SQL Server BIT類型的列。例如這樣一個(gè)表:
- CREATE?TABLE?tt? ?
- (? ?
- c1?INT?PRIMARY?KEY,? ?
- c2?BIT?NOT?NULL,? ?
- c3?CHAR(2)?NOT?NULL? ?
- )??
SQL Server在存儲(chǔ)表中的數(shù)據(jù)時(shí)先是將表中的列按照原有順序分為定長和變長(變長就是長度不固定的數(shù)據(jù)類型,如varchar,nvarchar,varbinary等)兩組。在數(shù)據(jù)頁中存儲(chǔ)數(shù)據(jù)時(shí)先存儲(chǔ)所有定長的數(shù)據(jù),然后再存儲(chǔ)變長的數(shù)據(jù)。這里由于c2列的左邊是int類型,右邊是char類型,都是定長的,而且不是BIT類型,所以c1和c3之間必須留出一個(gè)字節(jié)來存儲(chǔ)c2,雖然c2只用到了其中的一個(gè)位。
下面我們來驗(yàn)證一下是否真是如我所說:
(1)插入一行數(shù)據(jù):
- INSERT?INTO?tt?VALUES(1,1,'aa')??
(2)找到tt表數(shù)據(jù)的第一頁(也就是剛才插入的這行數(shù)據(jù)所在頁)的文件號(hào)和頁面號(hào):
- SELECT?first_page? ?
- FROM?sys.partitions?p? ?
- INNER?JOIN?sys.system_internals_allocation_units?a? ?
- ON?p.partition_id=a.container_id? ?
- WHERE?OBJECT_IDOBJECT_ID=?OBJECT_ID('dbo.tt')??
我這里返回的是0x76 00 00 00 01 00,這里需要反轉(zhuǎn)過來看0x00 01 00 00 00 76。其中前兩個(gè)字節(jié)是文件號(hào),后面的是頁面號(hào),所以文件號(hào)是1,頁面號(hào)是118(0x76轉(zhuǎn)換成十進(jìn)制就是118)
(3)使用DBCC page命令查看該頁的內(nèi)部結(jié)構(gòu):
- DBCC?traceon(3604)? ?
- DBCC?page(TestDB,1,118,3)??
這兒DBCC traceon(3604)表示將頁面內(nèi)容直接輸出,TestDB是我創(chuàng)建的tt表所在的數(shù)據(jù)庫,1和118前面已經(jīng)說了。最后一個(gè)是打印選項(xiàng)。0表示只輸出頁頭;1則不會(huì)輸出所有內(nèi)容,只是輸出有數(shù)據(jù)的內(nèi)容;2表示完整的輸出這個(gè)頁的內(nèi)容,3則和1差不多,但是要每條記錄分別列出列的值。以下是輸出的需要關(guān)注的內(nèi)容:
- 00000000:?10000b00?01000000?01616103?0000??????.........aa...??
關(guān)于數(shù)據(jù)行的具體格式我就不在這里多說了,在《SQL Server 2005技術(shù)內(nèi)幕 存儲(chǔ)引擎》中有詳細(xì)介紹。我們插入的數(shù)據(jù)從第5個(gè)字節(jié)開始,是01000000 016161。這兒01000000就是c1,由于是int類型,所以占用4個(gè)字節(jié)。接下來01就是c2,在這里占用了1字節(jié)。再接下來6161就是c3了。
2.多個(gè)BIT類型的列之間使用變長數(shù)據(jù)類型列分開
則去掉變長列,然后看連續(xù)的SQL Server BIT類型列的個(gè)數(shù),每列占用一個(gè)位,如果多余了8列那就再占用更多的字節(jié)。例如創(chuàng)建這樣的表:
- CREATE?TABLE?vtt? ?
- (? ?
- c1?BIT?NOT?NULL,? ?
- c2?VARCHAR(5)?NOT?NULL,? ?
- c3?BIT?NOT?NULL,? ?
- c4?NVARCHAR(5)?NULL,? ?
- c5?BIT?NULL,? ?
- c6?INT?NOT?NULL? ?
- )??
這里將變長列篩選出來后就變成了c1、c3、c5、c6,有3個(gè)BIT類型列是連續(xù)的,所以c1、c3、c5將公用一個(gè)字節(jié)。接下來就來驗(yàn)證一下:
(1)插入一條示例數(shù)據(jù):
- INSERT?INTO?vtt?VALUES(1,'abc',1,N'xyz',0,1023)??
(2)用前面用的SQL語句,同樣的方法,找出vtt表的第一頁為:0xC00000000100,對應(yīng)的就是文件號(hào)1,頁號(hào)192
(3)查看該頁的內(nèi)部數(shù)據(jù):
- 00000000:?30000900?03ff0300?00060000?02001500??0.?.............? ?
- ?00000010:?1b006162?63780079?007a00?????????????..abcx.y.z.??
插入的數(shù)據(jù)從第5個(gè)字節(jié)開始03ff…… 這兒03就是c1、c3、c5的數(shù)據(jù),03轉(zhuǎn)換成二進(jìn)制就是00000011。c1列對應(yīng)最低位1,c3對應(yīng)倒數(shù)第二位1,c5對應(yīng)倒數(shù)第三位0。接下來的ff就是c6的值1023。后面的就是列數(shù)、NULL位圖、變長列等,這里是討論BIT位占用空間的,所以就不講解后面這些了。
3.一個(gè)表中有多個(gè)SQL Server BIT類型的列
其順序是否連續(xù)決定了BIT位是否可以共享一個(gè)字節(jié)。SQL Server中按照列順序存儲(chǔ),第一列和最后一列都是BIT數(shù)據(jù)類型列,不可以共用一個(gè)字節(jié)。
也就是說下面的表t1和表t2占用的空間是不同的,t1數(shù)據(jù)占用了7字節(jié),t2數(shù)據(jù)占用了8字節(jié)。
- CREATE?TABLE?t1? ?
- (? ?
- c1?INT?PRIMARY?KEY,? ?
- c2?BIT?NOT?NULL,? ?
- c3?BIT?NOT?NULL,? ?
- c4?CHAR(2)?NOT?NULL? ?
- )? ?
- CREATE?TABLE?t2? ?
- (? ?
- c1?INT?PRIMARY?KEY,? ?
- c2?BIT?NOT?NULL,? ?
- c4?CHAR(2)?NOT?NULL,? ?
- c3?BIT?NOT?NULL? ?
- )??
但是在下面的t3和t4表中,由于中間是變長數(shù)據(jù)類型,所以他們的BIT列占用的數(shù)據(jù)空間是相同的。
- CREATE?TABLE?t3? ?
- (? ?
- c1?INT?NOT?NULL,? ?
- c2?BIT?NOT?NULL,? ?
- c3?VARCHAR(2)?NOT?NULL,? ?
- c4?BIT?NOT?NULL? ?
- )? ?
- CREATE?TABLE?t4? ?
- (? ?
- c1?INT?NOT?NULL,? ?
- c2?BIT?NOT?NULL,? ?
- c4?BIT?NOT?NULL,? ?
- c3?VARCHAR(2)?NOT?NULL? ?
- )??
以上的相關(guān)內(nèi)容就是對SQL Server BIT類型到底占用了多少空間的介紹,望你能有所收獲。
關(guān)鍵詞標(biāo)簽:SQL Server
相關(guān)閱讀
熱門文章 淺談JSP JDBC來連接SQL Server 2005的方法 SqlServer2005對現(xiàn)有數(shù)據(jù)進(jìn)行分區(qū)具體步驟 sql server系統(tǒng)表損壞的解決方法 MS-SQL2005服務(wù)器登錄名、角色、數(shù)據(jù)庫用戶、角色、架構(gòu)的關(guān)系
人氣排行 配置和注冊O(shè)DBC數(shù)據(jù)源-odbc數(shù)據(jù)源配置教程 如何遠(yuǎn)程備份(還原)SQL2000數(shù)據(jù)庫 SQL2000數(shù)據(jù)庫遠(yuǎn)程導(dǎo)入(導(dǎo)出)數(shù)據(jù) SQL2000和SQL2005數(shù)據(jù)庫服務(wù)端口查看或修改 修改Sql Server唯一約束教程 SQL Server 2005降級(jí)到2000的正確操作步驟 sql server系統(tǒng)表損壞的解決方法 淺談JSP JDBC來連接SQL Server 2005的方法