Database Design Advice for a Social Network App Needed - database

I am very new into backend stuffs like databases. That being said, I lack the database design knowledge.
I am wondering how and what is the best design for my scenario.
I am creating a social network app where the users can create groups and join other groups. Those groups have places in it. Those places are created by the User in the group
User
Group
Place
Rules:
One User can create and join many Groups
One Group can contain many Users
One Group can have many Places
Each Group have an admin User
I currently have 3 separate tables
1. USER TABLE
ID, EMAIL, USERNAME, PASSWORD, PROFILE PICTURE
2. GROUP TABLE
ID, NAME
3. PLACE TABLE
ID, NAME, COORDINATE, RADIUS
I am extremely confused in designing the proper database for it it.
Question:
How should I design the relation of the table.
I would like to have one User (maybe more) in a Group that has the permission to do certain stuff that normal User cant do. Such as Creating New Place, Deleting A Place
How should I define my table structure?
Any thoughts please? Any help is greatly appreciated!!
Thank you

You will need to have one more table in order to create what is known as a many to many relationship between the users and the groups.
Since you didn't specify the rdbms you are working with, I'll use SQL Server for my code:
CREATE TABLE TblUserToGroup
(
UserToGroup_UserId int FOREIGN KEY REFERENCES TblUser(UserId),
UserToGroup_GroupId int FOREIGN KEY REFERENCES TblGroup(GroupId),
UserToGroup_IsAdmin bit DEFAULT 0
CONSTRAINT UC_UserToGroup UNIQUE(UserToGroup_UserId, UserToGroup_GroupId)
)
As you can see, there is also an IsAdmin column that can take values of 0 or 1. If you only want one admin user for each team, you can add a check constraint to prevent having more then one admin for each group.

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.

Best Table Relationship Design for Similar Entities

I am trying to figure out the best way to set up my Entity Diagram. I will explain based on the image below.
tblParentCustomer: This table stores information for our Primary Customers, which can either be a Business or Consumer.(They are identified using a lookup table tblCustomerType.)
tblChildCustomer: This table stores customers that are under the Primary Customer. The Primary Business customers can have Authorized Employees and Authorized Reps. The Primary Consumer customers can have Authorized Users. (They are identified using a lookup table tblCustomerType.)
tblChildAccountNumber: This table stores AccountNumbers for tblChildCustomer. These account numbers are mainly for the Child Business Customers. I may be adding Account Numbers for the Child Consumer customers, I am not sure yet, but I believe this design will allow for that if/when necessary.
Going back to tblParentCustomer : If this customer is a Consumer, I will need to add account numbers for them. My question is, do I create a 1 - Many relationship between tblParentCustomer and tblParentAccountNumber? This option would give me 2 different Account Number Tables.
Or would it make sense to create a Junction Account Table that intersects tblParentCustomer and tblChildCustomer?
The first option doesn't really make sense to me because what if there is only 1 Account number for a customer but multiple childCustomers?
Does it make sense to have 2 similar Account Tables that serve a different purpose?
Creating a many-to-many the way you want it to be, you need a link table that will make the whole thing go from 1-* and then *-1
That link table will have two FK, one linking to the parentTable and one linking to the childTable. Combination of those two FK will give you a composite PK (this is important to avoid duplicates). It will allow for any customer to be part of as many accounts as possible (duh.. it'll make the parent/child table a many-to-many relationship).
This approach is extremely common with regards to CRM or any Accounts containing people. Bring it one step further and in that table, you might want to add a "is primary contact" in the AccountMembers table. Drop the childAccountNumber table; you don't need it.

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.

Users, Customers, Tenants, Employees - All in the same table?

In this case let me be more specific about the problem
I've got a peoples table(with customer & supplier) and I've got a users table(for users who can login).
Currently I have this DB structure
Customers -> Organisations -> linked through rel_customer_addresses to address table.
(as 1 customer could have delivery_address, invoice address etc.)
Users -> Tenants -> linked through rel_users_addresses to the address table
(as 1 user could have delivery_address, invoice address etc.)
Now I've got in the invoice table customer_key. The problem is when the user himself is the customer and the invoice is from one of his customers. How do I indicate my web app to look up user and not the customer?
Since you're looking at 2 separate entities (customers and users), I would go ahead and use 2 separate tables and have them share a unique identifier (i.e., username, SID).
That way there's no chance of one seeing information from the other without the appropriate permissions.
There are several ways to control this, but the logic is something like this.
If userID exists in table user, do this.
If userID exists in table customer, do this.
If userID exists in table user AND table customer, do this.
That way you can control the situation completely either independently or together. In other words, you could grant special permissions to userID that is found in table customer, or just make it completely separate (similar to say, how facebook makes a separate 'identity' for pages vs the account it's registered to).
Hope that helps!

How to model this one-to-one relation?

I have several entities which respresent different types of users who need to be able to log in to a particular system. Additionally, they have different types of information associated with them.
For example: a "general user", which has an e-mail address and "admin user", which has a workstation number (note that this a hypothetical case). Both entities also share common properties like first name, surname, address and telephone number. Finally, they naturally need to have a (unique) user name and a password to log in.
In the application, the user just has to fill in his user name and password, and the functionality of the application changes slightly according to the type of the user. You can imagine that the username needs to be unique for this work.
How should I model this effectively?
I can't just create two tables, because then I can't force a unique constaint on the user name.
I also can't put them all in just one table, because they have different types of specific information associated to them.
I think I might need 3 seperate tables, one for "users" (with user name and password), one for the "general users" and another one for the "admin users", but how would the relations between these work? Or is there another solution?
(By the way, the target DBMS is MySQL, so I don't think generalization is supported in the database system itself).
Your 3 tables approach seems Ok.
In users table have only ID, username, password,usertype.
In general users table have ID, UserID (from users table), other fields.
Same thing for admin users.
Usertype field will tell you from what table to search for additional info
if(usertype==admin)
select * from admins where userid=:id;
else
select * from general where userid=:id;
Two tables. USERS with user names, first, last, etc. ROLES with roles, and a link back to the user name (or user id or whatever). Put a unique constraint on the user name. Put workstation nbr, email, phone, whatever else you need, in the user table. Put 2 columns in the ROLES table -- USERID and ROLE.
You should decide how much specific information is being stored (or likely to be stored in the future) and make the decision based on that. If there are only a handful of fields for each user type then using a single table is alright.
USERS table (name, type, email, password, genfield1, genfield2, adminfield1, adminfield2)
Make sure to include the type (don't assume because some of the fields particular to that user are filled in that the user is of that type) field. Any queries will just need to include the "AND usertype = " clause.
If there are many fields or rules associated with each type then your idea of three tables is the best.
USERS table (ID, type, name, password)
GENUSERS (ID, genfield1, genfield2)
ADMINUSERS(ID, adminfield1, adminfield2)
The constraints between IDs on the table are all you need (and the main USERS table keeps the IDs unique). Works very well in most situations but reports that include both types of users with their specific fields have to be done in two parts (unioned SQL or subqueries or multiple left joins).
You can solve it with one 'general' users table containing the information thats available for all users and 1 table for every specific user type. In your example you will then need 3 tables.
Users: This table holds only information shared between all usertypes, ie. UserId, Name, Address, etc.
GeneralUsers: This table 'extends' the Users table by providing a foreing key UserId that references the Users table. In addition, information specific to general users are held here, fx. EmailAddress, etc.
AdminUsers: As with GeneralUsers, this table also 'extends' the Users table by providing a foreign key UserId referencing the Users table. In addition information specific to admin users are held here, fx. WorkstationId, etc.
With this approach you can add additional 'specializations' if the need arises by simply adding new tables that 'extends' the Users table using a foreign key reference. You can also create several levels of specialization. If for example admin users are general users as well as admin users then AdminUsers could 'extend' GeneralUsers instead of Users simply by using a foreing key to GeneralUsers instead of Users.
When you need to retreive data from this model you need to which type of user to query. If for example you need to query a GeneralUser you will need something similar to:
SELECT * FROM GeneralUsers
LEFT JOIN Users ON GeneralUsers.UserId = Users.UserId
Or if querying an admin user
SELECT * FROM AdminUsers
LEFT JOIN Users ON AdminUsers.UserId = Users.UserId
If you have additional levels of specialization, for example by having admin users also being general users you just join your way back.
SELECT * FROM AdminUsers
LEFT JOIN GeneralUsers ON AdminUsers.UserId = GeneralUsers.UserId
LEFT JOIN Users ON GeneralUsers.UsersId = Users.UserId
I most definitely would not do a model where you have separate tables as in GeneralUser, AdminUser and ReadOnlyUser.
In database design, a good rule of thumb is "Down beats across". Instead of multiple tables (one for each type), I would create a SystemUsers table, and a Roles table and define a join table to put SystemUsers in Roles. Also, I would define individual roles.
This way, a user can be added to and removed from multiple roles.
A role can have multiple permissions, which can be modified at any time.
Joins to other places do not need a GeneralUserId, AdminUserId and ReadOnlyUserId column - just a SystemUserId column.
This is very similar to the ASP.Net role based security model.
alt text http://img52.imageshack.us/img52/2861/rolebasedsecurity.jpg

Resources