'Fetching tangentially related data via two sets of join tables

In a part of this database I have 3 main tables - for the sake of this we will call them Articles, Users and Equipment. Between these are two intermediary tables ArticleEquipment and UserEquipment which resolve the relationships.

ArticleEquipment can be considered a set of requirements for a user to view an article. If an article has no equipment, it's viewable by everyone. If an article does have equipment, the user should have all of the specified equipment assigned to their account. Therefore every equipment ID in a returned set of ArticleEquipment must be present in a set of UserEquipment, for a given user/article pair.

For individual articles this is fine and not too difficult to compare, but drawing up any kind of article listing for a single user makes this complicated, as both users and articles will have arrays of equipment. Additionally, if I want to completely hide categories that would have no visible articles inside them, this further complicates things.

The project is a legacy app written in PHP with CodeIgniter. The tables themselves are relatively large and so ideally I'd like to have the data filtered before it is returned to he application itself if at all possible. My first thought was to procedurally construct in statements using the currently logged in user's equipment, but this creates the inverse of the requirement (meaning that the article requires all of the user's equipment, rather than the user requiring all the article's equipment).

The other thing I thought about was having a central table which pre-calculates whether something is viewable and is updated whenever a change is made to a user or article. This way I could simply tie the viewability directly to my SQL queries without any live comparisons necessary - however this will result in a large amount of redundant data that will regularly need to be updated if there are changes to articles. However this is currently seeming like the easiest solution.

Are there any other, more efficient ways to achieve this?



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source