Ozr*_*ric 7 null sql-server memory
考虑来自 Microsoft SQL 文档页面的以下信息:
SQL Server 数据库引擎优化位列的存储。如果表中有 8 个或更少位列,则这些列存储为 1 个字节。如果有 9 到 16 位列,则这些列存储为 2 个字节,依此类推。
请参阅:https : //docs.microsoft.com/en-us/sql/t-sql/data-types/bit-transact-sql?view=sql-server-2017
所以,如果我创建一个这样的新表:
CREATE TABLE MyTable (
Id int PRIMARY KEY,
Value1 bit,
Value2 bit,
Value3 bit,
Value4 bit,
Value5 bit,
Value6 bit,
Value7 bit,
Value8 bit)
Run Code Online (Sandbox Code Playgroud)
...然后一行中的所有位列(Value1、Value2、...Value8)应占用一个字节。或者?
当我们仔细观察时,一行的 Value1 字段内部可以包含值 0、1 或 NULL。这意味着该字段实际上是三态值或三元值。2 个这样的值可以表示 3*3=9 个值的字典。8 个这样的值是一个包含 6561 个值的字典。
如果我们考虑这样一行的内存占用,8 位应该占用一个字节。这意味着这一字节编码 6561 个值而不是 256 个值。这显然是错误的。
因此,要么 MS SQL 文档具有误导性,要么我们在这里谈论一些量子计算。当然是前者,但我真正想知道的是这个问题的答案:可空位(当然,SQL Server 位默认可以为空)是如何真正存储在 SQL Server 底层结构中的?
Geo*_*ios 13
对于固定长度的字段(例如位值),该字段将始终占用相同的空间量 - 在您的情况下为一位。
该NULL位图是在数据行本身-这种存储在特定字段是否被认为是NULL与否。因此,字段本身只需要存储两个值 - 1 或 0 - NULL 位图处理该字段是否实际设置为 NULL。
NULL 位图对于表中的每一列都有一个位,无论该列是否可以为空,并且它包含您提到的“第三个值”。再次将空位图的空间向上舍入为整数字节。
以下代码演示了 SQL Server 如何存储 NULL 位图 - 如果您自己运行,则需要替换页码。
CREATE TABLE TestNullBitmap (
TestText CHAR(10) NULL
)
GO
INSERT INTO [dbo].[TestNullBitmap] ([TestText])
VALUES
('hello'),
('hello2'),
(NULL);
--Grab the page number
DBCC IND ([TestDb],TestNullBitmap,-1);
GO
--Use the page number from DBCC IND
DBCC PAGE ([TestDb],1,631032,3) WITH TABLERESULTS;
GO
Run Code Online (Sandbox Code Playgroud)
对我来说,我得到了三个数据行的以下结果:
0000000000000000: 10000e00 68656c6c 6f202020 20200100 00 ....你好...
0000000000000000:10000e00 68656c6c 6f322020 20200100 00 ....hello2 ...
0000000000000000:10000e00 68656c6c 6f322020 20200100 01 ....hello2 ...
NULL 位图是对最后一个字节值的更改 - 在 Little Endian 中读取的二进制表示是0000 0001(IE 第一列是 NULL)
相当有趣的是,您还可以看到系统已将前一个 INSERT 中的值存储为固定长度字段的实际数据 - 而不是将其从 0 中取出。
| 归档时间: |
|
| 查看次数: |
556 次 |
| 最近记录: |