存储多个位 - 我应该使用多列还是单个位域列?

时间:2010-07-30 17:39:40

标签: sql sql-server-2005 sql-server-2008 database-design bit-fields

我正在我的数据库中设计一个User表。我为每个用户提供了大约30个左右的选项,可以是“允许”或“禁止”。

我的问题是我应该将这些列存储为30个bit列,还是应该使用单个int列来存储它们并解析我的应用程序中的每个位?

此外,我们的数据库是SQL Server 2008和2005(取决于环境)

5 个答案:

答案 0 :(得分:11)

我刚尝试创建两个表,一个包含一个int列,另一个包含30位列,然后为每个表添加一行,并使用SQL Server Internals Viewer

查看它们
CREATE TABLE T_INT(X INT DEFAULT 1073741823);

CREATE TABLE T_BIT(
X1  BIT DEFAULT 1,
/*Other columns omitted for brevity*/
X30 BIT DEFAULT 1
);

INSERT INTO T_INT DEFAULT VALUES;

INSERT INTO T_BIT DEFAULT VALUES;

包含30位列的表格的单行

BITS

包含一个int列的表的单行

INT

从存储的角度来看,SQL Server结合了位列,并且数据存储在完全相同的空间量(黄色)中。你最终会为NULL位图(紫色)连续丢失3个字节,但因为它的长度与列数成正比(不论它们是否允许空值)

字段键(对于int版本,颜色编码与位版本相同)

Int key

答案 1 :(得分:5)

两者都没有 - 除非您对其他系统存在重大的空间问题或兼容性要求,请考虑这将如何阻止您优化查询并清楚地了解每个位代表的内容。

您可以在表格中拥有超过一千列,或者您可以拥有一个用于用户设置的子表格。为什么要将自己限制在需要在应用程序中解析的30位?想象一下,如果不推荐使用其中一些设置或引入了几个新设置,您需要对应用程序进行哪些更改。

答案 2 :(得分:4)

如果每个值都有列,我认为允许将来扩展会更容易。如果您将来添加另一个选项(这可能适用于大多数此类应用程序),那么它可能会影响您的所有其他代码,因为您需要重新分析int列以考虑新位。

答案 3 :(得分:4)

如果你组合成一个bitflag字段,如果你正在查看原始数据,将很难看到设置的内容。我会为每个值使用单独的列,或将选项存储在自己的表中。

答案 4 :(得分:1)

我同意您的设计应该正确规范化,三个表用户和用户设置,以及桥接表:

用户:

Userid int

UserName varchar(X)

<强> UserSetting

Settingid int

SettingName varchar(X)

<强> UserUserSetting:

Userid int

SettingId int

IsSet位

桥接表 UserUserSetting UserSetting 和用户表之间会有FK,并且 UserUserSetting