I would like to get some advice from you about best practices in user role management.
I would like to create an application where user register and will have different roles. Now the obvious thing is, to create the users table and save the user data there like this:
users
id
userUUID
username
role
But I think about separated tables for different groups. So like:
admins
id
userUUID (-> foreign key users table)
accessRight1
accessRight2
subscribers
id
userUUID (-> foreign key users table)
etc
Does this make sense? So should all users, regardless of their role be in one database? And what is then about the specific information for different roles?
Thanks!
If your roles are rarely going to change that would probably work. But, you should always plan for change, and a more flexible option allowing you to add roles without needing to change your database schema would be something like this:
Users:
uid
user info...
Roles:
rid
name
UserRoles:
uid (FK to user table)
rid (FK to roles table)
In your code you could then check the UserRoles table to determine if the user has a given role and therefore should be allowed to do whatever.
Additionally, if you want to mix and match permissions for actions across multiple roles (i.e. both Admin's and Moderators have permission to delete posts or something). You could add another level with a Permissions table, and a join table (RolePermissions) linking that to the Roles table. You're access checks would become slightly more complicated then, requiring you to join the UserRoles table and RolePermissions join table to determine if a user has a given permission to do something.
Something like this:
SELECT *
FROM UserRoles u INNER JOIN RolePermissions p
ON u.rid=p.rid
WHERE u.ID=<USER> AND p.pid=<PERMISSION>
Related
I have a user table setup where a user can either belong to a Supplier or a Customer organization, which can have multiple users.
My original idea for the User table was to have a customerID and a SupplierID in the user table, out of which one will be filled, based on the organization the user belongs to. This does however not feel right, but I feel like maintaining two linking tables for this is overkill as well.
What would be the best practice in this case? I do not expect there to be any more organizations added in the future, but I do want to futureproof the application, by allowing multiple users to belong to the same organization.
you can design user or organization table with a column organization type which has value: supplier/customer and a column for organizationId
I am trying to design a database schema for a project using mysql as the database. and i am stuck on the authorization part, the business rules are as follows:
a role can have many permissions, and a permission and can be inserted in many roles
a user can have many roles, and one role can be assigned to many users
now this is the part that can't get it right, Every user can be in many "groups" but in each he can be assigned only to one role (by groups i mean group of people and not group of roles)
the following picture is what i came up with till now, what should be amended?
Based on your question and answer to my comment, here is the model I came up with:
This meets your requirements. The main difference with your model is how the groups are setup.
Group has a 1:1 relation with Role, which can be null (i.e. a group can exist even it no role is associated to it).
In each Group, you have a foreign key to the Role table.
If you need to know the roles a users has: individual roles through User_has_Role + role attached to each group the user is a member of (through Group_has_User).
There can be a table for each group which contains user and effective role(as user in one group can have only one role). There is also one implementation specific flaw, if user can be in multiple groups and in one group he can have only one role, so there must be some provision to decide effective group for the user which is going to decide effective role for user.
If users relationship with the group is only factor that decides the role user can have, then there is no point of having direct relationship between user and role.
I have a users table in my database and have three kinds of user roles - manager(admin), expert, and student.
I have tried storing their role as column role in the users table, but my question is what is the best way to store it?
For example, should I use numbers - 1 for admin, 2 for expert and 3 for student. Or only one character - 'A' for admin , 'E' for expert and 'S' for student? Or full string 'admin' for admin and so on, or what?
Edit
Guys, I want most efficient way. Some of you told me to have another table but this relationship isn't many to many, it's one to many because users can only have one role.
You might want to have a separate junction table, eg user_roles that will have columns: id, user_id and role_id. This way each user can have multiple roles in the future, even if right now they only have 1.
And that role_id would point to a role in a new roles table, which could have all the data associated with the roles.
Or if you really don't want the junction table, then just put the role_id directly into your users table.
Look up database "normalization". Basically if you have a specific set of data that will be repeating in a column, you might want to put it in its own table.
You could create a separate table showing 2 columns: role_nbr, role with values like:
1, Admin;
2, Expert;
3, Student
Then include role_nbr in your users table and use numbers, linking it to the role table to lookup the role name. That way, if you ever increase your roles, it's easy to add to the separate table. A good study would be on normalization - this will help you eliminate storing duplicate information where you have a lot of information to store (like the role name - since storing a number or letter - how would you remember what it stood for?)
Use the enum type. Here is an example
CREATE TABLE users (
-- the other columns
role ENUM('admin, 'expert', 'student')
);
An ENUM is a string object with a value chosen from a list of permitted values that are enumerated explicitly in the column specification at table creation time.
This means that the enum type has already defined values (and can contain only one value per row - you can't have a user who is admin and at the same time student). In your case, they are admin, expert and student.
DOCS
I finally got permission to redesign our database (yay, everybody cheer)!
One of the problems that I need to overcome is user login.
The way the database is currently designed, there is a User table, with a 1:n relationship to UserStaff (user can have multiple staff - think of a manager). There is also a completely unrelated Customer table.
I need to create a table to consolidate the login so that all of these people (User, UserStaff, and Customer) can login to the same area, but each of these tables above has completely different information inside and different relationships to data.
How/where should I start moving things around to get this to work?
You could create a "Login" table containing "loginID", "email", and "password" fields. Each of the other tables (User, UserStaff, Customer) would also contain the "loginID" field. Then at login-time you could SELECT from the login table, and (left) JOIN on loginID to the other tables to get your user's data.
Apologies if I wasn't able to describe the problem accurately in the title. My scenario is as follows.
My site operates as a platform to connect vendors and buyers. Vendors list down the goods/services they have available and buyers are able to purchase goods/services from them.
New buyer (user) registration is straightforward in that their information gets stored in users tables (users, user_profile, user_history etc.) tied together with a unique user_id. What I'm having difficulty wrapping my head around now is that I require vendors to register as well (for verification purposes,) and that vendors can also be buyers.
My users table is like so:
user_id <--- primary key
name
email
...
and a related table may look like so:
transaction_id
user_id <--- foreign key
date
amount
...
My initial thought for the vendors table:
vendor_id <--- primary key
user_id <--- foreign key
vending_name
registration_number
...
and a related table:
product_id
vendor_id <--- foreign key
name
price
...
My question is, would it be best to have this vendor_id to link up all the vendor-related tables or should I stick with using the user_id for everything?
Thanks.
It depends.
Think of this scenario, could a user ever become a vendor (or vice versa?) if so then it's best to plan your data models around a base user and add attributes or flags (in a separate table or field). This way, you can add/remove privileges.
i.e. Have a separate tables called "flags" "flagmappings"
//flags
flag_name <--- 'Vendor', 'User'
//flagmappings
user_id <--- foreign key
flag_id <--- foreign key
This structure gives you a few benefits:
For any given user you can search flagmappings and then determine what privileges a user might have.
All your login/authentication logic is the same for all users/vendors (i.e. you don't have to split/special case different tables if it's a vendor or a user, all the base information is in the same place).
If a user needs to become a vendor or vice versa you simply add that flag to the user.
If you need to create yet another type of user (i.e. administrator, manager, etc.) it's just another entry in the flag table.
If I were you, I would just stick with the users table for everything (as long as you don't have a gazillion vendor-specific fields). It just makes things cleaner. Then, you might have a 'is_vendor' field in the users table.
Or if you want to go even more sophisticated, you could implement roles with something like this:
users Table
id
firstname
etc...
groups Table
id
title
etc.
user_groups Table
user_id
group_id
Personally, I would go with the second option because it allows for more role-based permissions, such as admin, editor, moderator, buyer, seller, super-buyer, super-seller, etc.