SQLServerBIT类型能占多少空间?

此文章主要向大家讲述的是SQL Server BIT类型在实际操作中占用了多少空间的介绍,在实际操作中一般的数据类型如INT、以及CHAR与tinyint等相关的数据类型,他们所占用的存储空间都是以Byte字节为单位的。

但是SQL Server BIT类型由于只有0和1或者说false和true,这种情况只需要一个Bit位就可以表示了,那么在SQL Server中BIT类型到底占用了多少空间?是不是由一个Bit位来存储的?或者可能是使用一个字节来存储的?

这两个答案都不正确!实际上SQL Server BIT类型占用的空间与BIT类型的列所在表的位置有关,有些情况下BIT占用了一个字节,有些情况下BIT实际占用了几个位(几个BIT类型的列共用一个字节)。下面就来具体分析一下:

单独的BIT类型的列将占用一个字节。

所谓单独就是指一个BIT类型的列的左边定长列和右边定长列都不是BIT类型的列。例如这样一个表:

 
 
 
  1. CREATE TABLE tt 
  2. c1 INT PRIMARY KEY, 
  3. c2 BIT NOT NULL, 
  4. c3 CHAR(2) NOT NULL 

SQL Server在存储表中的数据时先是将表中的列按照原有顺序分为定长和变长(变长就是长度不固定的数据类型,如varchar,nvarchar,varbinary等)两组。在数据页中存储数据时先存储所有定长的数据,然后再存储变长的数据。这里由于c2列的左边是int类型,右边是char类型,都是定长的,而且不是SQL Server BIT类型,所以c1和c3之间必须留出一个字节来存储c2,虽然c2只用到了其中的一个位。

下面我们来验证一下是否真是如我所说:

(1)插入一行数据:

 
 
 
  1. INSERT INTO tt VALUES(1,1,'aa') 

(2)找到tt表数据的***页(也就是刚才插入的这行数据所在页)的文件号和页面号:

 
 
 
  1. SELECT first_page 
  2. FROM sys.partitions p 
  3. INNER JOIN sys.system_internals_allocation_units a 
  4. ON p.partition_id=a.container_id 
  5. WHERE OBJECT_IDOBJECT_ID= OBJECT_ID('dbo.tt') 

我这里返回的是0x76 00 00 00 01 00,这里需要反转过来看0x00 01 00 00 00 76。其中前两个字节是文件号,后面的是页面号,所以文件号是1,页面号是118(0x76转换成十进制就是118)

(3)使用DBCC page命令查看该页的内部结构:

 
 
 
  1. DBCC traceon(3604) 
  2. DBCC page(TestDB,1,118,3) 

这儿DBCC traceon(3604)表示将页面内容直接输出,TestDB是我创建的tt表所在的数据库,1和118前面已经说了。***一个是打印选项。0表示只输出页头;1则不会输出所有内容,只是输出有数据的内容;2表示完整的输出这个页的内容,3则和1差不多,但是要每条记录分别列出列的值。以下是输出的需要关注的内容:

 
 
 
  1. 00000000: 10000b00 01000000 01616103 0000††††††.........aa... 

关于数据行的具体格式我就不在这里多说了,在《SQL Server 2005技术内幕 存储引擎》中有详细介绍。我们插入的数据从第5个字节开始,是01000000 016161。这儿01000000就是c1,由于是int类型,所以占用4个字节。接下来01就是c2,在这里占用了1字节。再接下来6161就是c3了。

2.多个BIT类型的列之间使用变长数据类型列分开,则去掉变长列,然后看连续的SQL Server BIT类型列的个数,每列占用一个位,如果多余了8列那就再占用更多的字节。例如创建这样的表:

 
 
 
  1. CREATE TABLE vtt 
  2. c1 BIT NOT NULL, 
  3. c2 VARCHAR(5) NOT NULL, 
  4. c3 BIT NOT NULL, 
  5. c4 NVARCHAR(5) NULL, 
  6. c5 BIT NULL, 
  7. c6 INT NOT NULL 

这里将变长列筛选出来后就变成了c1、c3、c5、c6,有3个BIT类型列是连续的,所以c1、c3、c5将公用一个字节。接下来就来验证一下:

(1)插入一条示例数据:

 
 
 
  1. INSERT INTO vtt VALUES(1,'abc',1,N'xyz',0,1023) 

(2)用前面用的SQL语句,同样的方法,找出vtt表的***页为:0xC00000000100,对应的就是文件号1,页号192

(3)查看该页的内部数据:

 
 
 
  1. 00000000: 30000900 03ff0300 00060000 02001500 †0. ............. 
  2. 00000010: 1b006162 63780079 007a00†††††††††††††..abcx.y.z

插入的数据从第5个字节开始03ff…… 这儿03就是c1、c3、c5的数据,03转换成二进制就是00000011。c1列对应***位1,c3对应倒数第二位1,c5对应倒数第三位0。接下来的ff就是c6的值1023。后面的就是列数、NULL位图、变长列等,这里是讨论BIT位占用空间的,所以就不讲解后面这些了。

3.一个表中有多个SQL Server BIT类型的列,其顺序是否连续决定了SQL Server BIT位是否可以共享一个字节。SQL Server中按照列顺序存储,***列和***一列都是BIT数据类型列,不可以共用一个字节。

也就是说下面的表t1和表t2占用的空间是不同的,t1数据占用了7字节,t2数据占用了8字节。

 
 
 
  1. CREATE TABLE t1 
  2. c1 INT PRIMARY KEY, 
  3. c2 BIT NOT NULL, 
  4. c3 BIT NOT NULL, 
  5. c4 CHAR(2) NOT NULL 
  6. CREATE TABLE t2 
  7. c1 INT PRIMARY KEY, 
  8. c2 BIT NOT NULL, 
  9. c4 CHAR(2) NOT NULL, 
  10. c3 BIT NOT NULL 

但是在下面的t3和t4表中,由于中间是变长数据类型,所以他们的BIT列占用的数据空间是相同的。

 
 
 
  1. CREATE TABLE t3 
  2. c1 INT NOT NULL, 
  3. c2 BIT NOT NULL, 
  4. c3 VARCHAR(2) NOT NULL, 
  5. c4 BIT NOT NULL 
  6. CREATE TABLE t4 
  7. c1 INT NOT NULL, 
  8. c2 BIT NOT NULL, 
  9. c4 BIT NOT NULL, 
  10. c3 VARCHAR(2) NOT NULL 

以上的相关内容就是对SQL Server BIT类型到底占用了多少空间的介绍,望你能有所收获。

网页标题:SQLServerBIT类型能占多少空间?
URL网址:http://www.shufengxianlan.com/qtweb/news14/466614.html

网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等

广告

声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联