Do I need a login table? - sql

Hey guys I have a simple database question. Say I am emulating a university login system.
If i have a student table and faculty table, can I just store the password directly in the corresponding table? For example student table has such attributes as (student_ID - primary key), First_name, Last_name, Classification, and now I would add a password field.
If I create a login table i'm just effectively copying over thousands of potential records. Is there any benefit to creating a login table with say (primary key STUDENT_ID,FACULTY_ID) and a password field for authentication purposes?
Can I increase security on just one table? What is the better approach?

As one student contains only one password, there maintains one to one relationship so there is no need of splitting the table for one to one relationship.
If there is one to many relation, breaking the table will be good such as for storing multiple phone numbers or multiple address of a user.....

You need to decide upon whether only students will be allowed to login into your system.
What about admin user, teachers, etc?
even if there is a remote possibility that a non student will log into the system it is advisable to create a login table with userid and password stored in MD5 encryption

Related

Multiple Role Database Design

I recently had this problem in designing a SQL database.
I want to create a database for a school, and of course not all users have the same role or privileges.
For example, there are teachers, headteacher, students and parents.
If I put all those in the same table and put a role column the table, then I can't be free to put any other columns for a specific role
like I can't add a grade column for student because the other roles don't have grades.
Also I can't put them in separate tables because in the log in I can't specify the role for this user and go to his table .
What is the best way to do something like this?
Use polymorphism on the user table.
Create a user table with basic authentication and common information like email and credentials. Now create 2 columns authority_type, authority_id (naming can be changed).
Now for every type of new role or privilege, create a table.
For e.g. In your case, there will be a table for the teacher, headteacher, student and parent. All have separate sets of attributes.
Whenever saving a user record, you'll use its authority_type and its authoriy_id ( record foreign key of that other table ).

Best way to mimic inheritance in postgresql?

For an application I am writing, there are two types of "users", those who have made accounts and those who have not, virtual_users. These two types are nearly identical, except account_users have a password, and email is required and must be unique amongst all account_users, although it can be the same as any number for virtual_users. A large number of tables have a column that references users, which should include both, and 90% of app functionality treats them as interchangeable. What is the best way of handling this? Some options I have considered:
-Put both types of users in the same table and have a complicated constraints regarding uniqueness, basically, if password is not NULL, email must be unique among all users where password is not NULL. I have no idea how I would write this constraint. On the few occasions I only want account_users query for only users who have a password. This seems like the best solution if I can figure out how to write the constraint.
-Have Account_users inherit from Virtual_usersand Virtual_users has an additional column password and unique constraints on email. From here there are two potential options:
---Have a Users table which includes two columns account_user_id and virtual_user_id one of which is NULL and one of which corresponds to the appropriate user. When other tables need to reference a user, they reference this table. Have all my queries server side for users query both tables and combine.
---When other tables need to reference they reference either table. I don't think this is possible. Have all my queries server side for users query both tables and combine.
Any advice would be appreciated.
I assume the scenario is you have a system which some parts require the user to be signed into a registered account, and others do not, but you'd still like to track users.
Postgres has table inheritance. You could use that, but I'd be concerned about the caveats.
You could put them all into one table and use some sort of flag, like Single Table Inheritance, but then you run into constraint issues. You would then enforce constraints in the model. This should be fine if you have a strong model.
You could have separate accounts and users. Rather than one being a special case of the other, they key is thinking of them as two conceptually different things. In OO terms, an account has a user.
-- Visitors to the site who haven't signed up.
create table users (
id serial,
-- The unverified email they might have given you.
email text,
-- Any other common information like a tracking token
token text
);
-- Users who have registered.
create table accounts (
id serial,
user_id int references users(id),
-- Their verified email.
email text not null,
-- Hashed, of course.
password text not null
-- any additional information only for accounts
);
I like this because there are no flags involved, users and accounts can have separate constraints, and the accounts table doesn't get bloated with users that showed up once and never came back.
You'd access complete account information with a simple join.
select accounts.*, users.token
from accounts
join users on accounts.user_id = users.id
where accounts.id = ?
If you want to delete an account you can do so without losing the underlying user information.
delete from accounts where accounts.id = ?
Systems which require an account use accounts. Systems which don't use users. Systems which behave differently for users and accounts can check if a user has an account easily.
select accounts.id
from accounts
where accounts.user_id = ?
User tracking is associated with the users table, so you have a consistent record of a user's behavior before and after they register.

Foreign key or boolean value in database

Let's say I have a database with two tables, User and Store.
Lets make the rules:
A User must belong to one Store
A Store may have one or more Users
A store though, may have a store manager. What is the best approach for this?
Adding a 'is_store_manager' boolean column at the Users table, or create a foreign key called something like manager_user_fk at the Store table? I guess that would create a many to many relationship though, which would be bad, but it would be a solid constraint to select a user I think. What would be the best approach?
Don't create a fk on the Store. It is somewhat redundant and will make some future SQL queries harder.
You could add another table, UserType with the Manager, and Non-Manager types. You'd then add a fk on the Users table pointing to the UserType.
Edit:
If you wanted a user to be allowed multiple roles, you'd need another join table:
Let's call the previous table table Role, instead of UserType, and add another table, UserRole that is a join between User and Role (it has only 2 columns: a foreign key to User, and a foreign key to Role. With this setup, you wouldn't have any fk on the User table, as this join table would hold all the information about the relationship. A user could have as many roles as you like then.
An alternative to the accepted solution which only allows a user to be of one type you can use what I've been doing to replace boolean status fields. Create a table called UserManager with a primary key also being a foreign key to User.
Any user with an entry in UserManager is a manager. To get the managers you just join the User table with the UserManager. This also lets you store more meta data (i.e. you could store when the user became a manager etc).
Then if you want an AdminUser table, you do the same thing. Any user in the AdminUser table is also an admin. You can have a user be both (or none, or one). Along with storing more meta data about the type.

Database design relations in User and Profile

I'm designing a web application for a school. So far, I'm stuck with the database which has these tables:
users
id
username
password
profile
user_id (FK)
name
last_name
sex
group_id (FK)
(other basic information)
... And other tables irrelevant now, like events, comitees, groups and so on.
So, the users table stores basic information about the login, and the profiles table stores all the personal data about the user.
Now, the *group_id* column in the profile table has a foreign key that references the ID column of the group in which the user is currently enrolled, in the groups table. A user can only be enrolled in one group at once, so there's no need for any additional tables.
The thing is that it doesn't make much sense to me declaring a relation like group HAS MANY profiles. Instead, the relation should be group HAS MANY users, but then, I would have to put a *group_id* column on the users table, which doesn't really fit in, since the users table only stores auth information.
On the other side, I would like to list all the users enrolled in a group using an ORM and getting the a users collection and not profiles. The way I see it, is that the users table is like the 'parent' and the profiles table extends the users table.
The same problem would occur when setting attendances for events. Should I reference the profile as a foreign key in the events_attendance table? Or should I reference the user ID?
Of course both solutions could be implemented and work, but which of them is the best choice?
I have dug a little and found that both solutions would comply with 3NF, so in theory, would be correct, but I'm having a hard time designing the right way my database.
This is a question of your own conventions. You need to decide what is the main entity, right after that you can easiy find a proper solution. Both ways are good, but if you think of User as of the main entity while Profile is a property then you should put GroupId into User, otherwise, if you mean User and Profile as a single entity, you can leave GroupId in Profile, and by this you're not saying group HAS MANY profiles but group HAS MANY users.
By setting a proper one-to-one relation (User-Profile) you can force your data integrity good enough.

put login and password in one table or in multiple tables for each type of user?

I have different 3 types of users and each type of user can have columns and relationships with tables that another type doesn't, but all of them have login(Unique) and password,
how would you do:
create a table for each type or
create one table for all of them or
create a table for all of them only for login and password and separate for all the other things and bind them with a FK
something else
Number 3 is the best of the options you suggested (updated slightly for clarification):
create a table for all of them for login and password and anything else that is shared and a separate table for all the other things that are not shared and bind them with a FK
Except don't store the password, store a hashed version of a salted password.
An alternative might be to assign groups and/or roles to your users. This might be more flexible than a fixed table structure, allowing you to add new roles dynamically. But it depends on your needs whether this is useful for you or not.
As Aaronaught pointed out, in the main table you need an AccountType to ensure that a user can only have one of the roles. You must remember to check the value of this column when joining the tables to ensure that a user has only one role active.
A unique constraint on the foreign key ensures that a user can only have a role once.