Answering strictly in terms of MySQL, you do not want to overnormalize.
Here is why ;
REASON #1 : JOIN BUFFER
There is an in-memory buffer called the join buffer. Its size is regulated in RAM by the join_buffer_size option per DB Connection. The more normalized the data are, the more
JOIN clauses. In turn, the more
JOIN clauses, the more join buffers have to be allocated. If a join buffer is too small, it gets migrated to disk. This slows down the query's execution by
- pausing the query to write the join buffer to disk
- generating more disk I/O while executing the join
REASON #2 : QUERY EVALUATION
Because MySQL executes SQL through external storage engines, query evaluation for WHERE clauses and JOIN clauses are virtually identical. I wrote about this back on March 11, 2013 (Is there an execution difference between a JOIN condition and a WHERE condition?). The algorithm for JOINs are also in the MySQL Documentation. The JOIN algorithm can get rather wonky with multiple JOIN clauses.
REASON #3 : STORAGE ENGINE PERFORMANCE
Any storage engine in MySQL is basically comprised of 14 operations. Those operations, including JOINs, are layered in such a way that performance issues can occur in two layers
- Query Evaluation (See Reason #2)
- Storage Engine
- If you JOIN using large columns
- If you use the wrong Storage Engine
- If you mix Storage Engines in the JOIN
It is strictly up to you how deep you want to normalize your data. If you must normalize and do multiple JOINs, please join only integer values only. Joining on character values will have negative effects on the three reasons I just mentioned.