I want to make an application where there will be different users and each user will have a set of friends which will be put in categories. There will be some default categories, but the user will be able to add his own. I was wondering which will be the best way to do this.
My idea is to have 3 tables – user, friends and categories.
The user table to have fields (one to many) for friends and categories (but I don’t know if the user table will need any information about the friends and the categories at all).
The friends table to have a field for categories (one to many) and a field for the user (many to one).
The category table to have fields for user (many to many?) and friends (many to many?).
I’m not sure about the relations, too. I’m using PHP with MySQL and Symfony2 and Doctrine2. Please help!
EDIT
Maybe I haven’t described exactly what I need. When you open the app, you see a login form. If you don’t have an account, you should register – the registration creates a new user. This user isn’t connected with other users (I’m still new to programming and I want something a little easier so it’s something like phonebook). Each user has a list of friends and a firend is a row in a table with fields such as name, addres, phone, email, photo, birthday and so on, but they are added by the current user. The friends are not users. Every user is in fact an account with password and username and when you log in there is just a list of friends. So each user creates categories for himself and he has nothing to do with other users and their categories. The category will have only id and name.
So the idea is that you create an account, then create some categories and add friends to them just to have an organiser when you friends are born or where they live, or which is their phone number, but you create them and add the information about them, they are to users themselves. It’s not like a social network. Just a notebook where each user can write info about his friends.
First of all, you need to understand the role of intersection tables: if user A labels user B as a friend (i.e. there is a many-to-many relation from
userto itself), and you create a new table to represent that relation (thefriendstable), any additional information about this “friendship” should be linked to that table. So, if a user categorizes his friends in some way, the category applies tofriends, not touser. There’s no need for a relation betweencategoryanduserfor this specific purpose.Update: since friends are not users, the
friendstable will not be an intersection table (and thus have only one reference back touser, denoting the “owner”), but the rest of the answer still applies.I’m assuming each category will be a row in the
categorytable. Additional information about the category might be added, but it should be limited to that. For instance, if you want to know which user created a category, you could add a foreign key touserlabeled for instance “owner” or “created_by”. That might be useful if categories created by one user are not to be seen by others.Finally, you can relate
friendswithcategory. If User A can put user B in at most one category, then a foreign key fromfriendstocategoryshould suffice (i.e. a one to many relation). Otherwise, you might need another many-to-many relation, so an additional intersection table should be created (for instancefriend_category).You could avoid this extra table by employing denormalization, having multiple rows in
friendswhere both users are the same (and in the same order) but the category is different (see also this example). Whether this is advantageous or not is beyond the scope of this answer, but IMHO using an extra table is better for now (it might seem more complicated, but it will be easier to maintain in the long run). (Update: iffriendsis not an intersection table, denormalizing like this is not really an option, so stick with thefriend_categorytable)In the end, your layout would look like this: