First of all, create indexes for each column that you can ignore. This way, your eligibility criteria will be found a little faster.
You can then create a staging table that collects the relationship between the user and the content that he blacklisted.
Maybe something like this:
userId | blacklistType | blacklistId 1 | user | 2 1 | category | 12 1 | word | 4
Now, if you need all categories for user 1, you can request
SELECT * FROM categories WHERE NOT EXISTS ( SELECT userId FROM blacklist WHERE userId = 1 AND blacklist.blacklistType = 'category' AND categories.id = blacklist.blacklistId )
(I'm not quite sure of the syntax here, but you should get this idea, I hope)
source share