views:

84

answers:

4

Say you have the following many-to-many table relation:

user
-----
id
first_name
last_name

user_prefs
----------------
id
preference_name

user2user_prefs
-------------
id
user_id
user_pref_id

But say you have the user preference of "homepage" and need somewhere to store the actual homepage url. Where would that go?

I can't put a value in user_prefs because then the same value would apply to everyone who has that mapping.

I CAN put it in user2user_prefs like so:

user2user_prefs
-------------
id
user_id
user_pref_id
value

But is this the best way in terms of normalization? Something doesn't feel quite right about the way im doing it (for one thing, i can't use an ENUM on the new "value" because it would have to contain all values for all preferences). Any thoughts?

Thanks! Stabby L

+2  A: 

You have to look at the functional dependencies. The value does not depend on the user, it does not depend on the userpref but it does depend on both. It would imply that you need to place it in the user2user_prefs tabvle as you suggested.

If you need to use an enum then the value attribute can look up the values in another table.

Vincent Ramdhanie
This is the answer i was secretly hoping for... thanks ;-)
+1  A: 

I can't put a value in user_prefs because then the same value would apply to everyone who has that mapping.

You're normalizing too far. The homepage would be fine in user_prefs.

In fact, if I were you, I'd use just one table:

user
-----
id
first_name
last_name
homepage
<other settings>

Foreign key relations, especially many-to-many relations, have a large cost in complexity. And the job of the software developer is to keep complexity under control.

Andomar
Would you still say that if homepage was only one of thirty different user preferences? that table would very large and flat
There's nothing wrong with a big fat table. The question is, what does a many to many relation add? To help you balance it, write two simple clients that use both designs. I think you'll find the experience of dealing with a many-to-many relation clarifying :)
Andomar
+1  A: 

It seems to me that particular type of value does not actually belong in the many-many relationship. If a specific property value is specific to each user, then it seems that should be a separate table. It "feels" like there would be a 1-many relationship from user to another table that has preferences unique to each user.

Edit: For the 1 to many table:

user_specific_prefs
------
id
user_id
pref_name (or possibly pref_id that indicates the type)
pref_value (store www.myhome.com for example)

The user_id is just the foreign key back to the specific user. This is essentially (in a logical sense) adding additional columns to the user table. But as Andomar points out, it does add complexity. But if you have a huge number of preferences like that, it might be good. On the other hand, I have seen tables with hundreds of columns. I'm not saying that is good (and I didn't create them), but they get the job done and are easy to use.

Mark Wilkins
This is interesting, but im not sure i grasp what your saying. Any hope you can draw up the tables?
Thanks for the edit. This was closer to my original setup
A: 

You're very close.

[Edit: My previously thought to be brilliant answer was not so brilliant.]

Edited tables:

users
-----
id
first_name
last_name
preferences

The preferences field would hold a serialized object or array of the specific users options. In PHP:

if ( is_array( $options ) || is_object( $options ) )
       serialize( $options );

Serialize Manual

Elizabeth Buckwalter
Using the preferences table like that would create a name/value pair that would be identical for each user, which was part of my original problem
You're right. Color:red, color:blue, color:orage. Hmmm
Elizabeth Buckwalter