用于存储标志数组(位图/位数组)的数据类型


15

我需要为表的每个记录存储一个位数组,以支持以下操作:

  • 测试是否设置了一个位,并设置了一个位(使用SQL)

  • 使用ADO 2.8(而非ADO.NET)查询和设置值

  • 索引编制(为了从“覆盖索引”功能中受益)

此数组中要存储的最大位数是固定的,但可以超过32。也就是说,简单的int列并不总是有效。

到目前为止,我的选择是:

  1. 使用多个int
  2. 使用bigint(只要位数小于等于64即可工作)
  3. 使用二进制

第一个选项可以工作,但是需要在访问数据的代码中进行大量重构。第二种选择只是暂时的解决方案,到目前为止,根据我的搜索,我不太确定ADO是否可以与bigint一起使用。我没有使用binary的经验,并且不知道其他任何选项。

根据要求,您会选择哪种数据类型?

Answers:


12

我不能强烈主张不要为此使用单个字段。

我目前正在维护一个带有bigintbitmask字段的非常大的数据集,这是一场性能梦night。

如果您只检查一点就可以了。如果检查不止一位,性能将很快下降。

由于位掩码整数的性质,数据分布将非常不平衡,您将获得次优的计划。

多位检查会导致范围或索引扫描,并且每行都会运行一个函数。一团糟。

我的解决方法很简单-我制作了一个表来存储要检查的每个条件的PK。最初这是违反直觉的,但是所需空间很小(仅存储PK),并且查找速度很快,尤其是使用时UNIQUE CLUSTERED INDEX

您可以在不影响主表的情况下添加任意数量的条件,并且更新也不会影响主表。

索引很简单,因为您只需要对所有查找表进行单独索引,并且由于您的聚簇键在主表上相同,并且查找中的所有评估merge join都是非常有效的。


1
您能否详细说明解决方法?我发现此问题是因为我正在尝试解决同一基本问题,但不确定如何做到最好。
约书亚·弗兰克

4

如果您只需要存储少量的正确/错误值,则可以使用bit数据类型。

在内部,SQL Server存储bit打包为字节“块”的列。因此,对于bit表中最多8 列,SQL会将其存储为打包的1个字节;bit2个字节中的9-16 列,依此类推。

听起来好像您不会接近列数限制,所以这看起来很简单。当然,将它们很好地分隔开来可以使您为各列命名以提高可读性,并能像往常一样获得所有索引的可能性(如果标志是高度选择性的,那么如果您可以将2008+作为目标,则过滤后的索引可能会很有用)。

自己进行位打包将使索引工作变得更加复杂(可能是计算和索引的bit列代表了掩码的每个位置……但是,与bit直接使用相比,情况更糟)。

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.