views:

87

answers:

4

I'm trying to finalize my design of the data model for my project, and am having difficulty figuring out which way to go with it.

I have a table of users, and an undetermined number of attributes that apply to that user. The attributes are in almost every case optional, so null values are allowed. Each of these attributes are one to one for the user. Should I put them on the same table, and keep adding columns when attributes are added (making the user table quite wide), or should I put each attribute on a separate table with a foreign key to the user table.

I have decided against using the EAV model.

Thanks!

Edit

Properties include thing like marital status, gender, age, first and last name, occupation, etc. All are optional.

+2  A: 

Could you give some examples of what kind of properties you'd want to add to the user table? As long as you stay below roughly 50 columns, it shouldn't be a big deal.

How ever, one way would be to split the data:

One table (users) for username, hashed_password, last_login, last_ip, current_ip etc, another table (profiles) for display_name, birth_day etc.

You'd link them either via the same id property or you'd add an user_id column to the other tables.

Maxem
+2  A: 

It depends.

You need to Look at what percentage of users will have that attribute. If the attribute is 'WalkedOnTheMoon' then split it out, if it is 'Sex' include it on the user's table. Also consider the number of columns on the base table, a few, 10-20, won't hurt that much.

If you have several related attributes you could group them into a common table: 'MedicalSchoolId', 'MedicalSpeciality', 'ResidencyHospitalId', etc. could be combined in UserMedical table.

KM
Don't store an age, store a birth date.
KM
+2  A: 

Tables:

  • USERS
  • USER_PREFERENCE_TYPE_CODES
  • USER_PREFERENCES

USER_PREFERENCES is a many-to-many table, connecting the USERS and USER_PREFERENCE_TYPE_CODES tables. This will allow you to normalize the preference type attribute, while still being flexible to add preferences without needing an ALTER TABLE statement.

OMG Ponies
So in type_codes, I'd have 2 columns: id and name. Then, in preferences, I'd have a type id, a user id, and a value?It seems like this locks up the preferences table to 3 columns. However, if I have an attribute called 'address' that holds country, region, city, county, latitute, longitude, etc, how do I account for this? Should I use the model you suggested and simply break out address into its own table?
DexterW
@Greelmo: Yes, I recommend that commonly grouped information, like an address (mailing, office, etc), should be modelled to be its own table rather than a preference.
OMG Ponies
@Greelmo: Also, either make the `user_id` and `preference_type_code` columns in the `USER_PREFERENCES` table the primary key, or at least have a unique constraint (index if using SQL Server) on them.
OMG Ponies
+2  A: 

Personally I would decide on whether there are natural groupings of attributes. You might put the most commonly queried in the user table and the others in a separate table with a one-to-one relationship to keep the table from being too wide (we usually call that something like User_Extended). If some of the attributes fall into natural groupings, they may call for a separate table because those attributes will usually be queried together.

In looking at the attributes, examine if some can be combined into one column (for instance if a user cannot simlutaneoulsy be three differnt things (say intern, resident, attending) but only one of them at a time, it is better to have one field and put the data into it rather than three bit fields that have to be transalted. This is especially true if you will need to use a case statement with all three fileds to get the information (say title) that you want in reporting. IN other words look over your attributes and see if they are truly separate or if they can be abstracted into a more general one.

HLGEM