In my website I have a forum in which you can start a thread, respond to one, delete your posts, report others’ posts, etc.
I decided to make an abstraction and to create a table called activity which would store the user_id, time (the fields every activity has in common), and the type of activity (thread, response, report, deletion) and the effective_id (the id that would correspond to respective table).
At the beginning this seemed like a great idea, because it would help to avoid redundancy and would make it easier to look up what a certain user has done without having to ask each table. But at the same time, this abstraction results in more complicated queries (e.g. having to use INNER JOIN in almost every simple query) and now I’m having trouble with more complex queries.
So my question is: did I take the right decision? Is in a real-life environment so important to have a perfect database even if it results in very expensive queries?
The whole point of relational database system is to relate data (by separating entities in the correct tables), by doing so you introduce joins. This is normal and a good database design technique.
A lot of database beginners try to avoid joins and add attributes from various entities to avoid having to do a
INNERjoin, but this is not a proper technique and will bite you in the long run. Joins are there for a reason and should be used when you need to relate data.In your example you are in essence creating a “log” file. The activity on your application is simply a log to what the user is doing. Ask yourself, what would be better a log for a post, a log for a report, a log for deletions, a log for, in addition many log tables or one simple log table with a referenceID as to what activity the user initiated (this in fact is a FK). The answer is you’d want one log table that contains a foreign key have you of what the user initiated (a delete, a add, a flag, etc).
The question you want to ask yourself though is, why are you displaying the activity information when a user simply wants to get this data. You can always keep this data normalized as you have but only select it when you need it. I don’t understand why you are joining to this activity table.