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
Related
Im thinking about what is the better way to design a database with the following statements:
There are 3 kinds of users (3 differents roles).
They have some common fields, however they have differents fields too.
Solution A:
All user in the same table (some users will have empty fieds depending of their role).
Solution B:
A main table where i will add users and their role. In addition i will create 3 extra tables where i will record with extra fields (depending of the table) and each record will have an id related with the user in the main table.
Solution C: A main table with basic user info, and a second table with the metadata user info where each record means a field of a user. That it's similar than WordPress
Yours is a case of Specialization/Generalization. Since you said User (1, 2, 3) share common properties, it is best to have a General entity - User with all the common attributes.
Then you can Specialize to 3 different types and have the specific attributes to each type.
So, option B is what I think is best solution for your problem.
Option A will cause too many null values and option C is overly complicated.
That depends :-)
Will you ever treat the users the same? E.g. at login time: Will someone just login with a username and this can be any of the three user types? Then you need a user table with a username and a unique index on it. This is solution A or B. I'd prefer B over A, so you can decide which of the fields are nullable for the specific role.
Or will you never deal with a user with an unknown role (such as: a person logs in with a role plus a username, so it suffices to have three different tables each with their own usernames)? This would be three special user tables and no common user table.
Option C would be something easy to implement in order to give users additional attributes, but can become a hassle. Especially when there are obligatory fields and fields that link to other tables (such as a job number that is meant to be the key in the jobs table, but you cannot use a foreign key then). I usually don't take this route, if it is avoidable.
I'm building an application that will have two different types of users, lets call one User_type_a and the other User_type_b. I'm wondering if I should create 1 table in my database for both types of users and have a property distinguishing what type of user each record is, or if I should create two separate tables for each type of user.
Considerations:
1. 99% of all users will be User_type_a
2. User_type_b will require properties in addition to User_type_a (such as credit card #'s, etc)
Which design approach is optimal? Or does it not really matter.
One table for users, assuming that user type b are real users. Create another table that links to the user table to store the CC details for user type B.
This allows you do do all major user changes easily (searching users, changing user details, looking up users for login, etc), but doesn't contain many wasted columns.
Note that if you are storing credit card numbers, your datacenter and architecture will have to be PCI compliant, which is expensive.
If type B has only additional information (columns) to the generic user type then use:
If types A and B have some common columns and a set of distinct columns for each one, then use
I both cases keep all common columns in the User table -- sub-type tables have only columns specific to each one. Note that UserID propagates to sub-type tables.
The best way to do this would be to store all users in the same table, and have a foreign key relating to a second table, which contains the extra information.
**USER TABLE**
NAME AGE TYPE FK
Grant 25 Adult 1
Susan 4 Child null
John 65 Adult 2
**EXTRA TABLE**
FK CREDITCARD OTHER
1 234234... blah
2 2334... blah
This would be more efficient with space.
So it sounds like User_type_a and User_type_b are both identical in terms of data, with the exception being that User_type_b has additional data above and beyond User_type_a (but User_type_a does not have any unique data like this).
Given this, I would create a single users table that stores the User_type_a data (i.e. the intersection of the two user types). Then create a second table for the additional User_type_b data, with a foreign key linking that one back to users. (Note that there is no column here in the users table defining which users are which type.)
How to tell the difference between the two user types? Simple: User_type_b has a related row in the second table; User_type_a does not. This makes it easy for any application functions that don't care about the difference to just get the common user data for everyone, while functions that need the extra User_type_b data (or otherwise only care about one type or the other) can still determine who is what type and get that extra data.
Use one table. They are both users. Your code will have more general use between both types so you will avoid having to do 2 sql queries when dealing with users (even though they are not relevant 99% of the time)
i wanna have a Users details stored in the database.. with columns like firstname, last name, username, password, email, cellphone number, activation codes, gender, birthday, occupation, and a few other more. is it good to store all of these on the same table or should i split it between two users and profile ?
If those are attributes of a User (and they are 1-1) then they belong in the user table.
You would only normally split if there were many columns; then you might create another table in a 1-1 mapping.
Another table is obviously required if there are many profile rows per user.
One table should be good enough.
Two tables or more generally vertical portioning comes in when you want to scale out. So you split your tables in multiple tables where usually the partiotioning criteria is the usage i.e., the most common attributes which are used together are housed in one table and others in another table.
One table should be okay. I'd be storing a hash in the password column.
I suggest you read this article on Wikipedia. about database normalization.
It describes the different possibilities and the pros and cons of each. It really depends on what else you want to store and the relationship between the user and its properties.
Ideally one table should be used. If the number of columns becomes harder to manage only then you should move them to another table. In that case, ideally, the two tables should have a one-one relationship which you can easily establish by setting the foreign key in the related table as the primary key:
User
-------------------------------
UserID INT NOT NULL PRIMARY KEY
UserProfile
-------------------------------------------------------
UserID INT NOT NULL PRIMARY KEY REFERENCES User(UserID)
Depend on what kind of application it is, it might be different.
for an enterprise application that my users are the employees as well, I would suggest two tables.
tbl_UserPersonallInformation
(contains the personal information
like name, address, email,...)
tbl_UserSystemInformation (contains
other information like ( Title,
JoinedTheCompanyOn,
LeftTheCompanyOn)
In systems such as "Document Managements" , "Project Information Managements",... this might be necessary.
for example in a company the employees might leave and rejoin after few years and even they will have different job title. The employee had have some activities and records with his old title and he will have some more with the new one. So it should be recorded in the system that with which title (authority) he had done some stuff.
I'm creating a social networking site with features similar to Facebook.
I want to start with schema design for my database.
What i thought was to create each table for each user who registers to our site.. am i doing right?
If a million users register to my site, a million tables will be created. how to go on about optimizing this? Please do suggest me techniques to overcome this and some references or books to learn about such concepts will be vry useful..
Thanks in Advance.
This is not the way you want to do it.
What you want to do is have a table (perhaps called 'users') that contains one row for each user that registers. Creating a new table for each user is completely pointless and would cause terrible performance.
Maybe something like this:
TABLE users
- username AS VARCHAR(255)
- password AS VARCHAR(255) (use a hashed password, of course)
- ...
Then when a user registers, simply insert the information they provide into the users table as a new row.
That would be massive overkill. You should probably read up on database design (start with normalisation, but don't overdo it). Then write down what you want to save for each user, and think about how to save it without saving data double.
But I'm pretty sure a table-per-user is not an option for this.
You must be confusing the meaning of the words database, table, field (or column), record (or row).
A database contains all your data for a specific project. There is always one database per project (or almost always)
A table contains all data of a specific entity and by saying entity, I mean an object type that is imaginable as real or seperatelly existing by itself. A person is an entity, a book is an entity, a phone is an entity, a movie is an entity, etc. Each of these would be seperate tables in a database.
A field (or column) is a data type that represents a specific characteristic (feature) of a table's entity. For example a table of users can have the fields: NAME, SURNAME, AGE, etc. These are all features that a user has.
A record (or row) is an actual item of one table. It is a single 'piece' of the table's entity. For example in a table of users, one record is one single user, namely {NAME:"John", SURNAME:"Smith", AGE:"32"}.
In your example, I can tell you for sure that you only need one database. You want to store information for many users, so you need one table called USER. You will need to store features to your users, like: name, surname, age, address, etc., then you will need to create the respective fields in this table: NAME, SURNAME, AGE, ADDRESS, etc. Then you will need to insert your data in the database as records. It will be one record per user you want to store.
I have one MySQL table, users, with the following columns:
user_id (PK)
email
name
password
To manage a roles system, would there be a downside to either of the following options?
Option 1:
Create a second table called roles with three columns: role_id (Primary key), name, and description, then associate users.user_id with roles.role_id as foreign keys in a third table called users_roles?
Or...
Option 2:
Create a second table called roles with two columns: user_id (Foreign key from users.user_id) and role (ENUM)? The ENUM datatype column would allow for a short list of allowable roles to be inserted as values.
I've never used the ENUM datatype in MySQL before, so I'm just curious, as option 2 would mean one less table. I hope that makes sense, this is the first time I've attempted to describe MySQL tables in a forum.
In general, ENUM types are not meant to be used in these situations. This is especially the case if you intend to cater for the flexibility of adding or removing roles in the future. The only way to change the values of an ENUM is with an ALTER TABLE, while defining the roles in their own table will simply require a new row in the roles table.
In addition, using the roles table allows you to add additional columns to better define the role, like the description field you suggested in Option 1. This is not possible if you were to use an ENUM type as in Option 2.
Personally I would not opt for an ENUM in these scenarios. Maybe I can see them being used for columns with an absolutely finite set of values, such as {Spades, Hearts, Diamonds, Clubs} to define the suit of a card, but not in cases such as the one in question, for the disadvantages mentioned earlier.
Using ENUM for the case You suggested only makes sense when You have a strictly definded ORM on the receiving end that for istance maps db rows into a list of flat objects automatically.
Example:
table animal( ENUM('reptiles','mamals') Category, (varchar 50)Name );
is automatically maped to
object animal
animal->Category
animal->Name