Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 5 years ago.
Improve this question
I have to implement a role system in my app for authorization. We have around 5 kind of roles in our system.
To maintain these roles we have 2 options,
Alternative #1
1.Create an enum in rails Role model,
enum role: {super_admin: 1, translator: 2, approver: 3, sales_admin: 4, marketing_admin: 5, guest: 6}
2.In the Roles table , now we will have ID user_id role_id
Alternative #2
1.Create 2 models Role and Role_User.
Role table will only contain ID | role_name and Role_User will contain ID | user_id | role_id
Which should be preferred?
I would suggest to go for second approach as if in future there is any possibility of additional role there will be no burden for you to create that additional role. With first approach you have to edit your enum for additional roles which you might want to add in future
It depends how baked into your code the roles are. Some systems have a very rigid concept of "admin" or "moderator" or "user" and introducing roles that don't fit those slots can cause chaos. In those cases they're better off left hard-coded. You might have a table simply to convert the internal name into a label, something especially important when translation's involved. "admin" becomes "Administrator", or whatever that means in the other languages your system employs.
If you've got a system that's a lot more adaptable, where the roles table can define arbitrary permissions, then it makes a lot more sense. You can create custom roles that will work within the structure of the system because the system was deliberately engineered for it. A "role" in this cases is just a set of permissions.
An added benefit of the separate table is that users can have multiple roles, if that is something your system requires. Also, storing the different roles in the database should be better for enforcing database-level data integrity, i.e. you can't add nonexistent roles to users.
If you do end up using a separate table for roles and a join table, be sure to add proper indexing to the join table.
Other than that, it really depends on the context and use case. If the system is simple enough, nothing wrong with going the enum way.
Related
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 2 years ago.
Improve this question
I am implementing multi-login system in a web application in Laravel. In the application a user can register with multiple social platforms and all those accounts should be considered as one.
I have 2 ways to implement this:
Method I:
users table
- id
- username
- email
- google_id
- facebook_id
- github_id
- twitter_id
- ...other columns
Setting all google_id, facebook_id, twitter_id by default NULL. Saving each value based on when user registers with that platform through the application.
Method II:
users table
id
username
email
.. other columns
social-login table
id
user_id
social_type //facebook or google or twitter etc
uid // unique identifier returned from each platform
Using Method I, I am getting better performance as I need to execute queries just on one table but method II is providing better table structure.
Which method should I use? Consider the fact that there would lot of requests and in all requests we are going to get uid and not user_id to fetch any information of the user.
The queries would be something like below:
SELECT * FROM users WHERE id=2;
SELECT * FROM `social-login` WHERE user_id=2;
SELECT * FROM users as U JOIN `social-login` as S ON S.user_id=U.id WHERE U.id=2
I would go with option 2.
Reasons
You could always "add new social types without changing the schema." whereas in 1st option you would have to add another column for that social_type.
Normalized database as it prevents data inconsistencies.
I'd like to add one more suggestion.
Create another table
social_type table
id | name
1 Facebook
2 Google
And refer it's id in the social-login table
id | user_id | social_type_id | uuid
Benefits
The database has control over the types. With this user can only choose options that exist in the system and are valid for the system. So basically you control it. Whereas earlier user could send any random value qawqdq (no doubt that you could have other checks) and it would store it.
With the previous approach, there might be a possibility that some rows might have "facebook" in lowercase, some "FACEBOOK" in upper case, some "FaceBook". So this helps in keeping one particular value across all the entries.
Again, performance would be affected by this as it would add an extra join. So it's completely optional. I'd suggest you do it this way if performance is not affected by a huge amount and is not that big of a concern to you.
I would choose option 2.
It is the cleaner structure
You can store the data better
I don't think that the time loss can be that problematic for your performance. I would only choose option 1 if the time loss is significantly high.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
So I need to design NoSQL Schemas (Mongoose) from next SQL Database.
Image of SQL database
So I have a few questions about how to make those Schemas:
There is a field in table course_student called entryDate. In what Schema do I store this field and how do I connect it to other? (Refers to entry Date of one student to specific course) (Also the case for startDate in course_teacher table)
In Admin, Teacher and Student Schemas, how do I inherit all properties from PersonSchema (is this the case for Discrimantors?), or do I store all of their fields in PersonSchema (the case I don't like, because in case of "admin", teacher and student fields would be all NULL)
(Optional) Also, how to handle non-normalized case of many-many relationship? (Let's say there is no course_teacher table, and teachers & courses are connected with many-many relation)
In Mongo, like in SQL, there are many ways you can structure your data. The key to consider in Mongo, is how do you need to access the data. Try to group data in ways that it matches queries you expect to perform. Using that context, I'll try to answer some of your specific questions:
1) Your asking where to store the entryDate of a student into a class. Do you often pull students independently? Or do you always grab them with their classes? Do you need classes independently?
One option would be to nest classes inside of your students:
Student =>
{
firstName: "John",
lastName: "Smith",
classes: [{
classCode: "EN101",
entryDate: "10/10/2017"
}]
}
You could also have a class object with a list of students if you access it all it once usually:
Class =>
{
classCode: "En101"
students: [{
studentId: 12345,
firstName: "John",
lastName: "Smith,
entryDate: "10/10/2017"
}]
}
If you often reference things separately, you could have a flat table like in your SQL that just has classCode, studentId, studentEntryDate
These objects are all stored together in one table? If so that sounds like a great use of discriminators. like if you just have a People collection. However, I would guess that they are stored separately? Teachers and Students are stored in different collections? In that case you can just have them inherit the same class in code, and they will serialize fine into mongo without any discriminators.
There's multiple ways to handle this. You could create collections for each table and maintain a linking table, but not usually the best way. I would think Teachers and Courses would be one-many not many-many? So each course would have a teacher. If courses do have many teachers, you can just have a list of teachers instead of a field called teacher.
Hope my answers are clear, feel free to comment for more information.
If your pretty new in Mongo, I recommend signing up for some of there free courses. There pretty useful and get you a good foundation.
Good luck on your switch to mongo. It's worth it!
Below are two good resources with comparisons between RDBMS and NoSQL Databases.
https://www.mongodb.com/compare/mongodb-mysql
https://docs.mongodb.com/manual/reference/sql-comparison/
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 7 years ago.
Improve this question
What would be the "correct" way of organizing banned users?
Should I simply add a new column in the existing users table called is_banned that acts as a boolean or should I create a new table called banned_users that acts as a pivot table with the user_id?
The same question goes for administrators. Should I create a new table for site admins or just create a new column called is_admin?
What about performance of the two options?
Thanks.
What happens with the next type of users - add another table? Better not.
You could add a new column called type or something like that. One way would be it containing a number indicating the type like
1 = normal user
2 = admin
3 = banned
or you could even add another table called user_types that refer to it, but that would only be necessary if you have the types changing over time.
If you need to combine types - users having multiple types at once, then you could make the column a bit field.
When do you need seperate tables?
When these different users would have different attributes and the tables for each type of users would differ.
You need to think about how the banning concept will play out in the real world. Do you just want a flag? What about when they were banned and by whom? past banning history? a response mechanism for the banned? A list of complaints, with user/date/reason?
Data models are the most difficult part of a system to evolve, so you want to think about all manner of possible futures, even stuff you don't have on the roadmap just yet.
You might decide, for efficiency, that you want a ban table and a banned column. But there's a price to be paid for that too, since you're now capturing the same fact in multiple places.
The issues are subtle and sometimes complex. Don't accept blanket one-size-fits-all answers.
The scalable solution that satisfies multitude of criteria would be this:
table that contains user data, users
table that contains roles - roles
junction table that connects the two, user2roles
You keep the user data separate from their actual role in your app - every user will at least have name and last name, those are not related to their permissions or roles.
You will most likely need to add more roles. For example, one role is being an admin. Another role is being banned. Another role can be being banned for a week, 2 weeks etc - basically you can add those as you go, without needing to alter your tables to support future functionality.
Your application (php, python, whatever) collects the data and then acts upon those roles.
Now you have a system that's got established relations, that you can scale and that's easy to understand by kids in kindergarden.
This is a simplified system that mixes permissions with roles, you can further expand it but IMO it's better to keep it simple.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
I have reviewed some q&a but thought something specific to my subject would help me get off the fence.
I have an app that calculates pricing based on several different formulas and hundreds of different material types.
user A may use formula A and material A, B, C
user B uses formula A and material A, B, C, + they want to add a
material that no one else uses Material unique_A
when user A is on the app he doesn't want to see user B's unique material.
I was thinking of using a unique table of materials for each user so that it is "faster??? more efficient??? to grab the list of materials, instead of trying to set up some sort of off, on function that grabbed only the materials the user wants from one global table.
Which way is better? One table or a unique table for each user?
You can have a table of all materials.
materials = (id, name, other attributes...)
and a table of users:
myusers = (id, name, etc....)
then you can have a table that basically represents the many to many relationship between these two:
user_materials = (user_id, material_id)
You can then select the specific materials used by a user by joining these tables. Application wise, this arrangement is better than trying to create a table for each user. Queries will become difficult. This way you also have answer to the question: Which users are using material A?
Unless you have very few users, each with his own stable non changing items,
I don't see any sense in doing this.
Plus , most likely you will not get into performance issues
if you are talking about a domain of users and materials.
It's not like there are millions of either , right?
One "best practice" for databases is to reduce information duplicity. Actually variations of that exists for just about any field of theory there is.
It would mean however that your approach of a unique table per user would not be a good idea.
Not only would it duplicate data, but maintaining such a database would become a gigantic task as the number of users increases.
I would prefer to have a global table of materials, a table of users and a table over which user want's which materials.
The 'one-table-approach' can be considered better because it reduces complexity, both in database and in the code which should access the database, and duplication of information.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 3 years ago.
Improve this question
I have 3 types of users:
Admins
Suppliers
Employees
Each user type will have different user interface and access different types of data. Their only similarity is they are using one web application but they access totally different things. Is it better to put them all in one user table like tbl_users or is it better to create tbl_admins, tbl_suppliers, tbl_employees?
What you need to consider when designing tables is not necessarily what they'll have access to and how that is similar/dissimilar, but rather how the user levels themselves are similar/dissimilar.
For example, if the user types will have the same attributes (name, email, birthdate, etc), then they belong in one table together with a column indicating their privilege level.
This also facilitates changing privilege levels for a user, whereby you can make an ordinary Employee into an Admin, for example, by just updating the record in the user table.
If Suppliers are a different type of object with different attributes than the other two, Suppliers may belong in their own table.
Or, one more thing to consider: You might use a users table that holds only very limited information about users of all three types, and if the types have extended attributes that don't relate well to one another, you can store those in other tables with a foreign key back to the main users table.
There is also a third choice: put the columns that all users have in common into tbl_users, and create three tables for tbl_admins, tbl_suppliers and tbl_employees joining to tbl_users as 1 to 0..1. You should consider this choice as an alternative when the number of shared columns is significant.
It depends on how similar their data structures are. If they are similar, then perhaps you could put them all in one table. But, if they have a lot of different fields and you'll end-up with lots of NULL values...and then it's better that they're all in separate tables.
Best to keep all your login info in one place. If you were ever to make a change to your login process, having 3 different tables would mean having to change the code in 3 separate places.
If a user can belong to more than one role, consider making a UserRoles table. Otherwise, adding an additional field to the existing table - such as RoleType - would help differentiate the different types of users.
You should just include them in one table and create a field/attribute that would be an indicator of whether the user is an Admin, Supplier or Employee.
It's simpler if you centralize it that way.
The concern on how/what they access would be under the software you develop. You can either fetch/constrict the UI[or whatever they access in the software system] basing from the type of user you have.
I usually just hide and show stuff according to the type of user I have
Hope this helps..