Asp.Net教程,WinForm教程,Asp.Net MVC,vs2008教程,vs2010教程,Silverlight技术,源码下载,Asp.Net视频教程
全站热门标签
vs2010 Silverlight 存储过程 水晶报表 ADO.NET JavaScript LINQ AjaxPro DataGridView 面向对象 Extjs GridView XML DevExpress HTML教程 Oracle jQuery 分页 GDI+ Visual C++2010 MySQL Office2010 WPF MVC Dojo WCF4.0 VB.NET Sql2005 textbox cookie WCF WinForm Discuz!NT SQL经典语句 T-SQL checkbox ASPxGridView F# asp.net SQL VS2008新特性 DropDownList Access TreeView Ajax VS2008 页面执行时间 Flex 字符串 回调 VB2005 DataSet C#时间 ASP.NET性能优化 用户在线检测 动画
SQL Server Oracle Access MySQL
当前位置: 主页 > 数据库 > SQL Server >

NULL在SQLServer数据库数据文件中的存储

时间:2010-08-15 13:04来源:未知 作者:admin 点击:

这个对于定长和不定长字段来说是两个结果
定长字段Null要占足字段空间,不定长字段则不占空间,两者都是通过null_bitmap来确认行数据中的null列。这个很容易用事实表的大小来验证。其具体存储机制还是需要dbcc来查看数据页。我们分几种情况查看:
-- 定长测试:

-- 建立测试环境

create database dbtest111

go

use dbtest111

go

create table t1( id char ( 10) , name char ( 10))

insert into t1 select 'a' , '1'

insert into t1 select 'b' , '2'

create table t2( id char ( 10) , name char ( 10))

insert into t2 select 'a' , 'jinjazz1'

insert into t2 select 'b' ,null

insert into t2 select 'c' ,null

insert into t2 select 'd' , 'jinjazz2'

go

-- 运行此命令

dbcc ind( dbtest111, t2, 0)

-- 得到 pagetype=1 的那个行数据的 pageid ,比如我这里是

dbcc traceon( 3604)

dbcc page( dbtest111, 1, 89, 1)

运行上面的sql语句,创建测试环境和实验脚本。得到如下结果

Slot 0, Offset 0x60, Length 27, DumpStyle BYTE

Record Type = PRIMARY_RECORD        Record Attributes =  NULL_BITMAP  
Memory Dump @0x5655C060

00000000:  10001800 61202020 20202020 20206a69 †....a        ji      
00000010:  6e6a617a 7a312020 0200fc †††††††††††††njazz1  ...            

Slot 1, Offset 0x7b, Length 27, DumpStyle BYTE

Record Type = PRIMARY_RECORD        Record Attributes =  NULL_BITMAP  
Memory Dump @0x5655C07B

00000000:  10001800 62202020 20202020 20206a69 †....b        ji      
00000010:  6e6a617a 7a312020 0200fe †††††††††††††njazz1  ...            

Slot 2, Offset 0x96, Length 27, DumpStyle BYTE

Record Type = PRIMARY_RECORD        Record Attributes =  NULL_BITMAP  
Memory Dump @0x5655C096

00000000:  10001800 63202020 20202020 20206a69 †....c        ji      
00000010:  6e6a617a 7a312020 0200fe †††††††††††††njazz1  ...            

Slot 3, Offset 0xb1, Length 27, DumpStyle BYTE

Record Type = PRIMARY_RECORD        Record Attributes =  NULL_BITMAP  
Memory Dump @0x5655C0B1

00000000:  10001800 64202020 20202020 20206a69 †....d        ji      
00000010:  6e6a617a 7a322020 0200fc †††††††††††††njazz2  ...

每个slot都代表一行,可以看到null的不但占用空间,而且还写入了你不要的东西,最后处理是通过红色字体部分来判断那些字段是null哪些不是null,红色部分就是null_bitmap

--2 、不定长字段测试

create database dbtest111

go

use dbtest111

go

create table t2( id char ( 10) , name varchar ( 10))

insert into t2 select 'a' , 'jinjazz1'

insert into t2 select 'b' ,null

insert into t2 select 'c' ,null

insert into t2 select 'd' , 'jinjazz2'

go

-- 运行此命令

dbcc ind( dbtest111, t2, 0)

-- 得到 pagetype=1 的那个行数据的 pageid ,比如我这里是

dbcc traceon( 3604)

dbcc page( dbtest111, 1, 73, 1)

运行以上SQL代码得到结果

00000000:  30000e00 61202020 20202020 20200200 †0...a        ..      
00000010:  fc01001d 006a696e 6a617a7a 31††††††††.....jinjazz1          

Slot 1, Offset 0x7d, Length 17, DumpStyle BYTE

Record Type = PRIMARY_RECORD        Record Attributes =  NULL_BITMAP  
Memory Dump @0x5655C07D

00000000:  10000e00 62202020 20202020 20200200 †....b        ..      
00000010:  fe†††††††††††††††††††††††††††††††††††.                      

Slot 2, Offset 0x8e, Length 17, DumpStyle BYTE

Record Type = PRIMARY_RECORD        Record Attributes =  NULL_BITMAP  
Memory Dump @0x5655C08E

00000000:  10000e00 63202020 20202020 20200200 †....c        ..      
00000010:  fe†††††††††††††††††††††††††††††††††††.                      

Slot 3, Offset 0x9f, Length 29, DumpStyle BYTE

Record Type = PRIMARY_RECORD        Record Attributes =  NULL_BITMAP VARIABLE_COLUMNS

Memory Dump @0x5655C09F

00000000:  30000e00 64202020 20202020 20200200 †0...d        ..      
00000010:  fc01001d 006a696e 6a617a7a 32††††††††.....jinjazz2

varchar比char节省地方,他的rowoffset是依次写入的,null不占用空间,空间利用很好,这个比char字段的null节省地方。


--3 、不定长字段更改

update t2 set name = 'jinjazz3' where id= 'b'

dbcc page( dbtest111, 1, 73, 1)

/*

Row - Offset                      

3 (0x3) - 159 (0x9f)              

2 (0x2) - 142 (0x8e)              

1 (0x1) - 188 (0xbc)                

0 (0x0) - 96 (0x60) 

*/  

这个只要看最后的row Offset,红色部分是update的这条,他开辟了另外一处空间把null变成了非null。

当然系统会适时回收老的废弃空间。但varchar的效率没有char高是肯定的了,这也就是说char相当于空间换时间了

(责任编辑:admin)
Tags:SQL
责任编辑:admin
返回顶部
------分隔线----------------------------
推荐内容
骆驼户外男 真皮磨砂日常休闲鞋 低帮 2011秋冬新款 专柜正品特价 骆驼户外男 真皮磨砂日常休闲鞋 低帮 2011秋冬新款 专柜正品特价
  • 数据库中自定义拆分字符串函数Split()

    经常我们要用到批量操作时都会用到字符串的拆分,郁闷的是SQL Server中却没有自带Split函数,所以我们只能自己动手来解决一下。为了减少和数据库的通讯次数...

  • sql函数实现三种父子递归

    在实际运用中经常会创建这样的结构表Category(Id, ParentId, Name),特别是用于树形结构时(菜单树,权限树..),这种表设计自然而然地会用...

  • SQL CASE WHEN使用

    Case具有两种格式。简单Case函数和Case搜索函数。 --简单Case函数 CASE sex WHEN '1' THEN '男' WHEN '2' THE...

  • MSSQL移除字符串两边的指定字符

    移除字符串左边的字符: CREATE FUNCTION [ dbo ] . [ RemoveLeftChar ] ( @Expression varchar (...

  • IDENTITY的小技巧--SQL Server 2005

    备份数据库遇到一个问题,就是将旧数据搬移到新主机数据表的时候,如果主键是的 IDENTITY 是设定自动增加的话,那么旧有的主键数据,在新数据表上面就好像是重新...

  • Sql2005将相同值的行内容进行合并

    如何将相同键值的蓝位内容值串接 ? 举例来说 TableA 如下: ID Type DESC 1 cpu 处理器 1 cpu 双核心 1 cpu 800外频 2...

  • SQL Server数据库恢复案例分享

    很多数据恢复工程师包括一些数据恢复技术爱好者经常会问同样一个问题:数据一旦被覆盖了,还能不能恢复呀?我听说国外能恢复被覆盖以后的数据,据说只要是覆盖操作在7次以...

  • SQL2005索引优化

    SQL2005索引优化...

  • 容易忽略的SQL语句

    容易忽略的SQL语句...

  • 世界完全对称日(SQL)

    世界完全对称日(SQL)...

  • 经典的sql语句技巧

    1、应用程序中,保证在实现功能的基础上,尽量减少对数据库的访问次数;通过 搜索参数,尽量减少对表的访问行数,最小化结果集,从而减轻网络负担;能够分 开的操作尽量...

  • provider:SQL网络接口, error: 26-定位指定的服务器/实例时出错

    在建立与服务器的连接时出错。在连接到 SQL Server 2005 时,在默认的设置下 SQL Server 不允许进行远程连接可能会导致此失败。 (prov...

  • 树形数据汇总查询(MS-SQL Server应用实例)

    -- SQL2000: -- 查询的数据语句: SELECT DISTINCT B.KJND,B.GSDM,A.FZDM,A.FZMC, ZBZE1 = SUM...

  • SQLServer批量备份与还原

    备份与还原是数据库避不开的主题,而作为DBA,经常会面临将一台机器上的所有数据库重新构建到一台新机器上的要求; 在现在都讲究自动化管理的时代,传统的界面操作备份...

  • 如何修改SQL Server 2005服务器名称

    1、使用SELECT @@ServerName可以看到当前数据库的服务器名 2、SELECT * FROM Sys.SysServers表中可以看到当前的所有服...