关于NULL 是否占空间有关问题

关于NULL 是否占空间问题
For fixed width fields like nullable int the storage space required is always the same regardless of whether the value is null or not.

For variable width nullable fields the value ’NULL‘ takes zero bytes of storage space (ignoring the bit to store whether the value is null or not).
 但是在实际的测试里面,发现 char  int  为NULL的时候都是不占据空间的。

Slot 0 Column 1 Offset 0x4 Length 4 Length (physical) 4   -- int

Id = 1                              

Slot 0 Column 2 Offset 0x0 Length 0 Length (physical) 0  -- varchar

s1 = [NULL]                         

Slot 0 Column 3 Offset 0x0 Length 0 Length (physical) 0  --char

s2 = [NULL]              
           
Slot 0 Column 4 Offset 0x0 Length 0 Length (physical) 0 -- int

Ids = [NULL]                        

Slot 0 Offset 0x0 Length 0 Length (physical) 0

 
IF OBJECT_ID('DBCCResult') IS NOT NULL
    DROP TABLE DBCCResult
GO
 CREATE TABLE DBCCResult (
 PageFID NVARCHAR(200),
 PagePID NVARCHAR(200),
 IAMFID NVARCHAR(200),
 IAMPID NVARCHAR(200),
 ObjectID NVARCHAR(200),
 IndexID NVARCHAR(200),
 PartitionNumber NVARCHAR(200),
 PartitionID NVARCHAR(200),
 iam_chain_type NVARCHAR(200),
 PageType NVARCHAR(200),
 IndexLevel NVARCHAR(200),
 NextPageFID NVARCHAR(200),
 NextPagePID NVARCHAR(200),
 PrevPageFID NVARCHAR(200),
 PrevPagePID NVARCHAR(200)
  )

 IF OBJECT_ID('spaces') IS NOT NULL
    DROP TABLE spaces
GO
create table spaces(
 Id int identity(1,1) primary key,
s1 Varchar(20),
s2 char(30),
Ids int 
)

insert into spaces(s1,s2,Ids) values(null,null,null)
insert into spaces(s1,s2,Ids) values(1,null,1)
insert into spaces(s1,s2,Ids) values(null,2,1)
insert into spaces(s1,s2,Ids) values(3,3,1)

 SELECT  [index_id], [index_type_desc], [alloc_unit_type_desc], [index_depth],
         [index_level], [avg_fragmentation_in_percent], [fragment_count],
         [page_count]
 FROM    [sys].[dm_db_index_physical_stats](DB_ID('test'),
                                            OBJECT_ID('test.dbo.spaces'),
                                            NULL, NULL, NULL)

 INSERT INTO DBCCResult EXEC ('DBCC IND(test, spaces,-1) ')
 --PageType Page type: 1 = data page, 2 = index page, 3 = LOB_MIXED_PAGE, 4 = LOB_TREE_PAGE, 10 = IAM page
SELECT * FROM [dbo].[DBCCResult] ORDER BY [PageType] DESC

DBCC TRACEON(3604,-1)
 GO
 DBCC PAGE(test,1,16136023,3) 

------解决方案--------------------
你的结论是正确的。
------解决方案--------------------
看联机计算公式DB大小
http://msdn.microsoft.com/zh-cn/library/ms187445(v=sql.90).aspx

4、保留行中称为 Null 位图的部分以管理列的为空性。计算其大小:

Null_Bitmap = 2 + ((Num_Cols + 7) / 8)


------解决方案--------------------
楼主可以参考这个http://www.cnblogs.com/xwdreamer/archive/2012/07/18/2596984.html
------解决方案--------------------
引用:
那岂不是可以这样理解,为了考虑以后的扩展 省的修改表结构,我可以在一个表里面多 预留10个或更多字段,他们都是NULL, 不占存储空间 ?

数据不占空间了,但是整体上所有字段需要存放额外的信息,不一定省空间。
我5楼的给的链接中有表格对比的。