views:

70

answers:

5

Hello, I am designing a User table in my database. I have about 30 or so options for each user that can be either "allow" or "disallow".

My question is should I store these as 30 bit columns or should I use a single int column to store them and parse out each bit in my application?

Also, our database is SQL Server 2008 and 2005 (depending on environment)

+3  A: 

I think it would be easier to allow for future expansion if you have columns for each value. If you add another option in the future (which is likely for most applications like this), then it may affect all your other code since you would need to reparse your int column to account for the new bits.

JNK
+2  A: 

Neither -- unless you have a major space issue or compatibility requirement with some other system, think about how this will prevent you from optimizing your queries and clearly understanding what each bit represents.

You can have more than a thousand columns in a table, or you can have a child table for user settings. Why limit yourself to 30 bits that you need to parse in your app? Imagine what kind of changes you'll need to make to the app if several of these settings are deprecated or a couple of new ones introduced.

Cahit
+2  A: 

If you combine into a bitflag field, it's going to be difficult to see what is set if you're looking at the raw data. I'd go with individual columns for each value, or store the options in their own table.

David
+5  A: 

I just tried creating two tables, one with a single int column and one with 30 bit columns then added a row to each and looked at them with SQL Server Internals Viewer

Single row for table with 30 Bit Columns

Bits

Single row for table with one int Column

Int

From a storage point of view SQL Server combines the bit columns and the data is stored exactly the same (yellow). You do end up losing 3 bytes a row for the NULL bitmap (purple) though as the length of this is directly proportional to the number of columns (irrespective of whether they allow nulls)

Key for fields (for the int version, colour coding is the same for the bit version)

Int

Martin Smith
+1 for giving the technical details
Earlz
+1  A: 

I agree your design should be properly normalized, three tables User and User setting, and a bridge table:

User:

Userid int

UserName varchar(X)

UserSetting:

Settingid int

SettingName varchar(X)

UserUserSetting:

Userid int

SettingId int

IsSet bit

There would be FK's between the bridge table UserUserSetting and the UserSetting and User table and a unique contr constraint of t UserId, SettingId in UserUserSetting

JasonHorner
+1 Bravo for normalization. However, is the `UserUserSetting` needed. Shouldn't the existence of a row indicate that the user setting is enabled for the user?
bobs
Treating each user setting as an attribute rather than an entity doesn't necessarily violate 1NF. The way the question is phrased, however does treat a "user setting" as a generic concept; in this model user setting is an entity and needs a table. More information about how user settings are used and specific examples are needed to understand which approach is a better fit.
Paul Keister