关于NULL 是否占空间问题

jldzy 2014-08-28 06:05:43
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)
...全文
461 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
云中客 2014-08-29
  • 打赏
  • 举报
回复
没有数据的时候,是不占空间的,不仅是char型
jldzy 2014-08-29
  • 打赏
  • 举报
回复
我是觉的有点奇怪,看网上好多人都是说对于定长的都是占据空间的,但是实际测试是不占据的。 还有个问题,这个page 怎么能看出 行与行之间是通过什么关系关联在一起的 ?
exception92 2014-08-29
  • 打赏
  • 举报
回复
你的结论是正确的。
Tiger_Zhao 2014-08-29
  • 打赏
  • 举报
回复
引用 6 楼 jldzy 的回复:
那岂不是可以这样理解,为了考虑以后的扩展 省的修改表结构,我可以在一个表里面多 预留10个或更多字段,他们都是NULL, 不占存储空间 ?
数据不占空间了,但是整体上所有字段需要存放额外的信息,不一定省空间。 我5楼的给的链接中有表格对比的。
专注or全面 2014-08-29
  • 打赏
  • 举报
回复
中国风 2014-08-29
  • 打赏
  • 举报
回复
看联机计算公式DB大小 http://msdn.microsoft.com/zh-cn/library/ms187445(v=sql.90).aspx 4、保留行中称为 Null 位图的部分以管理列的为空性。计算其大小: Null_Bitmap = 2 + ((Num_Cols + 7) / 8)
jldzy 2014-08-29
  • 打赏
  • 举报
回复
那岂不是可以这样理解,为了考虑以后的扩展 省的修改表结构,我可以在一个表里面多 预留10个或更多字段,他们都是NULL, 不占存储空间 ?
Tiger_Zhao 2014-08-29
  • 打赏
  • 举报
回复
现在有了稀疏列这种存储方式,楼主测试的结果就是。
而定长的说法是针对原先的非稀疏列的,适用范围不同。
--小F-- 2014-08-28
  • 打赏
  • 举报
回复
楼主是来让我们学习的?

34,587

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server相关内容讨论专区
社区管理员
  • 基础类社区
  • 二月十六
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧