SQL SERVER 表最小行的一个纠结问题
昨天一个同事突然问我,说他在SQL 2000数据库创建如下表的时候,突然碰到了下面一条警告信息。SQL脚本和警告信息如下:
IF OBJECT_ID(N'Log') IS NULL
CREATE TABLE Log
(
[Date] DATETIME,
[Thread] NVARCHAR(255),
[Level] NVARCHAR(50),
[Logger] NVARCHAR(255),
[Message] NVARCHAR(4000),
[Exception] NVARCHAR(4000)
)
END
ELSE
PRINT('该表已经存在,请检查数据库');
GO
Warning: The table 'Log' has been created but its maximum row size (17159) exceeds the maximum number of bytes per row (8060). INSERT or UPDATE of a row in this table will fail if the resulting row length exceeds 8060 bytes.
我以前也没有遇见过这样的警告信息,当时我在SQL SERVER 2000 下面执行这段脚本,果然有这个警告信息,还有就是为什么Maximun ROW SIZE 是17159?;当我在SQL SERVER 2005 下面执行这段脚本却没有警告信息出现,难道SQL SERVER 2005 与SQL SERVER 2000在存贮机制上面有什么不同?在搞清楚这些问题前,我们先来看看其它的一些相关问题,就是SQL SERVER 2000/2005中最大数据行都是8060字节(对定长数据而言), 其中SQL SERVER 2000中可以使用的大小为8039字节, 而SQL SERVER 2005可以使用的大小为8053字节。我们可以从下面的脚本中实验一下(SQL SERVER 2005)
(
FIELD1 CHAR(4000),
FIELD2 CHAR(4000),
FIELD3 CHAR(53)
)
CREATE TABLE TEST1
(
FIELD1 CHAR(4000),
FIELD2 CHAR(4000),
FIELD3 CHAR(54)
)
最小行大小8061 = 4000 + 4000 + 54 + 7(内部开销)。下面我们改变下上面脚本的数据类型,如下所示,看看在SQL SERVER 2005下的情况
BEGIN
CREATE TABLE Log
(
[Date] DATETIME,
[Thread] CHAR(255),
[Level] CHAR(50),
[Logger] CHAR(255),
[Message] CHAR(4000),
[Exception] CHAR(4000)
)
END
ELSE
PRINT('该表已经存在,请检查数据库');
GO
那么最小行8575是怎么算出来的呢,我们先看这张经典数据行结构图(引自Inside SQL SERVER)
其实就是8 + 255 + 50 + 255 + 4000 + 4000 = 8568 + 7 = 8575 其中的7个字节是这样来的
Status Bits A 1
Status Bits B 1
Length of fixed-length ........ 2
number of columns 2
Null bitmap 1 bit for each column (6/8)1
由于表里面没有变长字段,所以其它与变长相关的字节为0 所以为7。 那么接下来我们看看开篇的问题为什么 maximum row size (17159),
8 + 255* 2 + 50 * 2 + 255 * 2 + 4000 * 2 + 4000 *2 = 17128
那么17128 + 19 = 17147 但是结果是17159,有点不明,查了很多资料也没搞清楚,这个17159 是怎么算出来的,呵呵,希望高手来解答!
呵呵,感谢邀月老大的解答:本来我怎么也找不出的12个字节即是: Heap中非聚集索引的叶级页有一个索引键列值(本例中由系统自动添加),加上一实际数据行的RID,即4+8=12
FROM sysobjects AS t JOIN sysindexes AS i ON t.id = i.id
WHERE t.id > 100 AND t.id=object_id( 'log')
SQL SERVER 表最小行的一个纠结问题相关推荐
- 如何去重一个SQL Server表
前面我写了个博客记录如何去重一个oracle表(link), 主要是利用了oracle的rowid伪列和row_number()分析函数. 有读者写邮件问, 如何去重一个SQL Server表, 场景 ...
- sql server 表索引碎片处理
DBCC SHOWCONTIG (Transact-SQL) SQL Server 2005 其他版本 更新日期: 2007 年 9 月 15 日 显示指定的表或视图的数据和索引的碎片信息. 重要提示 ...
- 在一个SQL Server表中的多个列找出最大值
在一个SQL Server表中一行的多个列找出最大值 有时候我们需要从多个相同的列里(这些列的数据类型相同)找出最大的那个值,并显示 这里给出一个例子 IF (OBJECT_ID('tempdb..# ...
- SQL Server 表和索引存储结构
SQL Server 表和索引存储结构 杜飞 在上一篇文章中,我们介绍了SQL Server数据文件的页面类型,系统通过96个字节的头部信息和系统表从逻辑层面上将表的存储结构管理起来,具体到表的存储结 ...
- SQL Server表分区的NULL值问题
原文:SQL Server表分区的NULL值问题 SQL Server表分区的NULL值问题 SQL Server表分区只支持range分区这一种类型,往往会被大家吐槽 人家MySQL支持四种类型:R ...
- SQL Server表分区【转】
转自:http://www.cnblogs.com/knowledgesea/p/3696912.html SQL Server表分区 什么是表分区 一般情况下,我们建立数据库表时,表数据都存放在一个 ...
- SQL Server表分区-水平分区
SQL Server表分区,sql server水平分区 转自:http://www.cnblogs.com/knowledgesea/p/3696912.html 根据时间的,直接上T-SQL代码 ...
- ssis导入xml_使用SSIS包将XML文档导入SQL Server表
ssis导入xml This article guides you through importing XML documents into SQL tables using SSIS package ...
- sql server表分区_介绍分区表SQL Server增量统计信息
sql server表分区 If you are maintaining a very large database, you might be well aware of the pain to p ...
最新文章
- BootStrap table 数据填充与分页应用总结
- 初学Java,这些框架你要掌握
- 要学DOT NET了
- Vue监听滚动条事件 点击回到顶部
- P4045-[JSOI2009]密码【AC自动机,状压dp】
- 使用libcurl以Post方式向HTTP服务器提交数据
- windows 2008 r2 AD域控服务器部署
- python程序设计实验报告实验程序流程序列化_Python程序设计_教学大纲_段震.doc
- JavaScript权威指南 - 数组
- 第五讲 C#中的异常处理
- Criteo数据集探索
- Spring mvc 项目整合P6Spy
- lync前段服务器证书安装,Lync Server 2013企业版部署测试六:前端服务器安装Lync Server系统...
- 2017最新版《土地利用现状分类》GBT 21010-2017
- html中加入计时器,javascript怎么做计时器?
- 深度学习与卷积神经网络
- 那个单位用计算机系统冷却,消防知识100题
- 武则天用无字碑深切蔑视男人
- ​如何通过微信打新债?
- 2021年四川高考成绩排名查询,四川高考排名查询方法,2021年四川高考成绩位次全省排名查询...