为什么以及何时应该使用SPARSE COLUMN?(SQL SERVER 2008)

pri*_*kar 64 sql sql-server database-design sql-server-2008

在通过SQL SERVER 2008的新功能SPARSE COLUMN的一些教程之后,我发现如果列值为0或null它不占用任何空间但是当有值时,它需要4倍的常规空间(非稀疏)列保持.

如果我的理解是正确的,那么为什么我会在数据库设计时采用这种方法呢?如果我使用它,那么在什么情况下,我呢?

出于好奇,当列被定义为稀疏列时,怎么没有空间得到保留(我的意思是说,内部实现是什么)

提前致谢

Bra*_*adC 87

稀疏列不使用4倍的空间来存储值,它使用每个非空值的(固定的)4个额外字节.(正如您已经说过的,NULL占用0个空格.)

  • 因此,存储在位列中的非空值将是1位+4字节= 4.125字节.但如果其中99%为NULL,那么它仍然是净节省.

  • 存储在GUID(UniqueIdentifier)列中的非空值是16字节+4字节= 20字节.因此,如果其中只有50%为NULL,那仍然是净节省.

因此,"预期节省"在很大程度上取决于我们所讨论的专栏类型,以及您对什么比率的估计将为空与非空.可变宽度列(varchars)可能更难以准确预测.

书籍在线页面有一个表格,显示不同数据类型的百分比需要为空,以便最终获得收益.

那么什么时候应该使用稀疏列?当您希望相当大比例的行具有NULL值时.想到的一些例子:

  • 订单表中的" 订单退货日期 "列.您希望销售额的很小一部分会导致退回的产品.
  • 地址表中的" 第4个地址 "行.大多数邮寄地址,即使您需要部门名称和"关心",也可能不需要4个单独的行.
  • 客户表中的" 后缀 "列.相当低比例的人有​​"小".或者名字后面的"III"或"Esquire".

  • Row对我来说感觉非常误导.表有列,记录有字段,对吗?每个非空列4个字节可能不明确,但我不认为每个非空字段有4个字节.正如这个答案所暗示的那样,无论它有多少非空稀疏字段,每条记录都有4字节的上限. (4认同)
  • 有一个建议编辑,每个非null*字段*是4个额外字节.这是不正确的,我已经回过头来说*行*.为了澄清一个例子:如果我们有一个带有GUID字段的100行表,其中10行有值,90行是NULL.GUID字段通常是16个字节,因此正常(非稀疏)GUID将是16*100 = 1600字节.如果我们将其作为稀疏字段,则使用的空间将仅为(16 + 4)*10 = 200字节,而不是(16*10)+4 = 164字节.4字节惩罚适用于每个填充的行. (3认同)
  • 但可以肯定的是,如果一行中有多个稀疏字段,那么4字节的惩罚分别适用于每个*字段*?在这种情况下,更自然地说*每场*(这实际上意味着*每行每行*).实际上我花了很长时间才意识到你对每个字段*的理解*每个字段*每个字段*. (3认同)
  • 空间不是你应该考虑的唯一事情.更新加载也很重要 - 请记住,无论何时归零或引入值,您都要更改行长度,因此必须重建并可能拆分页面.因此,虽然一个人的姓名后缀或地址第4行仍然是稀疏的良好候选人,但返回日期可能不是 - 如果你说亚马逊,你可能会更乐意咀嚼空间以降低更新的成本. (2认同)

rah*_*hul 23

  • 在稀疏列中存储null不会占用任何空间.

  • 对于任何外部应用程序,该列的行为都相同

  • 稀疏列对过滤索引非常有效,因为您只想创建索引来处理列中的非空属性.

  • 您可以在稀疏列上创建一个列集,该列返回集合所覆盖的列中所有非空数据的xml剪辑.列集的行为类似于列本身.注意:每个表只能设置一列.

  • 更改数据捕获和事务复制都可以,但不是列集功能.

缺点

  • 如果稀疏列中包含数据,则它将比正常列多4个字节,例如,即使一个位(通常为0.125个字节)为4.125个字节,并且唯一标识符从16个字节上升到20个字节.

  • 并非所有数据类型都是稀疏的:具有FILESTREAM属性的text,ntext,image,timestamp,用户定义的数据类型,几何或地理或varbinray(max)不能是稀疏的.(Changed17/5/2009感谢Alex发现错字)

  • 计算列不能稀疏(尽管稀疏列可以参与另一个计算列的计算)

  • 您无法应用规则或具有默认值.

  • 稀疏列不能构成聚簇索引的一部分.如果需要这样做,请使用基于稀疏列的计算列,并在其上创建聚簇索引(这类对象会失败).

  • 合并复制不起作用.

  • 数据压缩不起作用.

  • 访问(读取和写入)稀疏列更昂贵,但我无法找到任何确切的数字.

参考