SQL Server TinyInt的存储


12

在SQL Server中,为什么将tinyint与9B存储在行中。由于某种原因,在NULL位图掩码的末尾似乎还有一个字节。

    使用tempdb;
    走

    创建表tbl
    (
        我TINYINT不为空
    );
    走

    插入tbl(i)
        值(1);
    走

    DBCC IND('tempdb','tbl',-1);
    走

    DBCC TRACEON(3604); -页面转储将进入控制台
    走

    DBCC PAGE('tempdb',1,168,3);
    走

结果(由于DBCC PAGE首先显示了最低有效字节,所以我反转了字节):

Record Size = 9B
10000500 01010000 00
TagA = 0x10 = 1B
TagB = 0x00 = 1B
Null Bitmap Offset = 0x0005 = 2B
Our integer column = 0x01 = 1B
Column Count = 0x0001 = 2B
NULL Bitmap = 0x0000 = 2B (what!?)

1
这只是教育吗?我全都在需要时修剪空间,但这可能不是我要担心的1个字节……
Aaron Bertrand

这是教育性的。我的下一个SQLSaturday演讲是关于compressin;因此,我为每种数据类型创建了示例,以帮助人们理解其数据类型选择的含义并显示压缩对所有数据类型的影响。
ooutwire 2012年

我假设tinyint将以1B(它)的形式存储,而开销为7B。我想知道记录末尾的额外字节是多少???
ooutwire 2012年

当TINYINT列不是表中的唯一列时,我会看到不同的结果(尽管不确定它们是否与您的期望更加一致)。似乎是一个非常罕见的用例。
亚伦·伯特兰

当然不是用例的共同关注点。我只是试图仅显示每种数据类型,以便既了解存储所涉及的间接费用,又让初学者了解页面上列的外观。我觉得有多余的字节很奇怪...让我疯狂地看到它而没有理由。
ooutwire 2012年

Answers:


12

如果使用简单的大小加法计算记录,则确实会得到8:4 + 1 + 2 + 1(标题+固定大小+空位图计数+空位图本身)。但是,堆记录不能小于 9字节的转发存根大小,因为记录必须保证可以将其替换为转发存根。因此,记录将实际减少9个字节。smallint通过计算和最小大小,A 均为9字节。任何更大的东西已经比转发存根更大,因此您的计算大小与记录大小匹配。


9个字节也适用于此定义,CREATE TABLE tbl (i TINYINT NOT NULL PRIMARY KEY)所以这是否只是所有行的通用规则,无论它们是否是堆的一部分?
马丁·史密斯

1
可以将b树转换为堆(alter table ... drop constraint),并且该操作不是完全重建(b树的上部页面被丢弃,左侧的叶子页面被取消链接,结果堆),因此保留逻辑仍然适用。
Remus Rusanu 2012年

我认为这证明了什么莱姆斯曾表示... improve.dk/archive/2011/06/07/...
ooutwire

6

听到作者的声音真是太好了。:-) Kalen怀疑这只是强制执行某种最小行长度,将<9填充为9。当然,在少数情况下,这是可能的。您将找到TINYINT和BIT以及VARCHAR(1)/ CHAR(1)的此幻影字节。如果移至SMALLINT或CHAR(2),它将不会增加到9以上,但是如果移至CHAR(3),它将增加。

因此,从本质上讲,您可以指出通过明智地选择数据类型可以获得的效率,但是要指出,在某些极端情况下,由于存储层的其他因素,规则不成立。

编辑我希望为您提供更多具体信息。只是想让您知道,这就是“内部知识”书的作者当前的想法。她不是100%肯定的。


感谢Aaron与Kalen取得联系。昨晚我正在翻阅那本书,把头发拉出来。这有点像sql_variant的额外元数据字节,除了在这里我没有办法解释除了手挥舞和大喊“这就是好朋友的方式”之外的幻影字节。
ooutwire 2012年

1
好吧,您可以将该注释与“这是一个极端的情况,因为设计用于在每行中存储单个tinyint或char(1)的表并不多”。
亚伦·伯特兰
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.