SQL Server :理解数据记录结构

原文:SQL Server :理解数据记录结构

在SQL Server :理解数据页结构我们提到每条记录都有7 bytes的系统行开销,那这个7 bytes行开销到底是一个什么样的结构,我们一起来看下。

数据记录存储我们具体的数据,换句话说,它存在堆表里,或者存在聚集索引的叶子节点。数据记录结构是为了让SQL Server更高效的管理数据。我们来看下数据记录结构示意图:

上图中蓝色部分是所有数据记录部分(即系统行开销,大小基于列个数,等于或大于7 bytes),绿色部分是表结构里取决于定长/变长列的数据记录部分(实际存放的数据,大小基于实际数据)。

行头系统数据:

用做状态位1的第1字节(8位)是用来定义记录的属性:

  • 第0位:版本信息,在SQL Server 2008里始终是0;
  • 第1-3位:这3位用来定义记录类型;
    • 0 数据记录(data record)
    • 1 转发记录(Forwarded record)
    • 2 转发存根(a forwarding stub)
    • 3 索引记录(Index record)
    • 4 二进制堆碎片或行溢出数据(blob fragment or row overflow data)
    • 5 鬼影索引记录(ghost index record)
    • 6 鬼影数据记录(ghost data record)
    • 7 鬼影版本记录(ghost version record)
  • 第4位:存在空值位图(Null bitmap )或没有。在SQL Server 2008里没有不为空的列也会有空值位图(Null bitmap );
  • 第5位:表示是否存在变长列;
  • 第6位:表示该列包含版本信息;
  • 第7位:在SQL Server里未使用;

用作状态位2的第2字节(8位)。只有1位用来表示这条记录是否为鬼影转发记录(ghost forwarded record)。

由行头开始到定长列结尾长度:

下2个字节用来存储行头开始到定长列结尾长度。它包含2个状态位,2个字节用作这个列表示在表中定长数据的实际长度。例如如果表里没有定长列,这个列的值会是4。这和页头列pminlen显示的值是一样的。

所有定长列字段值(Fixed_Data_Size):

下n个字节用来存储在表中的定长数据,n就是在表中所有定长列的长度。如果表里的所有列都是变长列,这一部分就没有。

空值位图(Null_Bitmap):

下2个字节用来存储表里的列数。

下n个字节用作空值位图,每个bit对应一个列,1表示对应列为空。n的值为:列数 / 8,将值取整。

Variable_Data_Size:

下2个字节用来存储表里变长列个数。

下n个字节用来存储每个变长列结束为止的偏移量。每个变长列需要2字节,n的值为:变长列数 * 2 。

最后n个字节用来存储所有变长列值,n的值为所有变长列的实际长度的总长度。

 我们来看一个具体的例子:

创建数据库,并插入2条记录

 1 USE [InternalStorageFormat]
 2 GO
 3 
 4 IF EXISTS ( SELECT  *
 5             FROM    sysobjects
 6             WHERE   id = OBJECT_ID(N'[dbo].[Customers]')
 7                     AND OBJECTPROPERTY(id, N'IsUserTable') = 1 )
 8     DROP TABLE dbo.Customers
 9 
10 CREATE TABLE Customers
11 (
12    FirstName CHAR(50) NOT NULL,
13    LastName CHAR(50) NOT NULL,
14    Address CHAR(100) NOT NULL,
15    ZipCode CHAR(5) NOT NULL,
16    Rating INT NOT NULL,
17    ModifiedDate DATETIME NOT NULL,
18 )
19 GO
20 
21 
22 INSERT INTO dbo.Customers
23         ( FirstName ,
24           LastName ,
25           Address ,
26           ZipCode ,
27           Rating ,
28           ModifiedDate
29         )
30 VALUES  ( 'Woody' , -- FirstName - char(50)
31           'Tu' , -- LastName - char(50)
32           'ZUOQIAO YOUXI TOWN LINHAI CITY' , -- Address - char(50)
33           '0000' , -- ZipCode - char(5)
34           1 , -- Rating - int
35           '2015-05-07 10:09:51'  -- ModifiedDate - datetime
36         )
37         go 2

使用DBCC IND命令查看表对应页列表:

1 DBCC IND('InternalStorageFormat','Customers',-1)

我们看到数据页号为79。

使用DBCC PAGE命令查看页信息:

1 DBCC TRACEON(3604)
2 DBCC PAGE(InternalStorageFormat,1,79,3)
3 GO  

在页头pminlen的值是221,包括定长列的总长217 bytes(50+50+100+5+4+8),2 bytes用作状态位(行头系统开销),2 byte 用作由行头开始到定长列结尾长度。

在记录槽提到的长度224,包括页头pminlen的值,1 byte用作空值位图(6/8 取整为1)和2 bytes 的字段个数。

我们来看一个变长列的表。

创建表并插入数据后,查看表对应的页:

 1 CREATE TABLE VariableLength(
 2    Title         CHAR(10) NOT NULL,
 3    FirstName     VARCHAR(100),
 4    Lastname      VARCHAR(100),
 5    email         VARCHAR(50), 
 6    dob           date NOT NULL,
 7    phone         CHAR(10),
 8    Countrycode   CHAR(3),
 9    Designation   VARCHAR(100),
10    PersonalPreference VARCHAR(100)
11 )
12 GO
13 INSERT INTO VariableLength VALUES ('Mr','Woody','Tu','smartgz@qq.com','2015-5-7','XXXXXXXXXX','Chn','DBA','Nothing Spl')
14 GO
15 DBCC IND('InternalStorageFormat','VariableLength',-1)

我们看到数据页号为202。

使用DBCC PAGE命令查看页信息:

1 DBCC TRACEON(3604)
2 GO
3 DBCC PAGE('InternalStorageFormat',1,202,3)--记得根据你的实际数据库,修改页号202

pminlen值为30,包含:

  • 1 byte 状态位1
  • 1 byte 状态为2
  • 2 bytes 存储行头开始到定长列结尾长度
  • 26 bytes 所有定长列总长度(10+3+10+3:tittle,dob,phone,countrycode)
    • Title  CHAR(10) NOT NULL

    • dob date NOT NULL

    • phone CHAR(10)

    • Countrycode CHAR(3)

可以用下列语句验证下定长列总长度: 

1 SELECT DATALENGTH(Title) title,DATALENGTH(dob) dob,DATALENGTH(phone) phone,DATALENGTH(Countrycode) countrycode FROM VariableLength

 在槽0显示的81长度包含:

  • 1 byte 状态位1
  • 1 byte 状态为2
  • 2 bytes 存储行头开始到定长列结尾长度
  • 26 bytes 所有定长列总长度(10+3+10+3:tittle,dob,phone,countrycode)
    • Title  CHAR(10) NOT NULL

    • dob date NOT NULL

    • phone CHAR(10)  

    • Countrycode CHAR(3)

  • 2 bytes 存储列个数
  • 2 bytes 用作空值位图,字段个数/8后取整,即 9/8 得到2
  • 2 bytes 存储变长列个数
  • 10 bytes 用来存储每个变长列结束位置的偏移量 变长列个数 * 2,即 5 * 2 得到10,5个变长列包含:
    • FirstName VARCHAR(100)

    • Lastname VARCHAR(100)  

    • email VARCHAR(50)

    • Designation VARCHAR(100)  

    • PersonalPreference VARCHAR(100)

  • 35 bytes 用来存储所有变长列的实际长度,这个可以使用下列语句得到
1 SELECT DATALENGTH(FirstName)+DATALENGTH(Lastname)+DATALENGTH(email)+
2 DATALENGTH(Designation)+DATALENGTH(PersonalPreference) FROM VariableLength

总结下每条记录的系统行开销:

行头系统数据(2 bytes)+由行头开始到定长列结尾长度(2 bytes)+列个数(2 bytes)+空值位图数据(取整(列个数/8) n bytes)

2 bytes + 2 bytes + 2 bytes + 取整(列个数/8)

当列个数小于等于8时,系统行开销始终是7 bytes,往上没增加8列,增加1 bytes,即系统系统行开销始终大于等于7 bytes

对于在SQL Server里数据记录的存储格式,希望你已经有了清晰的认识。

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/460225.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

京东云擎提供了免费的wordpress一键安装功能了

1. 京东云擎(http://jae.jd.com)提供了免费的个人博客WordPress一键安装功能了,如下图,给开发者分享福利! 免费的应用,提供了源码,提供了数据库: 我之前把文章发到首页,遭到了封杀!本…

Distinct源码分析

以前比较两个List数据,筛选出所需要的数据时候,一直套两层for循环来执行。用到去重(Distinct)的时候,这两个需求其实都是一样的,都是需要比较两个集合,查看了下它的源码,里面确实有值得借鉴的地方。 先附上…

java语言 编译原理_【Java学习】深入分析Java的编译原理

在《Java代码的编译与反编译》中,有过关于Java语言的编译和反编译的介绍。我们可以通过javac命令将Java程序的源代码编译成Java字节码,即我们常说的class文件。这是我们通常意义上理解的编译。但是,字节码并不是机器语言,要想让机…

实验 使用 vivado zedboard GPIO 开关 开控制 LED

前面我做了几个实验 都没有用过 开关,这一次用一用 发现 vivado 真的挺方便 所以 使用 vivado 开发 1.建工程 我使用 vivado 2013.4 创建新工程 –》 next –》next 勾选 Do not specify sources at this time //这样跳过后面两个添加文件页面 选择 board –》 ze…

java 最优化_java-多维度求最优解

拿出11条数据//条件每个位置(position)的人数限制每队(team)人数不能超过7人credits的总和在100分之内(包含100)总分(points)最高//位置人数限制position-1 : 1 position-2 : 3-5 position-3 : 1-3 position-4 : 3-5//模拟数据{points credits position team56 9.0 1 t154 9.1 …

必应(Bing)每日图片获取API

必应(Bing)每日图片获取API January 11, 2015 API http://lab.dobyi.com/api/bing.php 介绍 ValueDescriptiontitle标题desc描述url图片地址你们自由发挥……

java取模多位数_JAVA大数类—基础操作(加减乘除、取模、四舍五入、设置保留位数)...

当基础数据类型长度无法满足需求时可以使用大数类构造方法接受字符串为参数1 BigInteger bInt new BigInteger("123123");2 BigDecimal bDouble new BigDecimal("123123.123123124");基础操作(取模使用divideAndRemainder方法,返回的数组第二…

HDU 4902

数据太弱&#xff0c;直接让我小暴力一下就过了&#xff0c;一开始没注意到时间是15000MS&#xff0c;队友发现真是太给力了 #include <cstdio> #include <cstring> int n,q,a[100005],x[100005],p,l[100005],r[100005],t[100005]; int tree[1000005]; void build(…

tcp/udp高并发和高吐吞性能测试工具

在编写一个网络服务的时候都比较关心这个服务能达到多少并发连接,而在这连接的基础上又能达到一个怎样的交互能力.编写服务已经是一件很花力气的事情,而还要去编写一个能够体现结果的测试工具就更加消耗工作时间.下面介绍一个测试工具只需要简单地设置一下就能对tcp/udp服务进行…

几个数字的和

ctrl z 的使用 #include<iostream> using namespace std;main() {int num,sum0;while(cin>>num) {sumnum;}cout<<"和为"<<sum<<endl; } View Code#include<iostream> using namespace std; main() { int num,s…

网站在线压力测试工具Load Impact

关于Load ImpactLoad Impact是一个一个在线的网站压力测试服务及工具&#xff0c;模拟多用户同时访问你的站点&#xff0c;并出具报告以分析你的站点可以支撑的访问者数量&#xff0c;它能让你通过简单的几次点击就能测试出你的网站的性能。不过免费用户只能同时并发50个虚拟访…

sc.next在java什么意思_sc.next() 和 nextLine 的原理

对java的Scanner类的next开头的相关类有点纠结&#xff0c;看了一些博客大致懂了&#xff0c;整理下代码事例直接参考了这位大佬的https://blog.csdn.net/long71751380/article/details/94008351. 总的原理以一段代码为例,scanner类import java.util.Scanner;public class Next…

WPF RichTextBox相关总结

由于公司涉及到聊天对话框的功能&#xff0c;就想到了RichTextBox&#xff0c;查阅相关资料&#xff0c;总结下&#xff1a; 一、RichTextBox的内容相关的类 1.1RichTextBox的内容结构 RichTexBox是个可编辑控件&#xff0c;可编辑我们很容易想到word的可编辑&#xff0c;在wor…

python 内置方法赋值_Python内置数据结构之字符串str

1. 数据结构回顾所有标准序列操作(索引、切片、乘法、成员资格检查、长度、最小值和最大值)都适用于字符串&#xff0c;但是字符串是不可变序列&#xff0c;因此所有的元素赋值和切片赋值都是非法的。>>> website http://www.python.org>>> website[-3:] c…

以下是关于ASP.NET中保存各种信息的对象的比较,理解这些对象的原理,对制作完善的程序来说是相当有必要的(摘至互联网,并非原创--xukunping)...

在ASP.NET中&#xff0c;有很多种保存信息的对象.例如:APPlication,Session,Cookie,ViewState和Cache等,那么它们有什么区别呢?每一种对象应用的环境是什么? 为了更清楚的了解,我们总结出每一种对象应用的具体环境,如下表所示: 方法信息量大小保存时间应用范围保存位置App…

实现每个点赞用户点击的带属性的字符串

2019独角兽企业重金招聘Python工程师标准>>> #pragma mark - 点击各个点赞用户-(void)setClicked:(TweetCell *)cell andOSCTweet:(OSCTweet *)tweet {NSMutableAttributedString *attributedString [[NSMutableAttributedString alloc] initWithString:tweet.like…

xampp php5.6 7.1共存,New XAMPP with PHP 7.2.8, 7.1.20, 7.0.31 5.6.37

嗨&#xff0c;阿帕奇的朋友们&#xff01;We just released new versions of XAMPP for all platforms with the latest PHP versions: 7.2.8, 7.1.20, 7.0.31 & 5.6.37.您可以下载这些新版本http://www.apachefriends.org/download.html.7.2.8 / 7.1.20 / 7.0.31 / 5.6.3…

基于.net开发chrome核心浏览器【四】

原文:基于.net开发chrome核心浏览器【四】一&#xff1a; 上周去北京出差&#xff0c;给国家电网的项目做架构方案&#xff0c;每天都很晚睡&#xff0c;客户那边的副总也这样拼命工作。 累的不行了&#xff0c;直接导致第四篇文章没有按时发出来。 希望虚心学习1&#xff0c;小…

php5.6 pdo.dll 没有,php5.6没有pdo怎么办

php5.6没有pdo是因为在php5.6中php已经内置了pdo功能&#xff0c;只需要在php.ini文件中将“extensionphp_pdo_firebird.dll”等配置项打开即可。推荐&#xff1a;《PHP视频教程》php5.6中没有php.pdo.dll文件我下载的php 5.6要使用pdo模块&#xff0c;但是通过百度发现发现没有…

网页的背景图片代码

网页背景图片代码1.(最普遍类) <style>body{background-image:url(logo.gif);background-repeat:no-repeat;background-position:center}</style> 说明:以上代码为网页背景图片固定代码&#xff01;网页背景图片固定代码&#xff0c;这样&#xff0c;当向下拉网页时…