NULL值在数据库中是否占用空间---MS-SQL

starfork 2009-03-18 10:32:27
NULL值在数据库中是否占用空间---(MS-SQL)
如果占用,和所在列的数据类型是否有关?

请大虾帮忙解答!
...全文
1535 55 打赏 收藏 转发到动态 举报
写回复
用AI写文章
55 条回复
切换为时间正序
请发表友善的回复…
发表回复
lily_0629 2011-07-08
  • 打赏
  • 举报
回复
刚刚学C#,看的我都有点晕了
fwacky 2010-02-21
  • 打赏
  • 举报
回复
null 不占用空间在 程序中!

VISLIVE 2009-10-25
  • 打赏
  • 举报
回复
据我了解,定长字段是绝对占用的。比如DateTime为Null时也一样占用8 bytes
水族杰纶 2009-03-18
  • 打赏
  • 举报
回复
建議推薦此帖~~
等不到来世 2009-03-18
  • 打赏
  • 举报
回复
[Quote=引用 25 楼 jinjazz 的回复:]
位置不同,比如一个表有四个字段

定常1,变长2,定常3,变长4

他的顺序是

标志字段-定常1-定常3-标志字段\Null字典信息-变长2位置-变长4位置-变长2内容-变长4内容
[/Quote]学习了
jinjazz 2009-03-18
  • 打赏
  • 举报
回复
位置不同,比如一个表有四个字段

定常1,变长2,定常3,变长4

他的顺序是

标志字段-定常1-定常3-标志字段\Null字典信息-变长2位置-变长4位置-变长2内容-变长4内容
等不到来世 2009-03-18
  • 打赏
  • 举报
回复
jj,
对于定长类型(n)char与变长类型的null值存储,
它们在空间上有区别吗?
jinjazz 2009-03-18
  • 打赏
  • 举报
回复
如果有兴趣可以看看,如下代码,他可以在得到一行二进制内容,比如通过fn_dbLog函数或者dbcc checklog,然后检查此行内容那些是列是null

实际检验这个代码是正确的。



static byte[] ReadRowData()
{
//代码略去
return null;
}
static void AnerlizeNull()
{
byte[] data = ReadRowData();//表示一行数据的二进制

//从第二个字节算起,data[2]
short index = 2;
//第二字节内容为pos_columns_count,表示第pos_columns_count个字节存放了列数信息,可以把本字节理解为指针
short pos_columns_count = BitConverter.ToInt16(data, index);
//pos_columns_count内容为data_columns_count,表示这个表有data_columns_count列
short data_columns_count = BitConverter.ToInt16(data, pos_columns_count);
//pos_columns_count的后两个字节开始表示了Null列信息,Null列信息不止占用1个字节,因为每列按位保存,如果列多,他的占用字节也多
short pos_null_map = (short)(pos_columns_count + 2);
//算Null信息占用多少字节
int data_null_map_length = (int)System.Math.Ceiling((double)data_columns_count / 8);
//读取Null列的标志内容
byte[] data_null_map = new byte[data_null_map_length];
System.Array.Copy(data, pos_null_map, data_null_map, 0, data_null_map_length);

//这里就可以开始检查一个表格的任何一列是否null了,null的数据是不在数据区的,只记录在Null列的标志内容中。

//比如看第10列是否null

checkNull(data_null_map, 10);
}

static bool checkNull(byte[] map, short col_order)
{
int mapIndex = (col_order - 1) / 8;
int mapExp = (col_order - 1) % 8;

int iResult = (int)System.Math.Pow(2, mapExp);

return (iResult & map[mapIndex]) != 0;
}
gyp2008 2009-03-18
  • 打赏
  • 举报
回复
不占用
-晴天 2009-03-18
  • 打赏
  • 举报
回复
[Quote=引用 19 楼 jinjazz 的回复:]
引用 17 楼 qianjin036a 的回复:
SQL codecreatedatabasedb1gousedb1goselecttop50000id=identity(int,0,1),col2=null,col3='abc',col4='gif'intotb1fromsysobjects a,sysobjects bgocreatedatabasedb2gousedb2goselecttop50000id=identity(int,0,1),col2='abc',col3='abc',col4='gif'intotb1fromsysobjects a,sysobjects bgo--执行完毕后,查看两数据库属性,都为大小:2.73M,可用0.94M./*drop table tb1
use db1
drop table …
[/Quote]
当表结构确定后,一个数据页上能写入的记录数是不固定的?
jinjazz 2009-03-18
  • 打赏
  • 举报
回复
还是看我10楼图片当中的第11行吧,这个才是关键,他以位存储来标志哪些字段是null

jinjazz 2009-03-18
  • 打赏
  • 举报
回复
[Quote=引用 17 楼 qianjin036a 的回复:]
SQL codecreatedatabasedb1gousedb1goselecttop50000id=identity(int,0,1),col2=null,col3='abc',col4='gif'intotb1fromsysobjects a,sysobjects bgocreatedatabasedb2gousedb2goselecttop50000id=identity(int,0,1),col2='abc',col3='abc',col4='gif'intotb1fromsysobjects a,sysobjects bgo--执行完毕后,查看两数据库属性,都为大小:2.73M,可用0.94M./*drop table tb1
use db1
drop table tb1
use master
drop database db1,db2*/
[/Quote]


你不要忘了数据不能跨页,一个字段的null不足以容纳另外一行记录


一页8k,一条数据6k也是要8k空间存储的,7k也是要8k空间存储的。
starfork 2009-03-18
  • 打赏
  • 举报
回复
[Quote=引用 16 楼 dawugui 的回复:]
引用 13 楼 ks_reny 的回复:
SQL code
Select len(null)
--------------
null
應該不占用吧.


舉個例子吧,非null的 相當與 活人,活人要吃飯,要睡覺....
那么 null 相當與 死人, 火花后 變成一點煙灰,風一吹就沒了.

孝顺点的后人,还是弄个地,碑什么的.
[/Quote]
咋扯到这个上面了
-晴天 2009-03-18
  • 打赏
  • 举报
回复
create database db1
go
use db1
go
select top 50000 id=identity(int,0,1),col2=null,col3='abc',col4='gif' into tb1 from sysobjects a,sysobjects b
go
create database db2
go
use db2
go
select top 50000 id=identity(int,0,1),col2='abc',col3='abc',col4='gif' into tb1 from sysobjects a,sysobjects b
go
--执行完毕后,查看两数据库属性,都为大小:2.73M,可用0.94M.
/*
drop table tb1
use db1
drop table tb1
use master
drop database db1,db2
*/
dawugui 2009-03-18
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 ks_reny 的回复:]
SQL code
Select len(null)
--------------
null
應該不占用吧.



舉個例子吧,非null的 相當與 活人,活人要吃飯,要睡覺....
那么 null 相當與 死人, 火花后 變成一點煙灰,風一吹就沒了.
[/Quote]
孝顺点的后人,还是弄个地,碑什么的.
htl258_Tony 2009-03-18
  • 打赏
  • 举报
回复
应该只占用数据类型本身要求的大小.帮顶了
jinjazz 2009-03-18
  • 打赏
  • 举报
回复
所有varchar列都是放在整条数据最后(二进制放在其他页),通过13、14行这样的地址指针来表示,一行数据不能跨页
ks_reny 2009-03-18
  • 打赏
  • 举报
回复

Select len(null)
--------------
null
應該不占用吧.

舉個例子吧,非null的 相當與 活人,活人要吃飯,要睡覺....
那么 null 相當與 死人, 火花后 變成一點煙灰,風一吹就沒了.
qizhengsheng 2009-03-18
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 wufeng4552 的回复:]
--轉老大原話
/*
如果你是char/nchar这类定长的类型,  那不用说,  肯定占用.
如果你是其他数据类型,  则不占用空间.
但要注意,  即使记录中的每个列都是NULL,  记录本身也要一个地址或者指针之类,  也会有空间开销.
*/
http://topic.csdn.net/t/20060111/19/4511392.html#
[/Quote]
mark
jinjazz 2009-03-18
  • 打赏
  • 举报
回复
上面表格代表一行数据,数据脚本

create table log_test(id int ,code char(10),name varchar(20),date datetime,memo varchar(100))
insert into log_test select 100, 'id001','jinjazz',getdate(),'剪刀'
加载更多回复(35)

34,596

社区成员

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

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