Database—Multiple User Types: Different Data - mysql

I'm having a bit of trouble figuring out how to structure my database for an application I'm building.
There will be three different types of users:
Admin
Applicants
Reviewers
I'm planning on having a general users table to store shared information between each user type. However, I'll need to store quite a bit of information for Applicants that I won't for Reviewers, or Admins, and I'll need to store some permissions information for Reviewers that I won't for Applicants.
I know I'll need to set up some additional tables to accommodate this information but I'm not sure how to do so. Should my users table have an admin_data, reviewer_data, applic_data fields as FKs? How would I detect what type of a user a person is when they login?
Each user will only need to be one type.
Thank you for your help.

Have an accounts table with login info, account id and account type. Then join to the appropriate related table (admin, reviewer, etc) to get relevant info.
There's no reason to mix the data since it sounds like it varies quite a bit.

Related

best practice for designing system with multiple user type

We have a system with two main roles: service provider and customer. The provider side is users like doctors, nurses, and caregivers. The customer side is just the customer. all user types contain some common data and some uncommon data. in the current system, we have a table for each user type, and for common data, we have User table. currect system ERD is:
https://s4.uupload.ir/files/screenshot-20210710165449-1007x662_tpwd.png
in the current system, we have a lot of tables and we think about reducing them. our vision is to bring all user types in a single table called User and instead of a lot of tables, we have more columns. of course in some users, we have empty cells that do not belong to this user type.
I have 4 questions:
is it ok to bring customers and providers to a table like User?
what is the optimal number of columns in a table?
load a row with a lot of columns OR relation between different tables?
provider type should be a separate table or can be an enum?
It is best to put all users in single table. So when you check login there is less place to do mistake. When selecting user you dont need to use SELECT * FROM... You can use SELECT id, username, name FROM...
Dont put too many columns, if there is some data which you dont need when searching or displaying users, you can create helper table "user_meta" with dolumns user_id, meta_key, value where user_id and meta_key are primary key
Answered by first 2 answers
Provider type should be enum if there will not bee needs to expand with additional types.

Partitioning or not a table on mysql

I know that there is not a "good" answer to my question, and it is opinion based. But since I am now learning those things on my own, I need advice.
I have a table on Mysql about "Customer". In this table there are columns referred to customer's info like name, surname, date of birth, address, and so on.
Each customer has his own credentials (username, password).
Now my question is: It is better to keep credentials in "customer" table, or it has sense to create a separate table, in order to guarantee the protection of these credentials, and also keep track of the changes of them along time, without wasting space repeating all the others customers' info?
You need to answer some questions about your data:
Do the columns change? People change names, addresses, and so on.
The credentials will change, at least the password.
What sort of history do you need?
My recommendation would be different sets of tables for different purposes:
One table that defines the customer id and whatever other immutable information there is (perhaps the date of becoming a customer and related information).
One or more tables with PII (personally identifiable information). You want to keep PII separate for regulatory and privacy reasons.
Tables for history. How you do this depends on your data model and what you need. A simple method is a single archive table per table in your data model. However, I might recommend type-2 tables (i.e. those having version effective and end dates).
Separate tables for credentials. These are even more sensitive than PII and you will want to control access.
Remember to never store clear-text passwords. And often you want to keep a history of passwords to prevent users from using the previous one.
It is better to create personal information in the person table and additional customer information in another table that has a relationship with the customer, and if you have any other information about the person in another table and link it to the table of persons.

MySQL Tables Arrangement

I have a corporate website which is used to communicate between staff members as well as staff members with clients. There are internal users who can login and work with their mail using web interface, there is a list of external clients with email address and phone numbers which internal users can use to write an email or make a call. Sometimes clients become staff members, sometime staff members gets fired but stays in the database as they can become future clients.
There are two MySQL tables for those two types. First one is a full list of all people, and there is a separate table of internal users partially duplicating the first table. The second table for the people who can login so it has login, password and some permisisons fields but it also have last name, first name, job, address etc. which is already in the first table.
So all internal users have two entries - one entry at the users table and one at people table. People table has internal users and all the external clients data.
I'm thinking to make one table from those two just by adding internal users fields to the people table such as login, password, permissions etc. so whoever have those fields filled considered to be internal users. That would probably simplify my SQL queries and get rid of edless SQL JOIN constructions as I constantly have to fetch data from both of the tables in order to get full data on a user.
Basically I want users table to become part of the people table. Is there any negative consequences per your experience may be in terms of security or conviniency that can be a problem for such an integration of clients and users being put together in one table?
I don't think you should get rid of the users table. The distinction between internal and external users is too important to depend just on the use of columns.
Instead, make users a "subtype" of people. So keep the people table and include all the users in them, with the appropriate "people" fields. Then in your users table, include the internal information along with a people id.
With this structure, it is easy to get "everyone" (from people) and "internal users" (from users). To get external users, you need to do something like:
select p.*
from people p
where not exists (select 1 from users u where p.personid = u.personid);
This should be a fast operation, with a index on personid. You could maintain a flag in the people table, indicating whether someone is or is not a person, but you would need a trigger to keep it up-to-date. Probably not worth the effort.

What is a better data model to use to store user profiles?

I am working on the data model for a relational database where I have to store User Information as well as User's profile such as Education Level, personal interests, hobbies, and etc. Similar to what most of the social networking sites have or any other systems that allow you to build a profile.
I cannot decide if it would be better to store all this information in one Users table, or break it into 2 tables.
If I would break it into two tables I would have Users table that would just store UserID, Name, e-mail, DOB, gender.
UserProfiles would store the rest of the stuff pertaining to a profile, sharing the same UserID with Users table
If there are multiple profiles of a single user means one to many relation then i would recommend you to create 2 tables one is user and other is user-profile.
If one user have only one profile then your should create only one table with both attributes on User as well as profile.
Go for the more modular design, this will allow for more flexibility and control. The only time I would recommend keeping the data in a single table is if you plan to query the same data frequently.
There is a great article here which goes into depth as to why joins are expensive. You should ultimately base your decision off the information provided in the link, however as I mentioned before if you plan to query the two tables together frequently then keep the data in a single table.
I think,in order to decide which data model to chose, just look at some of the similar requirement Datamodels, which are presented in this Datamodel Library.
Specific to your User-profiles Datamodel Requirement, this link may be useful.
Hope those links will be useful. OR I got this Data model image depicting facebook type data model:

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