2

I am starting a new Project for a website based on "Talents" - for example:

  • Models
  • Actors
  • Singers
  • Dancers
  • Musicians

The way I propose to do this is that each of these talents will have its own table and include a user_id field to map the record to a specific user.

Any user who signs up on the website can create a profile for one or more of these talents. A talent can have sub-talents, for example an actor can be a tv actor or a theatre actor or a voiceover actor.

So for example I have User A - he is a Model (Catwalk Model) and an Actor (TV actor, Theatre actor, Voiceover actor).

My questions are:

  1. Do I need to create separate tables to store sub-talents of this user?

  2. How should I perform the lookups of the top-level talents for this user? I.e. in the user table should there be fields for the ID of each talent? Or should I perform a lookup in each top-level talent table to see if that user_id exists in there?

  3. Anything else I should be aware of?

MAX POWER
  • 5,213
  • 15
  • 89
  • 141

4 Answers4

3

before answering your questions... i think that user_id should not be in the Talents table... the main idea here is that "for 1 talent you have many users, and for one user you have multiple talent".. so the relation should be NxN, you'll need an intermediary table

see: many to many

now

Do I need to create seperate tables to store sub-talents of this user?

if you want to do something dynamic (add or remove subtalents) you can use a recursive relationship. That is a table that is related to itself

TABLE TALENT
-------------
id  PK
label
parent_id PK FK (a foreign key to table Talent)

see : recursive associations

How should I perform the lookups of the top-level talents for this user? I.e. in the user table should there be fields for the ID of each talent? Or should I perform a lookup in each top-level talent table to see if that user_id exists in there?

if you're using the model before, it could be a nightmare to make queries, because your table Talents is now a TREE that can contain multiple levels.. you might want to restrict yourself to a certain number of levels that you want in your Talent's table i guess two is enough.. that way your queries will be easier

Anything else I should be aware of?

when using recursive relations... the foreign key should alow nulls because the top levels talents wont have a parent_id...

Good luck! :)

EDIT: ok.. i've created the model.. to explain it better

model

Edit Second model (in the shape of a Christmas tree =D ) Note that the relation between Model & Talent and Actor & Talent is a 1x1 relation, there are different ways to do that (the same link on the comments)

alt text

to find if user has talents.. join the three tables on the query =) hope this helps

pleasedontbelong
  • 19,542
  • 12
  • 53
  • 77
  • Hi, I think this may have been misunderstood, but basically what I'm trying to say is there will be separate talent tables, in which I create entries for each user that has that talent. The fields in each talent table would be related to that particular talent. – MAX POWER Dec 01 '10 at 15:15
  • @pleasedontbelog +1 @GSTAR, actually I don't think it has been misunderstood. I suspect that you can not see how to get all the talents user has from the above design? If so, let us know and we can demonstrate how to get all the talents user has, or all users with a talent, etc... – Unreason Dec 01 '10 at 16:47
  • Hi again pleasedontbelong. What do I do if I want to store talent-specific information? For example I need to store information that is specific to models or specific to actors. Suppose I create another two tables (models, actors) - how should these be linked to the User? – MAX POWER Dec 09 '10 at 01:59
  • ...I assume it should link to the talent_user table but I can't work out how. I don't see the point in inserting a user_id field in the new table either... – MAX POWER Dec 09 '10 at 02:10
  • .. so you have different types of users (actors and models) and depending on the type of user, you need to relate specific talents, for example: Actors can be related only with talents "singing","dancing","crying", while Models can only be related to talents such as "posing","smiling" and "vomiting".. or what kind of info you need to store?.. give me examples :) – pleasedontbelong Dec 09 '10 at 10:07
  • Basically on the user's admin section of the site the user will first be able to select what Talents they have - these are stored in the Talent_User table. The user can then go in to each of their selected talents and provide more information. For example for a Model talent they can specify their hourly rate, for an Actor talent they can specify how many years experience. These attributes will not be the same for each talent, so I don't think they could just be stored in one table. – MAX POWER Dec 09 '10 at 11:32
  • ahhhhhhhhhh ok, now i see.. there are two ways to do it.. the elegant way, using subclasses maybe http://www.tomjewett.com/dbdesign/dbdesign.php?page=subclass.php, so you'd have multiple tables like "TalentModel", "TalentActor" each one of them related to users in NxN using intermediary tables and eachone extending the Talent table... The inelegant way: add a certain number of attributes to the Talent_User (5 or 10 maybe?) and is up to you to define how to use those attributes, for exemple for a Model, the first attribute will use the first attribute to store years of experience – pleasedontbelong Dec 09 '10 at 14:27
  • the problem here is that (i think) Talents are not static.. and you can add talents on the admin section, is that right? so you need something like dynamic tables, and that's always difficult – pleasedontbelong Dec 09 '10 at 14:30
  • Hi mate, thanks for that. Yes, I prefer the method whereby I have seperate tables for each talent. Would you mind updating your ER diagram above to show how these tables would be linked? – MAX POWER Dec 09 '10 at 14:51
  • Thanks for that. I see the Talent_User table is no longer present - the only slight issue with that is there is no easy way to get the list of talents that a user has. – MAX POWER Dec 09 '10 at 18:01
  • Hi mate, can you please advise how I would go about getting the list of Talents that a user has? In the previous diagram we could easily just do one query on the talent_user table. – MAX POWER Dec 10 '10 at 01:26
  • forget everything i've said... i didn't understood you question and then i suddenly assumed that you had a Talents table... reading you question again i realize that what you need is to represent inheritance in databases.. i'll post a new answer – pleasedontbelong Dec 10 '10 at 09:37
2

You should have one table that has everything about the user (name, dob, any other information about the user). You should have one table that has everything about talents (id, talentName, TopLevelTalentID (to store the "sub" talents put a reference to the "Parent" talent)). You should have a third table for the many to many relationship between users and talents: UserTalents which stores the UserID and the TalentID.

Here's an article that explains how to get to 3rd NF:

http://www.deeptraining.com/litwin/dbdesign/FundamentalsOfRelationalDatabaseDesign.aspx

Leslie
  • 3,604
  • 7
  • 38
  • 53
2

This is a good question to show some of the differences and similarities between object oriented thinking and relational modelling.

First of all there are no strict rules regarding creating the tables, it depends on the problem space you are trying to model (however, having a field for each of the tables is not necessary at all and constitutes a design fault - mainly because it is inflexible and hard to query). For example perfectly acceptable design in this case is to have tables

Names (Name, Email, Bio)

Talents (TalentType references TalentTypes, Email references Names)

TalentTypes (TalentType, Description, Parent references TalentTypes)

The above design would allow you to have hierarchical TalentTypes and also to keep track which names have which talents, you would have a single table from which you could get all names (to avoid registering duplicates), you have a single table from which you could get a list of talents and you can add new talent types and/or subtypes easily.

If you really need to store some special fileds on each of the talent types you can still add these as tables that reference general talents table. As an illustration

Models (Email references Talents, ModelingSalary) -- with a check constraint that talents contain a record with modelling talent type

Do notice that this is only an illustration, it might be sensible to have Salary in the Talents table and not to have tables for specific talents.

If you do end up with tables for specific talents in a sense you can look at Talents table as sort of a class from which a particular talent or sub-talent inherits properties.

Unreason
  • 12,556
  • 2
  • 34
  • 50
1

ok sorry for the incorrect answer.. this is a different approach.

The way i see it, a user can have multiple occupations (Actor, Model, Musician, etc.) Usually what i do is think in objects first then translate it into tables. In P.O.O. you'd have a class User and subclasses Actor, Model, etc. each one of them could also have subclasses like TvActor, VoiceOverActor... in a DB you'd have a table for each talent and subtalent, all of them share the same primary key (the id of the user) so if the user 4 is and Actor and a Model, you would have one registry on the Actor's Table and another on the Model Table, both with id=4

As you can see, storing is easy.. the complicated part is to retrieve the info. That's because databases dont have the notion of inheritance (i think mysql has but i haven't tried it).. so if you want to now the subclases of the user 4, i see three options:

  • multiple SELECTs for each talent and subtalent table that you have, asking if their id is 4.

    SELECT * FROM Actor WHERE id=4;SELECT * FROM TvActor WHERE id=4;

  • Make a big query joining all talent and subtalent table on a left join

    SELECT * from User LEFT JOIN Actor ON User.id=Actor.id LEFT JOIN TvActor ON User.id=TvActor.id LEFT JOIN... WHERE User.id=4;

  • create a Talents table in a NxN relation with User to store a reference of each talent and subtalents that the User has, so you wont have to ask all of the tables. You'd have to make a query on the Talents table to find out what tables you'll need to ask on a second query.

alt text

Each one of these three options have their pros and cons.. maybe there's another one =)

Good Luck

PS: ahh i found another option here or maybe it's just the second option improved

pleasedontbelong
  • 19,542
  • 12
  • 53
  • 77
  • Cheers mate - I think I will probably go for the third option. There is obviously some replication of data (storing the list of talents for each user) so I have to ensure when a user talent is deleted, the entries in both tables are deleted. But other than that it's all good! – MAX POWER Dec 10 '10 at 11:24
  • Hi mate, just one last quick question - in my talent_user table I plan to include an "active" field - this will determine if the user has switched that talent on/off. So when I do my query to find all models, I want to find all models where active=1. How would I create the join for this? – MAX POWER Dec 10 '10 at 11:44
  • i dont think that you need an "active" field.. the idea is that.. if a User is a Model and a TvActor,then in the Talent_User table, this user will only be related to the talent "Model" and the talent "TvActor".. that's how you know what talents a user has. Once you know the talents related to the user, ask the proper tables =) I know.. its complicated – pleasedontbelong Dec 10 '10 at 11:58
  • No what I'm saying is the user wil be able to manually switch off a talent (as opposed to completely removing it). The record will remain in the DB - it will just say that it's not active. I was thinking it would make sense to have this switch in the talent_user table.. or would it cause less headache if we put the switch in the actual table - e.g. model or actor table. – MAX POWER Dec 10 '10 at 12:04