@Kulga I think it's beter if i post some examples in another thread, 'Dev' probably. Normalisation is probably the main thing to keep in mind.
I tried to motivate and keep everything as understandable as possible. Ok here we go.
Users
discussions_count / comments_count
The table users looks good, until I saw the columns "discussions_count" and "comments_count", values that can be calculated/looked up shouldn't be stored. Don't be afraid of COUNT(), its performance might surprise you.
preferences
“preferences” is a BLOB type and holds all the users preferences in a json format. If you want to read or edit one of those preferences, the server will need to load this data into the ram, find the correct preference, edit it (or do something else with it) and put it back. Seems like a lot of trouble.
Creating a new table e.g. user_preferences with ‘user_id’ as a key is a great alternative.
Getting or updating a field this way is just as easy as executing a simple SELECT, no further serialization needed, here you only come in contact with the data you actually need.
{"notify_discussionRenamed_alert":true,"notify_postLiked_alert":true,"notify_discussionLocked_alert":true,"notify_postMentioned_alert":true,"notify_postMentioned_email":false,"notify_userMentioned_alert":true,"notify_userMentioned_email":false,"notify_newPost_alert":true,"notify_newPost_email":true,"followAfterReply":false,"discloseOnline":true,"indexProfile":true}
↑ This blob of text of 381 bytes becomes 12 bytes (note: per user):
(12 booleans, tinyint takes up 1 byte hence 12 bytes)
We are just talking about a few bytes here, the savings are indeed negligible. But look at it from a performance point of view. If you want to lookup 1 preference, well now you’ll just come in contact with that 1 byte.
notifications_read_time
I’m not sure but I assume “notifications_read_time” has to do with the notification centre. If it does, might using cookies render this column not useless? Then again I’m not sure about this one.
NOTE: This might also be the case with “flags_read_time”, but this is an extension.
read_time
For my own curiosity, what does “read_time” do? The naming is quite vague within the current table.
posts
type
This is a red flag. Duplicate data, it breaks the rules of normalisation. Beter to define the types in a new table and point to it with an id.
discussions
discussions_count / participants_count
Same as before. Don't be afraid of COUNT(), its performance might surprise you.
discussions (in general)
Looking at the big picture, there is something not completely right here. I can see the choice that was made to completely separate every post including ‘the original discussion message’. But the amount of unnecessary information that is stored is, well weird.
All this can be looked up, why is this stored again?
~Cheers