我正在我的数据库中设计一个User
表。我为每个用户提供了大约30个左右的选项,可以是“允许”或“禁止”。
我的问题是我应该将这些列存储为30个bit
列,还是应该使用单个int
列来存储它们并解析我的应用程序中的每个位?
此外,我们的数据库是SQL Server 2008和2005(取决于环境)
答案 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位列的表格的单行
包含一个int列的表的单行
从存储的角度来看,SQL Server结合了位列,并且数据存储在完全相同的空间量(黄色)中。你最终会为NULL位图(紫色)连续丢失3个字节,但因为它的长度与列数成正比(不论它们是否允许空值)
字段键(对于int版本,颜色编码与位版本相同)
答案 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位p>
桥接表 UserUserSetting 与 UserSetting 和用户表之间会有FK,并且 UserUserSetting