MySQL M-N Relationship with extra attributes and permissions - mysql

I have a task in which I have to represent a M-N Relationship between a Users table and a Courses one. The goal is to allow only some Users (with a level of privilege) to see some Courses details(other tables related). The things get complicated because a user can have multiple privilege levels on different courses. For example - attending Course1 will give him privilege 1, watching Course2 will give him privilege 2 and so on. I am thinking to have a table users_courses which will store the relationship between a user and a course and also the privilege level (e.g. for columns: UserID | CourseID | Privilege).
The question is, can I create this join table including Privilege field ?
Is there another simpler approach ?

You can use RBAC pattern for that purpose. The picture below shows an example using users, permisions, and applicationes. In your case you would be using users, privileges and courses. You can also use roles for a better privileges handling.

Related

Do I need more than my current 3 tables in order to create the relationships explained in my post?

I'm trying to create a clone of a very popular application called Discord which allows people to communicate over voice, video, and text.
Discord allows every user to create their own servers and invite people to them. In order to allow users to create servers, I first created 2 tables - users and servers
Users table:
id, username, password
And
Servers table:
id, name, image, userId
So the relationship between these 2 tables is that a user can create and have many servers and a server belongs to a user. So far, so good.
Once a server is created, users can join the server as members of that server. A user can join as many servers as he wants and a server can have many members. I achieved this by creating a server_users junction table and a many-to-many relationship between users and servers:
Server_Users table:
id, userId, serverId
This works fine, however, I'm not sure if the logic behind the many-to-many relationship between users and servers is sound. To me it seems like I'm applying 2 relationships between users and servers and I don't know if this is correct. Maybe I need more tables to make the relationships clear?
User has many servers and a server belongs to a user ( Because a user is the owner/creator of a server, and the server belongs to only 1 user - his creator )
Server has many users and users have many servers ( As in every server can have many members and every member can be a part of many servers )
I think it's good design, almost a textbook example. The goal is that the tables are in normal form, which is the case here.
An alternate design also with three tables, if you would like to "merge" the two relationships, is to also use Server_Users to store the user who owns the server, marked as such with a boolean column. However, I think it is more efficient how you did it with a foreign key (userId), as you will only need one join for the 1-to-N relationship.
I would also add that the design of the table is not only motivated by getting this right "theoretically", but also by your use case. Picking a design depends on the kinds of queries that you will run against the database. If you list all users on a server including the owner, but never the owner alone, then the alternate approach may be faster.
Another aspect is integrity constraints: do you require that the owner of the server is also a member of that server, or is it fully independent? This also influences the design.
An alternative in the context of large quantities of data that do not get updated often, is to denormalize everything, by nesting the users (replicated) inside the server tuples.
I think your approaches are good.
As discribed before it's depending on your use cases or future functions.
In my opinion you have this possibilities:
Possibility 1
user
id
username
password
server
id
name
image
userId
adminId (references user id of admin/owner/creator)
user_server
id
userId
serverId
Possibility 2
user
id
username
password
server
id
name
image
userId
user_server
id
userId
serverId
admin (null if not an admin and true if an admin/owner/creator)
Possibility 3
user
id
username
password
server
id
name
image
userId
roleId (1=normal user, 2=admin,3=moderator)
user_server
id
userId
serverId
role
id
rolename
With possibility 1 you are limited to one owner of a server.
With possibility 2 you could add a "admin flag" to each user wich is allowed to manage the server. (like in chat groups of a messanger where exists multiple group admins)
With possibility 3 you could add a system to manage the rights of the corresponding users.

MySQL Database Structure for Club and Staff members Database

I am trying to develop a new website for event management system.
I want everyone to sign up as a simple user only and then if they chose to run event user can then create an Organisation and create events.
Every club will have lots of staff members who should then be able to log in and make changes into the event. Like accounting,event set up and entries, Refunds etc.
So I have created few roles like following
clubOwner :- All permission
eventManager :- Tier 1
treasurer :- Tier 2
Now how should I structure staff roles and permission table so that if in future creator of the club leaves that organisation he/she can easily nominate someone else clubOwner.
It is also the case that one eventManager handles events for different clubs or they can also run events under own Organisation name.
So far I have come up with following structure
clubs
=========
id | clubName | clubOwner
club_staff
id | clubId | accountId | roleId
club_roles
id | name
club_role_permission
id | roleId | permissionId
club_role_permission_details
id| name |
I am not sure if this will solve both of my problem of clubOwner easily nominating other user and same user with different roles in different clubs.
Any suggestion will be appreciated.
Thank you
Though this topic is subjective to many developers, I believe you are in the right track.
Permissions - normally corresponds to smallest unit of actions like View Club Staff, Add Club Staff, Remove Club Staff and so on. Normal club staff can view other staff within their club, but cannot add or remove club members.
Roles - are group of Permissions that are related to each other. ClubManagerRole for example must have all the permissions related to managing the club, while ClubStaffRole can only view members for example.
Users - are your users, that's all.
UserRoles - a junction table which has many-to-many relationship between Users and Roles. In other words, a user can have many roles, and a certain role can be assigned to many users. Just like how there are many Club Managers but maybe some of them can also be Other Managers.
Clubs - are your clubs.
ClubUsers (or staff) - are the users of a club. If a certain user is allowed to be a staff of one club only, one-to-many will be a fit choice. Otherwise, you can go with a junction table again for many-to-many relationship which will allow for users being assigned to many clubs.
The nomenclatures again, are also subjective. You can search for Database practices/normalization to get a basic a idea on how one can come up with a good schema.

Efficient way to handle user roles

I am working on one portal where will be few user roles. I have been wondering what is the best way to handle them. I have created separated tables for users and clients, but clients will want the functionality as users and users can become clients easy too.
I also don't want to make many joints, so what I as thinking is this:
I will have 4 different user roles (at least for now) as follow:
user
client
reviewer
admin
I will assing "id" to each role. At the same time I will keep table in mysql with these roles. It will be something like:
1 - admin
2 - reviewer
3 - client
4 - user
This table will be used only upon creation of user, to get the code of user "permissions". So Let's say that there will be a guy who is a user and reviewer. His role would be 24.
login password email role created
----------------------------------------------------------
guy password guy#gmail.com 24 2012-12-08 23:12:30
I think this could work pretty well, but still want to ask if you guys think this is good and effective solution.
Thanks
The other way to do this would be to have a many to many USER_ROLE table where for your example guy would have the following entires.
login role
guy 2
guy 4
I generally prefer this method of tracking roles. A join against this table in a situation like this should be fast and painless, especially if you move to using a user_id instead of a login, and index appropriately.
What you're defining is a Role Based Access Control System (I would suggest looking up resources on this). An RBAC system will have a separate table for users and another table for roles. There will be a many to many relationship between users and roles. Also, you will connect a permissions table to roles in another many to many relationship. The image attached represents how to implement this system:RBAC SYSTEM IN MYSQL
A similar question was asked before: How to design a hierarchical role based access control system

Human relations between users

I'm involve in a development of a tiny Social Network where users must be able to establish relations between them and also have permissions over contents. For a example: I add one user as my friend but this user doesn allow me to see all his/him contents so I only have access to those contents that user allow me (permissions). So I have a problem and need help designing the DER of this part. I think in have this tables:
- users (id, name)
- relations_type (id, name, active)
- users_relations (id, id_user_1, id_user_2)
- users_permissions (id, id_relation, id_module, id_user, view, edit, delete)
This cause the following:
Two rows for every relationship: User 1 > User 2 and User 2 > User 1 because when I search (SELECT) I need to know which are User 1 friends and also which are User2 friends. If I leave only one way relationship then I need a UNION and this migth slow my DB
Is that correct? How yours handle this when CRUD on this? I'm using MySQL by the way and MyISAM tables.
Don't use user1 and user2 as table names, you're going to forget which is which when the scope expands.
you can denormalize permissions on the users table, you don't need to divide tables for a few boolean bits.
never count on union, it will betray you in the least expected situations.

Database modeling

My question is about modeling a particular situation:
In my model I have tables: User, Offices and Partners.
The system has different user profiles: users of Office (counselors, principals, assistants), users for Partners (Institutions,..), admin users.
What is the best way to model the relationship between office users and partner users if:
- The users are unique (two users should have the same login - should be in only 1 table)
- An office user is associated to only one office
- A partner user is associated only with a partner.
It should be a table for office users and one for partners users?
A many to many relationships in this case would not work, right?
Thanks for your help.
You have not provided enough definition re Partners and Offices, so those parts of the model are not yet complete, but I think the main question you are asking is answered in this ▶Data Model◀. As I understand it:
User (login, UserName is unique, and you do not want that to be unclear)
Users are exclusively (that is the X in the half-circle) Office/Partner/Administrator
that requires a Supertype-Subtype structure. The cardinality is 1::0-1
Users belong to (?) an Office or a Partner, exclusively.
That may be OfficeType or OfficeTitle.
If you define that last item a bit more, I can finish the model.
Readers who are unfamiliar with the Standard for Modelling Relational Databases may find the ▶IDEF1X Notation◀ helpful.
Assuming this model will never change I would add a field to the users to determine where they belong. You could put an enum named user_type with possible values of 'office', 'partner', or 'admin'.. And then you could put in columns of office_id, and partner_id so you could join the tables as needed.
I think the best route would be to go with an account group structure, where you use an association table to determine who's in what group...
group
id | name
group_assoc
group_id | account_id