昨天一个同事突然问我,说他在SQL 2000数据库创建如下表的时候,突然碰到了下面一条警告信息。SQL脚本和警告信息如下:

IF OBJECT_ID(N'Log') IS  NULL

BEGIN
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)

CREATE TABLE TEST
(
    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下的情况

IF OBJECT_ID(N'Log') IS  NULL
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

1 + 1 + 2 + 2 + 1 + 2 + 2* 5  = 19 

那么17128 + 19 =  17147 但是结果是17159,有点不明,查了很多资料也没搞清楚,这个17159 是怎么算出来的,呵呵,希望高手来解答!

呵呵,感谢邀月老大的解答:本来我怎么也找不出的12个字节即是: Heap中非聚集索引的叶级页有一个索引键列值(本例中由系统自动添加),加上一实际数据行的RID,即4+8=12

SELECT t.name AS [Table Name], i.name AS [Index Name], i.minlen as minlen

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 表最小行的一个纠结问题的更多相关文章

  1. SQL Server 游标运用:查看一个数据库所有表大小信息(Sizes of All Tables in a Database)

    原文:SQL Server 游标运用:查看一个数据库所有表大小信息(Sizes of All Tables in a Database) 一.本文所涉及的内容(Contents) 本文所涉及的内容(C ...

  2. VFP 用 SPT 来发布一条 SELECT 到一个新的 SQL Server 表

    为了发布一条 SQL SELECT 语句来创建一个新的 SQL Server 表,  SQL Server 数据库的 select into/bulkcopy 选项必须是可用的. 在默认情况下, 对于 ...

  3. sql server 表索引碎片处理

    DBCC SHOWCONTIG (Transact-SQL) SQL Server 2005 其他版本 更新日期: 2007 年 9 月 15 日 显示指定的表或视图的数据和索引的碎片信息. 重要提示 ...

  4. 在一个SQL Server表中的多个列找出最大值

    在一个SQL Server表中一行的多个列找出最大值 有时候我们需要从多个相同的列里(这些列的数据类型相同)找出最大的那个值,并显示 这里给出一个例子 IF (OBJECT_ID('tempdb..# ...

  5. SQL Server表分区的NULL值问题

    SQL Server表分区的NULL值问题 SQL Server表分区只支持range分区这一种类型,但是本人觉得已经够用了 虽然MySQL支持四种分区类型:RANGE分区.LIST分区.HASH分区 ...

  6. SQL Server 表变量和临时表的区别

    SQL Server 表变量和临时表的区别 一.表变量 表变量在SQL Server 2000中首次被引入.表变量的具体定义包括列定义,列名,数据类型和约束.而在表变量中可以使用的约束包括主键约束,唯 ...

  7. SQL Server表分区【转】

    转自:http://www.cnblogs.com/knowledgesea/p/3696912.html SQL Server表分区   什么是表分区 一般情况下,我们建立数据库表时,表数据都存放在 ...

  8. SQL Server表分区详解

    原文:SQL Server表分区详解 什么是表分区 一般情况下,我们建立数据库表时,表数据都存放在一个文件里. 但是如果是分区表的话,表数据就会按照你指定的规则分放到不同的文件里,把一个大的数据文件拆 ...

  9. SQL Server 表的管理_关于完整性约束的详解(案例代码)

    SQL Server 表的管理之_关于完整性约束的详解 一.概述: ●约束是SQL Server提供的自动保持数据库完整性的一种方法, 它通过限制字段中数据.记录中数据和表之间的数据来保证数据的完整性 ...

随机推荐

  1. solrCloud设置Tomcat jvm内存解决内存溢出的问题

    几乎已经搜遍了整个网络,没有找到一篇解决设置solr在Tomcat下设置虚拟机内存的文章.   因为之前一直是在Tomcat中设置zkhost参数,在加上jvm参数后会无法启动,添加其他参数也没有生效 ...

  2. 微信小程序——Now you can provide attr "wx:key" for a "wx:for" to improve performance.

    在官方的swiper(滑块视图容器)中demo代码,运行时会出现Now you can provide attr "wx:key" for a "wx:for" ...

  3. macOS 中 apache vhosts 配置备忘

    1. 修改 apache 服务器指向的根目录 macOS 默置了 apache,有以下几个常用命令: sudo apachectl -v // 查看 apache 版本 httpd -v // 同上 ...

  4. DAY6-小变化(java提示框)-2018-1-16

    终于有一点点小变化了,今天学习了java里的对话框,有四种类型:1.确认对话框(showConfirmDialog) 2.可选择输入的对话框(showInputDialog) 3.信息对话框(show ...

  5. Nginx常用配置实例(4)

    Nginx作为一个HTTP服务器,在功能实现方面和性能方面都表现得非常卓越,完全可以与Apache相媲美,几乎可以实现Apache的所有功能,下面就介绍一些Nginx常用的配置实例,具体包含虚拟主机配 ...

  6. python网络数据采集(低音曲)

    废话不多说,马上开始. 上次我们说到遍历单个域名,今天我们来写一个爬对应词条的脚本,他会遍历整个网址直到爬完对应词条. 代码: from urllib.request import urlopen f ...

  7. NowCoder牛客练习赛7-A.骰子的游戏 B.购物-优先队列

    A.骰⼦的游戏 时间限制:C/C++ 1秒,其他语言2秒空间限制:C/C++ 32768K,其他语言65536K64bit IO Format: %lld 题目描述 在Alice和Bob面前的是两个骰 ...

  8. 防止ajax重复提交

    在jquery中防止ajax重复提交

  9. mysql 手册关于修改列字符编码的一个bug

    项目因为历史原因使用了 GBK编码,遇到非GBK编码字符时出现乱码问题,情况比较严重,暂时先打算修改 列的字符编码为 utf8mb4. 查看 mysql 手册: 用 GBK 编码转 utf8 进行说明 ...

  10. Vuex初识

    vuex是vue中单向数据流的一个状态管理模式,它可以集中存储管理应用中所有组件的状态,并且有一套相应的规则可以去预测数据的变化.类似与此的还有react中的redux,dva等状态管理模式. 一般我 ...