regarding the LEFT OUTER JOIN issue...
LEFT OUTER JOIN retrieves all rows from the left table, together with matching rows from the right table, if any
so if there is a row from the left which has no match from the right, then the columns in the result row that would ahve come from the right are all set to NULL
with me so far?
okay, then the WHERE clause comes along, and says that the column from the right table has to be equal to a certain value
well, NULL is not equal to anything, so the unmatched rows all get thrown out
in effect, a condition on the WHERE clause for a column from the right table effectively turns the query into an inner join, because all the unmatched rows from the LEFT OUTER JOIN are thrown out
make sense?
okay, about your design....
your many-to-many table for categories is fine
still, it is almost exactly like the situation with a many-to-many table for keywords
the main points are:
1. numeric ids are ~not~ required (and may not even be advisable) in order to make a many-to-many relationship work
2. the keywords or categories table is only really needed if
2a. you want to control which values get used, or
2b. you're storing additional data for the keywords or categories
regarding 2a, you would not try to control values, for example, in a scheme where users can tag entities freely
regarding 2b, you might want to have a category hierarchy (e.g. see
Categories and Subcategories)