User
- Groups
- Link
- User1
- User2
- Time (or some other relevant link data)
- Posts
- Link
A user can only see a post if the user belongs to a link that belongs to the same group to which the post belongs.
I would like to optimize the database for querying all posts that a given user is allowed to see. What is the best way to structure the database to do this?
Thanks for the help!
EDIT: The above schema is a basic idea to get you started. Thanks again!
This is how I would model this:
Users(id, etc)
This is the user list. It contains only user data. The PK will be the
id, so there will be an implicit index thereGroups(id, etc)
This is the group list. It contains only group data. The PK will be the
id, so there will be an implicit index thereUser_Groups(userId, groupId, etc)
This is the way to link users to groups. It needs to have the foreing keys to the users and groups and you can add any additional data to it, for instance, date when the user joined the group. The PK here will be a compound key between
userIdandgroupId, so the index will beuserIdandgroupId. You will also want to have an additional index in thegroupId, because the “main order” will be given byuserId, not bygroupIdPosts(id, createdByUserId, belongsToGroupId, etc)
This is the lists of posts. Posts are created by only a user and belong to only one group. To display a post you’ll join createdByUserId with Users table (to display the name of the user who created the post). Additionally, you’ll want to check if the user who wants to see the post is actually allowed to see it. So, you’ll go to the User_Groups table and use a
WHEREclause similar to$currentUserId = users_groups.userId and $currentPostBelongsToGroupId = users_groups.groupId(OR you can join the table onpost.belongsToGroupId = user_groups.groupId).This is the general idea. Now, to focus on “optimize the database for querying all posts that a given user is allowed to see” you should basically do what I stated in the Posts entity description. As you’re not looking for a particular post you’ll have to join Posts with User_Groups (this join will use the
groupIdindex created on the User_Groups entity) and then use theWHEREclause stated there too. That clause will use the compound primary key created on that entity. And that’s it. It seems to be a fully indexed path.Now, why didn’t I add the
linkentity you’ve got on your question? Because I’ve not idea what it is and you didn’t answer my comment on top asking what it was. If it was a link between 2 users then it shouldn’t belong to a group because users belong to groups separately, not in pairs. Apart from that, if the link is what I assumed then it wouldn’t affect at all the performance on how a user see his/her own allowed posts. Possibly related question to thelinkentityHope this helps or guide you to a better solution 🙂