Two foreign keys from one table - database

I am trying in following DB ERD that User creates a Profile. A user can see his followers as well as the profiles that users are following.
The problem is:
Both sections either "Followers" or "Following" are users not Profile
Update:
Is the following approach okay or in above diagram?
SQL> Create table users(
2 user_id number(5) primary key,
3 reg_date date,
4 name varchar2(50),
5 password varchar2(50));
Table created.
SQL> Create table Follow(
2 follow_id number(5),
3 following number(5) constraint User_fk references users(user_id),
4 follower number(5) constraint User_fk1 references users(user_id));
Table created.
Please advise. Thanks in anticipation

Should Profile be an entity/table separated from User, or should they be merged?
This depends on your requirements. If a user has just one profile (as on many sites, e.g. on this one), the profile doesn't need to be a separate entity. Then the question whether the following relationship should point to users or to profiles vanishes. If, however, a user can have more than one profile (which might be guessed from your FK type_id), let's say one for his sports and another for his musical interests, then two entities and tables are needed.
Should Follower point to User or to Profile?
In the case of just one User entity, follower and following must both point to User, as there is nothing else. This is your SQL solution.
In the case of a separate Profile entity, it's again up to your requirements. Should the follower follow the user as a whole, or is he just interested in a certain profile angle of the user? (Follow Jack, or follow Jack as a sportsman, but not as a musician.) In the first case, following points to the User, otherwise to the Profile.

Related

multiple users Database design

I'm creating a db schema that involves users that can have multiple users.
I want to register different companies to use the web services.
For example:
user A or B (etc) can signup and create a company account
user A can create multiple accounts of other users with their types, similarly user B
If user A or B create different accounts, how would I know this particular user is belong to User A or B company ? I think user table have many to many relationship with itself (like basic friendship design).
Please suggest the best design .
Ex.
User 3,4 belongs to User A
User 5,6 belongs to User B
In general, I would recommend starting by identifying all the entities you are trying to persist. It sounds like you have two distinct entities in your question. One being "user," which represents a single person. Your second entity is "company." A "user" can belong to a company.
An example of a database design would be one table for users, and one table for companies. In the "users" table, you would want to have a foreign key column that references the primary key (unique id) of the company the user belongs to. If each user can only belong to one company, this becomes a simple one to many relationship.
In short, I would highly recommend treating company accounts separately from user accounts, since they are fundamentally different entities.

One to two (1:2) relation between two tables

I'm working on some asp.net application, I got stuck in following business.
Suppose we have a person, and he can open both types of accounts and each account has some transaction history. Person table has some primary key say PPK, and customer table has some PK as PIN.
My question is how to solve/present this scenario in database, relation of person table to customer table is 1:2 as no person can have more than two account. and what about that transaction table? that holds all transaction history for some specific account? shall I make two transaction table (which is really a bad idea because as account type exceeds transaction tables exceeds).
Can I build their relation as 1:* (then I may need another table for that. it holds Fk of both table. )
or Can make pin as unique key and always open database for like checking limit of accounts (i.e. two).
I really need some suggestions.
All suggestions are welcome.
Thanks!
P.S: If you dont understand the question please ask me before reporting it away please!
You can either do something like this:
Or something like this:
The first model allows adding more accounts by just changing the CHECK (in case requirements change in the future), while the second would require adding another column in such case.
NOTE: The above assumes both account types are structurally identical, so they "fit" into same table. If that's not the case, you can use inheritance.
Ok you have a person table and an account table with a foreign key relationship between the two which is 1 person to many accounts. Then you have a transaction table that is related to the account id in the account table which is also 1 account to many transacations.
Now to enforce the limit of only two accounts being allowed, for that you want a trigger that checks when a record is being inserted or updated to amek sure the person currently has no more than one other record.

Need an idea for designing DB for a University -- Messeging system issue

I have a University system project for my db lab.
I should have a unique login page for all the 3 user types: 1.student 2.Teacher 3.Supervisor
I already separated them in 3 tables(each has its unique properties).
My problems:
How to check when someone tries to log in?(which table should be checked and how to prevent duplicate usernames however they are in 3 different tables).
How to send messages between these 3 types although there is no central unique table to lookup(3 tables should be checked and there is a chance of username duplication)
My current ERD:
You should have all the users with their type in one table and additional information in separate tables.
you do not show any difference between the Students and the Professors in the schema.
also there is no 'supervisor' table.
i would suggest renaming the table to users - and adding a type or role column.
also:
the professors should be many to many with the courses also - assuming one professor can teach more than one course.
in the case where you combine the users, then there should also be a role on the association between users and courses identifying whether that user is a professor of that course, a student, an auditor, an associate, a substitute - etc.

Normalizing Foreign Keys with Junction & Lookup Tables

I've been scratching my head lately over the relationship between database normalization and foreign keys with respect to junction tables and lookup tables.
I’ve currently have the following tables: Users, UserTypes, Roles, UsersInRoles, and Permissions. UserTypes is simply a lookup table providing the name of the type, with description, via a foreign key in the Users table. Roles are the various roles with associated Permissions linked to each User via the UsersInRoles table.
I need to come up with a structure that allows me to provide multiple Roles for each User, in addition to special permissions for each respective User that may not be covered in the fixed Roles of which they are a member.
I had a foreign key to my UsersInRoles table from the Users table, but decided that it just didn’t make sense. Conversely, it seems to make perfect sense to use a foreign key from the Users table to the UserTypes table. Is this the rule of thumb? That junction tables have foreign keys linking to the primary keys of the tables it joins, while master tables have foreign keys linking to the primary key of associated lookup tables?
Parameters:
Each User can have one or multiple Roles
Each Role has a fixed set of Permissions
Each User can have additional Permissions not provided by their Roles
I suspect I may also need a PermissionsInRoles junction table as well as one for PermissionsInUsers? But this is just ridiculous isn't it? There just must be a better way. I'm thoroughly convinced that I'm losing my mind here, lol. Any help would be greatly appreciated. This has got my head spinning :P
UPDATE
Is this basically how it would be setup? I might get rid of the UsersInRoles table so each user can only be in one role, and additional permissions can be added via the SpecialPermissions junction table. From a UI standpoint, I was thinking it might be good when assigning permissions to a user, selecting a "Role" would simply check the appropriate boxes associated with that role, then you customize that and submit. That way I think I would only need a junction table between the Users and Permissions tables perhaps? Ugh. This is quite daunting for a first time database designer haha. Remember when you were just starting out? Or maybe you guys are more of a genius than I am, lol.
Schema Image link (can't post images yet)
Here's a neat scholarly article (albeit 10 years old) on query-driven database design titled: "Robust Database Design for Diverse Query Patterns". The Conclusion section has an interesting approach.
I suspect I may also need a PermissionsInRoles junction table as well
as one for PermissionsInUsers?
Well, you already said one of the requirements was "Each Role has a fixed set of Permissions". So to fulfill that requirement, you need to store permissions that apply to each role.
Table: role_permissions
PK: (Role, Permission)
Role Permission
--
User Create
User Update
Admin Create
Admin Update
Admin Delete
You don't need two different tables to implement that requirement.
By the same token, you've already said "Each User can have additional Permissions not provided by their Roles". To fulfill that requirement, you have to store user-specific permissions.
Table: user_permissions
PK: (username, permission)
username permission
--
user1 Rename
user1 Leak to News of the World
user2 Randomly corrupt data
So, again, you don't need two different tables to implement that requirement. Both those tables are in 5NF.
But this is just ridiculous isn't it?
What's ridiculous?
That you have very elaborate requirements for permissions?
That you store business data (like permissions) in tables?
That it takes more than one table to model your permission requirements?
Something else?
If you want specific advice about your actual tables, edit your question and insert DDL for your tables.
Later
I looked at your diagram. Not every table needs an id number; id numbers have nothing to do with normalization.
If I were designing your system, I probably wouldn't use id numbers in the tables Roles, Permissions, and UserTypes until I saw a performance problem that id numbers could fix. (In most systems over the last 30 years, that means, well, almost never.) Before I used an id number, I'd also consider and test using a human-readable code instead. Human-readable codes often don't require joins; id numbers always require joins.
In most SQL dbms, you can combine a data type and check constraint in a CREATE DOMAIN statement. In PostgreSQL, you might use something like this to reduce the number of tables.
CREATE DOMAIN role AS VARCHAR(7) NOT NULL
CHECK (VALUE in ('Admin', 'User', 'Guest'));
Followed by
CREATE TABLE user_roles (
user_id integer not null references users (id),
role_name role
);
Replacing a table with a CREATE DOMAIN statement is most useful when the number of rows is stable and relatively small. Personally, I'd rather have the tables.
If you stick with id numbers, you also need UNIQUE constraints on Roles.RoleName, Permissions.Description, and UserTypes.UserType.
Otherwise, you seem to be doing fine.
If your securables are just a products table (or set of tables), and you're using SSMS (SQL-Server Management Studio) then you should not be inventing your own security schema from scratch.
What I would recommend is that you setup your users and roles in SSMS -- expand the Database, then --> Security --> Users, etc. Right-click a user, look for securables, and then you can assign the user to roles, or also, just objects (tables, etc.) directly. Or right-click roles and you have similar options. Whatever you do, stay away from creating your own security schema, if you can help it.
If you need your web app to have access to the database, then look into "utility accounts" (these are like users, created at the server level instead of the database level, but then you can bring them into your database from there.); or look into impersonation if you're able to pass users' creds from your internal network when they login to the database. Utility accounts or users can be assigned to roles, or granted direct access to database objects without roles -- whatever you need.
One thing I've done before, in a similar-sounding scenario:
Keep Roles and users in the same table.
Have an objects table (the tables/queries/forms/etc. you will be granting permissions to)
Have a permission table -- this is where you will link roles/users to objects (i.e., John can SELECT on table 1)
Finally, have an Inheritance table -- this is where you will link roles/users to each other (i.e., John has permission to do whatever Role1 can do)
For example -- a structure like this:
For example:
Users Table:
UserID -- User -- UserTypeID
1 ------- John Smith --- 1
2 ------- Sally Fort --- 1
3 ------- Public Role -- 2
4 ------- Special Role - 2
UserType Table:
UserTypeID -- Description
1 ----------- Human Being
2 ----------- Role
Objects Table:
1 -- Data-Entry Form 1
2 -- Data-Entry Form 2
3 -- Query 1
4 -- Table 1
Permissions Table
UserID -- ObjectID -- Permission
1 -- 1 -- Update (This says John can Update Data-Entry Form 1 (via direct permission))
3 -- 1 -- Update (This says that the Public Role can Update Data-Entry Form 1)
3 -- 2 -- Update (...as well as Data-Entry Form 2)
4 -- 3 -- Select (This says that the special role can Select from Query1)
4 -- 4 -- Insert (...the special role can Insert into Table1)
Permission Inheritance Table
UserID -- UserID_ToInheritFrom
1 -- 3 (this says John can do whatever the Public Role can do)
1 -- 4 (this says John can do whatever the Special Role can do)
2 -- 3 (this says Sally can do whatever the Public Role can do)
So then if you wanted to query, "What can John do?", you'd do something like this:
SELECT
ObjectID,
Permission
FROM
PermissionsTable
WHERE
UserID = 1 -- John has direct permission
OR UserID IN (SELECT UserID_ToInheritFrom FROM PermissionInheritanceTable WHERE UserID = 1)
-- John has indirect permission via the Permission Inheritance Table (or you can call it the "role
-- membership table" if that's easier for you to think of that way.)
This implementation works well. If you want to see a similar implementation, look at SQL-Server's implementation (or better yet, USE it, instead of re-creating the wheel from scratch.)

User, customer, admin account in 3 different tables?

In my web application I will have three types of accounts.
User: for using the web application for free
Customer: for advertising and getting a Company Logo
Admin: for editing and deleting stuff
Should all these three be in separate tables or in one with a column named "account_type" where i can mark it as User, Customer or Admin?
What are the pros and cons for both? Is there a best practice for this?
Thanks
In general, a person can be user, customer and admin -- so, I would start with a Person table with columns IsCustomer, IsUser, IsAdmin. Later (for fast search) you may decide to add separate tables Admin, Customers, Users with FK to the Person table.
EDIT:
A typical case may be:
5 million users
1000 customers
10 admins
In general, having separate tables for customers and admins should speed-up any admin/customer related query.
If a user can only be one type, you'd be better off with one table and a bit field for IsAdministrator, etc.
If a user can be of more than one account type, you should then have a different table with a foreign key,
sample structure (data sypes are SQL Server and suggested only)
Users table
UserID - int
Username - varchar(25)
Password - varchar(25)
Firstname - varchar(50) etc...
Roles table
RoleId - int
Role Description - varchar(25)
User_Roles table
UserId - int (with a foregin key to the Users table)
RoleId int (foreign key to the Roles table)
Pros and Cons vary based on the size and complexity of your system.
I would break it up into User, Role, UserResources
User (would define basic information)
User Roles
FK->RoleType
Role_Type (user, admin, customer, possibly permissions or you could break this out further).
UserResources (media)
FK->User

Resources