【问题标题】:SQL Server nullable data types sizeSQL Server 可为空的数据类型大小
【发布时间】:2014-02-01 14:59:33
【问题描述】:

Microsoft SQL Server DBMS 中可为空的数据类型的大小是多少?

例如,不可为空的 int 应该占用 4 个字节,多少空间将专用于可空列?

子问题:可为空的 int、char(N)、nvarchar(N) - 我认为它们的存储方式可能不同。

我读到的:

  • Where to find the size of SQL Server data types - 为我的 SQL Server 版本获取 sql 类型列表及其大小的好方法。但对可空类型只字未提。
  • http://msdn.microsoft.com/en-us/library/ms189124.aspx - 有一个计算可变大小列所需空间的公式:“Variable_Data_Size = 2 + (Num_Variable_Cols x 2) + Max_Var_Size”。这很奇怪:为什么它包含 *2 乘数(没有任何关于 nvarchar 的说明 - 这个公式适用于所有可变大小的类型,如来自解释); Max_Var_Size 是相加而不是相乘的,一定是错字;最后它包含 +2 个字节用于存储值的长度,但又不包含用于存储 NULL 值的任何内容。据我了解,可以使用值长度 2 字节的剩余 3 位来存储 NULL 标识符,但它真的是这样存储的吗?
  • How much size "Null" value takes in SQL Server - 对我来说,最佳答案令人困惑。 @Mark Byers 说“如果字段是固定宽度,则存储 NULL 占用与任何其他值相同的空间 - 字段的宽度”,但不可能将标准整数值间隔和附加 NULL 值存储在相同的计数中位。然后“如果字段是可变宽度,则 NULL 值不占用空间” - 再次存储 NULL 根本不能占用空间 - 它必须为空值存储一些标记。与那里的其他答案类似的混淆:有人说它需要 2 个额外的字节,有人说它只需要 1 个字节。
  • http://home.clara.net/drdsl/MSSQL/DataTypes.html - 带有类型大小的漂亮表格,但同样没有专门用于 NULL 值。

【问题讨论】:

    标签: sql sql-server


    【解决方案1】:

    可空列和不可空列在数据页上占用完全相同的存储空间。每个数据页的一部分是空位图,它对表中的每个列都有一个位,即使是不可为空的。

    数据页的空位图部分仅存储可空列的位是一种常见的误解。这不是真的。空位图部分包含表中 all 列的可为空标志。 Here 是解释这个神话的一个很好的参考。 Here 是另一个。

    我想知道为什么 SQL Server(以及以前的 Sybase)使用这种结构。一种可能性是更改列的可空性可能是“快速”操作。尽管所有页面都发生了很大的变化,但通过引入一个新的 NULLable 字段不会出现页面拆分的危险。

    另一种可能性是它将页面上的布局与表元数据分离。虽然页面不知道列名,但它确实知道基于列索引的列的所有信息。

    【讨论】:

      【解决方案2】:

      根据微软支持

      1. SQL Server 2008 中的 NULL 值:

        -- SPARSE 需要 6 个字节加上行大小 + 每个非空列 4 个字节 + 值的字节(类型无关紧要)
        -- 常规的NULL值在NULL位图中需要1位

      2. SQL Server 2008 中的空字符串:

        -- 定长数据即使输入空字符串也需要数据的全部空间 -- 可变长度数据需要 2 个字节的开销来存储数据 -- 数值上没有空字符串 -- NULL 值在 NULL 位图中需要 1 位

      参考:http://social.msdn.microsoft.com/Forums/sqlserver/en-US/0404de89-70dc-4026-9e2e-13ddc3e7c058/null-data-storage-sql-server-2008?forum=sqldatabaseengine

      【讨论】:

      • 不错的链接,谢谢。这是我第一次听说稀疏列 =)。我不确定您是否可以确认,但它真的是额外的 1 位,还是占据了整个字节?因为 SQL server 中的 bit 数据类型实际使用了 1 个字节。
      • 顺便说一句,对于稀疏列,请考虑 this,部分 按数据类型估计的空间节省
      • @OleksandrPshenychnyy - SQL Server 会将 NULL 标志位打包到一个字节中,因此最多 8 个可为空的列只会产生一个字节的开销。
      猜你喜欢
      • 2015-07-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-11
      • 2011-09-22
      • 2017-09-20
      • 1970-01-01
      • 2012-03-01
      相关资源
      最近更新 更多