Efficient way to handle user roles - mysql

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

Related

User roles schema design comparison

I'm learning how to design a DB structure for assigning users permission to access certain pages
if the user is an admin that user would have access to crud operations
if the user is an editor that user would have access to only edit
user can have custom permission then access it would vary depending on the config
I have two schema designs and both seems good, one requires simple queries and the other can hold more description about each role and permission.
Design 1
role id is stored in a table called user and i will need to lookup role_has_permission table get all the permission ids then lookup permission table to get the permission_name column. comparatively longer query with more data being fetched, but i can have description column in permission table
Design 2
role id stored in table user, i can simply make a single query and check for permission. eg: role.canEdit is set to true user is allowed to edit. smaller and faster query.
why cant i go with the second design? and why do many articles go with the first design?
Design 1 lets you add permissions dynamically without changing the software. If you need a new permission, say can order lunch for entire team, you just add a record in the permission table and as many in the role_has_permission as needed, and you're done. In design 2 you'd have to add an operation canOrderLunchForEntireTeam. So design 1 is more flexible.
However, the flexibility of design 1 has a price. It's not enough to define and assign these permissions, but the software shall probably also check them when a function is performed. Adding a function for ordering lunch is a software change anyway, so adding an attribute to your design 2 class might be tolerable. The generic way of defining permissions in design 1 will therefore only pay out if you implement a similarly generic way of applying them.

Relational tables best practice

im building a application where will run a mysql database, and in the database i will have some relational tables, but latelly i been looking different relational tables online different of how im used to do, basically i dont no what is the best practise and hope in finding the best way to go, above i leave a small example of how i normally do and other online examples:
My practice:
users
- id
- role_id;
- email
- password
roles:
- id
- title
Online Example from others
users
- id
- email
- password
role_user:
- role_id
- user_id
roles:
- id
- title
Basically my question is wich one is better, in terms of best practise and scalability?
It depends on if you want a many-to-many or a one-to-many relationship. In your first example, that's a one-to-many relationship. In other words, a user can have at most one role. In the second example, users can have many roles and roles can apply to many users.
So, if you need users to be in more than one role, use the second example. Otherwise, your first example is just fine.
the second is normally used when you need a separated module for rbac functionality .. in this way the aspcted related to the role are not intrinsecally related to the user authentication module..
Your solution is formally correct butn don't keep in the right consideration the design aspctec of keep the modules separated ..
In Simple words, if you think that one user gonna have multiple roles, then 'role_id' column of 'users' table in become insufficient, so, if are you pretty sure that one user will have only one role anyhow, then first one is fine
else go with second one!

How do I restrict certain values in column 2 with the same value in column 1 in SQL?

consider the following ERD for a MySQL database:
the table roles contains all kinds of (website-specific) roles users that are logged in could have. As you can see from the ERD: members can have multiple roles, and roles can have multiple members assigned to them.
The table members is dynamic, new members with custom roles can be made at any time, but the roles table is not. The current set-up of roles is final.
The records inside the roles table look like this:
id rolename
1 captain
2 cabin boy
3 buccaneer
4 parrot caretaker
5 cook
Now for the problem: I want members to have certain roles assigned to them, but certain combinations of roles cannot be chosen. For example, a captain can not also be a cabin boy, but he can also be a parrot caretaker. A cook can also be a cabin boy, but not a parrot caretaker.
I have done some research on Google regarding this topic, but I seem to fail in finding the right keywords to actually find usable information to solve this problem. All I seem to find are references and tutorials on how the SQL CHECK works, but not quite THAT in-depth.
Is there a way for me to use MySQL constraints to restrict some combinations from happening? If not, might this problem be solved using triggers or functions? I am generally looking for the most efficient solution to this, it does not necessarily have to be on the database side.
This depends on a few things..
Do you want the database to handle this logic or are you happy to have it at the application level?
If you want the database to handle it, you are probably going to want a trigger.. mysql parses a CHECK constraint but doesn't enforce it.
Either way you'll probably want to store the allowed combinations somewhere.
For simple cases I'd go for either a black-list or a white-list of other roles for each role depending on numbers. You can store this easily in another table.
Another option is a pre-requisite table, for example to be an admiral you must also be a captain.

Database Schema help needed for a social networking site

I'm in middle of creating a social networking site something like facebook, and got struck up with database schema design for it.. from previous questions i posted here, i confirmed that i cant create new database or tables for a new user who registers onto my site. I need to insert new row [thats my only option(correct me if i'm wrong!)]. but, this works out for registration for the first time. what if the user posts something new on his profile.. where should i insert this update.. coz, i cant insert them into rows as dey correspond to each user.. and too many columns cannot be created.. what is the solution for this.?
schema =>
TableName : User_content
userId Name College City Status_Updates Messages
1 a sfd fds fsds sdds
2 f dfg dfd fdf dfd
what if user 1 updates something.. what i need to do nw. Think its a status update, how to go about it.?
Before you start thinking about this social network site you dream if
Developing you need to understand database modelling fundamentals. This link will help you with some simple concepts. http://www.databaseanswers.org/tutorial4_data_modelling/index.htm
Add tables based on what you want to allow your users to do and the related data you need to store as a result. Some example tables:
'user_account': User account information (e-mail address, password) - referenced by user ID
'user_profile': Basic user profile information - referenced by user ID
'user_status': User status message - referenced by user ID
I have the sense that this is your first major database application, and if so, you need to learn more about database design in general before you take on creating an application like this. There are many things to consider when designing a database schema and designing it well from the start is key. The core of your application will rely on how well your data is organized and accessible, so ensure you spend enough time developing a good design.
Good luck!

Permissions for web site users

I'm working on a web site where each user can have multiple roles/permissions such as basic logging in, ordering products, administrating other users, and so on. On top of this, there are stores, and each store can have multiple users administrating it. Each store also has it's own set of permissions.
I've confused myself and am not sure how best to represent this in a db. Right now I'm thinking:
users
roles
users_roles
stores
stores_users
But, should I also have stores_roles and stores_users_roles tables to keep track of separate permissions for the stores or should I keep the roles limited to a single 'roles' table?
I originally thought of having only a single roles table, but then what about users who have roles in multiple stores? I.e., if a user is given a role of let's say 'store product updating' there would need to be some method of determining which store this is referring to. A stores_users_roles table could fix this by having a store_id field, thus a user could have 'store product updating' and 'store product deletion' for store #42 and only 'store product updating' for store #84.
I hope I'm making sense here.
Edit
Thanks for the info everyone. Apparently I have some thinking to do. This is simply a fun project I'm working on, but RBAC has always been something that I wanted to understand better.
This is probably obvious to you by now, but role based access control is hard. My suggestion is, don't try to write your own unless you want that one part to take up all the time you were hoping to spend on the 'cool stuff'.
There are plenty of flexible, thoroughly-tested authorization libraries out there implementing RBAC (sometimes mislabeled as ACL), and my suggestion would be to find one that suits your needs and use it. Don't reinvent the wheel unless you are a wheel geek.
It seems likely to me that if I have permission to do certain roles in a set of stores, then I would probably have the same permissions in each store. So having a single roles table would probably be sufficient. So "joe" can do "store product updating" and "store product deletion", then have a user_stores table to list which stores he has access to. The assumption is for that entire list, he would have the same permissions in all stores.
If the business rules are such that he could update and delete in one store, but only update, no delete, in another store, well then you'll have to get more complex.
In my experience you'll usually be told that you need a lot of flexibility, then once implemented, no one uses it. And the GUI gets very complex and makes it hard to administer.
If the GUI does get complex, I suggest you look at it from the point of view of the store as well as the point of view of the user. In other words, instead of selecting a user, then selecting what permissions they have, and what stores they can access, it may be simpler to first select a store, then select which users have access to which roles in that store. Depends I guess on how many users and how many stores. In a past project I found it far easier to do it one way than the other.
Your model looks ok to me. The only modification I think you need is as to the granularity of the Role. Right now, your role is just an operation.
But first, you need a store_role table, a joint table resolving the Many-to-many relationship b/w a role and a store. ie, one store can have many roles and one role can be done in many stores.
Eg: StoreA can CREATE, UPDATE, DELETE customer. and DELETE customer can be done in StoreA, StoreB and StoreC.
Next, you can freely associate users to store_role_id in the user_store_roles table.
Now, a user_store_role record will have a user_id and a store_role_id:
A collection of
SELECT * FROM USER_STORE_ROLE WHERE user_id = #userID
returns all permitted operations of the user in all the stores.
For a collection of users's roles in a particular store, do an inner join of the above to user_store table adding a WHERE part of like
where STORE_ROLE.store_id = #storeID
Put a store_id in the user_roles table.
If this is Rails, the user model would have_many :stores, :through => :roles