views:

277

answers:

4

I need to develop an application where there will be 4 types of user entities (administrators, partners, companies and clients), each user type has it's own set of details and they all should be able to do common operations like send messages, make payments and so on. These operations should be kept on a single table but they need to reference the exact user despite it's type.

What database design would be more appropriate?

A: 
user
================
id
user_type_id
name
etc

user_type
================
id
name (admin, partner...)
etc

user_detail
================
id
user_id
user_detail_type_id
value

user_detail_type
================
id
name

user_type_to_user_detail_type
================
id
user_type_id
user_detail_type_id
(maps which user types have which detail types)
chaos
-1: Sorry, but this design cannot be recommended.
jug
+5  A: 

I'd say this is a perfect case for inheritance. Put the common attributes in one table and inherit that to add custom attribute for your different user types.

Chaos answer seems a bit messy to me, alltough it'd be useful if you don't know in advance what the properties you need to store are.

NA
How can this be adapted to MySQL?
Alix Axel
http://www.sqlteam.com/article/implementing-table-inheritance-in-sql-server gives an example of how to implement this without support in the db.
NA
+1, Thank you, I'll look into it!
Alix Axel
+2  A: 

Have a look at the three ways to do that in the Patterns of Enterprise Application Architecture:

http://martinfowler.com/eaaCatalog/singleTableInheritance.html

http://martinfowler.com/eaaCatalog/classTableInheritance.html

http://martinfowler.com/eaaCatalog/concreteTableInheritance.html

The choice depends on how many properties the 4 types of user entities will be sharing and also on the use cases that your system will require.

cherouvim
The Concrete Table Inheritance seems to be the right one for me, however my problem persists, how can I map each record in each table globally available non-repeated user id? For instance, how would I design the schema so that a footballer can send a message to a bowler? Or to receive payments, should I have a table payments for each user type? How can I have a payments_players instead of payments_footballers, payments_bowlers and payments_cricketers?
Alix Axel
If you use GUIDs or a sequence (the 4 entities have all different and unique ids) then it's possible. Otherwise your messaging system could be more generic (and independent of the inheritance mapping strategy). So you'd need a messages table with id, from_id, from_class, to_id, to_class, message.
cherouvim
+1  A: 

"I would just like to add one more thing, you suggest I have a table per each user type... I prefer this approach however how would I design a schema where I can say that user id 7 (admin) sent a message to user id 537 (client)? Or that a payment was received by user id 70 (company)?"

There is nothing to stop you from doing that. Have a table {sender recipient message(-id)} with primary key all three attributes and two FK {sender} and {recipient}. The FK's refer to the primary key of the table that holds the COMMON attributes of all users.

Now, your next question may be, "but I want a rule to say that no user of type X can directly send a message to any user of type Y".

That is the point where any current IMPLEMENTATION of a (so-called) relational DBMS shows its weaknesses. Even Oracle or DB2 can't do that declaratively. There is simply too very much for me to say about that subject to fit in this response.

BTW You seemed to have taken an interest in my response despite all the downvotes. Really appreciate that.

Erwin Smout
If you really wanted to enforce such a rule in the database you could denormalise the SENDER_RECIPIENTS table to include SENDER_TYPE and RECIPIENT_TYPE. It seems to me that that rule is a business rule, which shouldn't be enforced in the database anyway. After all, the rule might be, "when we are in the quiet period no user of type X can send messages to users of type Y or Z but otherwise it's okay". That would be really messy to enforce through declarative constraints. Which is why nature gave us Rule Engines.
APC
Thanks, that isn't the case however this question made me realize the importance of having a solid knowledge on the workings of FKs. You seem to be very knowledgeable and your solution seems be the correct way to go, thank you.
Alix Axel