MySQL database design - trouble figuring out table relationships - mysql

I'm trying to figure out the best way to design these tables for a website I'm making for a school club. I want to set it up so each user can have multiple emails, phone numbers, and addresses tied to their account. To do this I tried to tie all these things to a contacts table and store the contacts id in the users table as a foreign key. The contacts id is also a foreign key in the emails, phone numbers, and addresses table. Is this a feasible way of relating these tables or should I just cut out the middle man (contacts table) and store the user id in the emails, phone numbers, and addresses tables?
Just in case my description of the relationships weren't enough, here is an ERD for the tables:
Sorry for such a "noob" question, it's been a while since I had to build a database with more complexity than 2 tables. Any general tips for database design are very much welcomed as well.

All you need to do is remove the Contacts table and store the user_id in the tables on the right, rather than contact_id.
Remove contact_id from Users as well.

I have dealt with this very question in the past. We did it wrong and we were sorry.
The determining factors should be these:
Will you have any other category of person that isn't a user, for whom you need to store contact information?
Will those kinds of persons somehow be "fungible" with users?
If you answer both these questions "yes," keep your contact table. Otherwise get rid of it.
The mistake made by a team I worked on was our answer to the second question. We had medical patients and doctors/nurses/etc as our categories of people. We stored their contact information together. But we shouldn't have done that because patients' contact information is very sensitive and confidential, but health care provider information is much less so. We were always wishing we didn't have the two kinds of data in just one set of tables after the system became successful.
Unless you can convince yourself you need your contact table, get rid of it, I say!

Yes I would cut out the midle man:
Although I was tempted to go the 'contact_type' route, I have found that there are usually validations and different data types which become more complicated when the contact is generic. For instance a table that has address fields is not the same as a phone number and having both presents more complexity and less readability.
This model focuses on simplicity, e.g. a user has many emails and an email belongs ot a user.

According to me you can design DB accordingly
Table 1 : Users
UserID //PK
Name
Table 2 : Contacts
ContactID //PK
UserID //FK to Users
ContactTypeID // FK to ContactType
Value
Table 3 : ContactType
ContactTypeID //PK
ContactTypeName
Description
Table 1 is pretty clear stores user information
Table 3 holds information about contacttype i.e email, home phone, mobile, home address, shipping address, etc
Table 2 holds information about user, contact type and its value
like cinatacttypeid corresponds to mobile than value is , etc.

Related

best practice for designing system with multiple user type

We have a system with two main roles: service provider and customer. The provider side is users like doctors, nurses, and caregivers. The customer side is just the customer. all user types contain some common data and some uncommon data. in the current system, we have a table for each user type, and for common data, we have User table. currect system ERD is:
https://s4.uupload.ir/files/screenshot-20210710165449-1007x662_tpwd.png
in the current system, we have a lot of tables and we think about reducing them. our vision is to bring all user types in a single table called User and instead of a lot of tables, we have more columns. of course in some users, we have empty cells that do not belong to this user type.
I have 4 questions:
is it ok to bring customers and providers to a table like User?
what is the optimal number of columns in a table?
load a row with a lot of columns OR relation between different tables?
provider type should be a separate table or can be an enum?
It is best to put all users in single table. So when you check login there is less place to do mistake. When selecting user you dont need to use SELECT * FROM... You can use SELECT id, username, name FROM...
Dont put too many columns, if there is some data which you dont need when searching or displaying users, you can create helper table "user_meta" with dolumns user_id, meta_key, value where user_id and meta_key are primary key
Answered by first 2 answers
Provider type should be enum if there will not bee needs to expand with additional types.

How to handle unified relationships of different tables (eg. Customers/Companies and Addresses)

I'll start of with what I have already:
I've learned at uni how to create databases and now I'm trying to create my own for personal use and possible use for my customer base. The people I work for are on the one hand businesses (Companies) and on the other hand privates (Customers).
I tried to build my database like shown above. I want to be able to add multiple addresses to both my customers and companies. I also have several employees that work for me.
Now, I'm pretty happy with what I have right now but I have the feeling it can be simpler but with the same capabilities (multiple addresses, ...).
Secondly, both Companies and Customers can make orders. Right now I only have a table for Customers to place an order and I'm clueless how I can do the same for Companies.
Should I make a CustomerOrder and CompanyOrder table to achieve this or is there a better solution?
EDIT
I played around a little and actually started over. I tried to take each part like email, phone, fax and put it in its own table. This way, if I update a phone number somewhere and it's used elsewhere, both will be updated.
Below is what I have so far:
Phone, Phone_1 and Phone_2 are the same table, Access just displays it that way. Any suggestions on how I'm doing? ContactType is used if there is CustomerSupport or TechnicalSupport. Type in EntityAddress is to determine if the Address is for a Person or a Company. This way it's expandable for more entities.
Now that I'm Writing this, would it be a good idea to do the same for Phone, Email and Fax like I do with Address?
What I would suggest you is to create a separate table for orders with no link to either customers or to companies. Then you create 2 intermediate tables to link order and company together on the one hand and order and customers together on the other hand.
Fields in the table will look like:
LinkID
CustomerID / CompanyID
OrderID
It avoids having twice the same table (order table).
For the phones, you can do the same thing. This way you can have as many phone numbers as you like linked to one company or customer.

Proper way to model user groups

So I have this application that I'm drawing up and I start to think about my users. Well, My initial thought was to create a table for each group type. I've been thinking this over though and I'm not sure that this is the best way.
Example:
// Users
Users [id, name, email, age, etc]
// User Groups
Player [id, years playing, etc]
Ref [id, certified, etc]
Manufacturer Rep [id, years employed, etc]
So everyone would be making an account, but each user would have a different group. They can also be in multiple different groups. Each group has it's own list of different columns. So what is the best way to do this? Lets say I have 5 groups. Do I need 8 tables + a relational table connecting each one to the user table?
I just want to be sure that this is the best way to organize it before I build it.
Edit:
A player would have columns regarding the gear that they use to play, the teams they've played with, events they've gone to.
A ref would have info regarding the certifications they have and the events they've reffed.
Manufacturer reps would have info regarding their position within the company they rep.
A parent would have information regarding how long they've been involved with the sport, perhaps relations with the users they are parent of.
Just as an example.
Edit 2:
**Player Table
id
user id
started date
stopped date
rank
**Ref Table
id
user id
started date
stopped date
is certified
certified by
verified
**Photographer / Videographer / News Reporter Table
id
user id
started date
stopped date
worked under name
website / channel link
about
verified
**Tournament / Big Game Rep Table
id
user id
started date
stopped date
position
tourney id
verified
**Store / Field / Manufacturer Rep Table
id
user id
started date
stopped date
position
store / field / man. id
verified
This is what I planned out so far. I'm still new to this so I could be doing it completely wrong. And it's only five groups. It was more until I condensed it some.
Although I find it weird having so many entities which are different from each other, but I will ignore this and get to the question.
It depends on the group criteria you need, in the case you described where each group has its own columns and information I guess your design is a good one, especially if you need the information in a readable form in the database. If you need all groups in a single table you will have to save the group relevant information in a kind of object, either a blob, XML string or any other form, but then you will lose the ability to filter on these criteria using the database.
In a relational Database I would do it using the design you described.
The design of your tables greatly depends on the requirements of your software.
E.g. your description of users led me in a wrong direction, I was at first thinking about a "normal" user of a software. Basically name, login-information and stuff like that. This I would never split over different tables as it really makes tasks like login, session handling, ... really complicated.
Another point which surprised me, was that you want to store the equipment in columns of those user's tables. Usually the relationship between a person and his equipment is not 1 to 1 and in most cases the amount of different equipment varies. Thus you usually have a relationship between users and their equipment (1:n). Thus you would design an equipment table and there refer to the owner's user id.
But after you have an idea of which data you have in your application and which relationships exist between your data, the design of the tables and so on is rather straitforward.
The good news is, that your data model and database design will develop over time. Try to start with a basic model, covering the majority of your use cases. Then slowly add more use cases / aspects.
As long as you are in the stage of planning and early implementation phasis, it is rather easy to change your database design.

Database design for user driven website

Assuming I want to have a web application that requires storing user information, images, etc as well as storing status updates or posts/comments would I want to separate tables?
For example if I have a "users" table that contains users information like passwords, emails, and typical social networking info like age, location etc. Would it be a good idea do create a second table("posts") that handles user content such as comments and/or post?
Table one: "users"
UserID
Username
Age
etc.
Table Two: "posts"
PostID
PostContent
PostAuthor
PostDate
etc
Is this a valid organization? Furthermore if I wanted to keep track of media should I do this in ANOTHER table?
Table Three: "media"
ID
Type
Uploader
etc.
Any help is much appreciated. I'm curious to see if I'm on the right track or just completely lost. I am mostly wondering if I should have many tables or if I should have larger less segregated tables.
Also of note thus far I planned on keeping information such as followers(or friends) in the 'users' table but I'm not sure that's a good idea in retrospect.
thanks in advance,
Generally speaking to design a database you create a table for each object you will be dealing with. In you example you have Users, Posts, Comments and Media. From that you can flesh out what it is you want to store for each object. Each item you want to store is a field in the table:
[Users]
ID
Username
PasswordHash
Age
Birthdate
Email
JoinDate
LastLogin
[Posts]
ID
UserID
Title
Content
CreateDate
PostedDate
[Comments]
ID
PostID
UserID
Content
[Media]
ID
Title
Description
FileURI
Taking a look above you can see a basic structure for holding the information for each object. By the field names you can even tell the relationships between the objects. That is a post has a UserID so the post was created by that user. the comments have a PostID and a UserID so you can see that a comment was written by a person for a specific post.
Once you have the general fields identified you can look at some other aspects of the design. For example right now the Email field under the Users table means that a user can have one (1) email address, no more. You can solve this one of two ways... add more email fields (EmailA, EmailB, EmailC) this generally works if you know there are specific types of emails you are dealing with, for example EmailWork or EmailHome. This doesn't work if you do not know how many emails in total there will be. To solve this you can pull the emails out into its own table:
[Users]
ID
Username
PasswordHash
Age
Birthdate
JoinDate
LastLogin
[Emails]
ID
UserID
Email
Now you can have any number of emails for a single user. You can do this for just about any database you are trying to design. Take it in small steps and break your bigger objects into smaller ones as needed.
Update
To deal with friends you should think about the relationship you are dealing with. There is one (1) person with many friends. In relation to the tables above its one User to many Users. This can be done with a special table that hold no information other than the relationship you are looking for.
[Friends]
[UserA]
[UserB]
So if the current user's ID is in A his friend's ID is in B and visa-verse. This sets up the friendship so that if you are my friend, then I am your friend. There is no way for me to be your friend without you being mine. If you want to setup the ability for one way friendships you can setup the table like this:
[Friends]
[UserID]
[FriendID]
So If we are both friends with each other there would have to be 2 records, one for my friendship to you and one for your freindship to me.
You need to use multiple tables.
The amount of tables depends on how complex you want your interactive site to be. Based on what you have posted you would need a table that would store information about the users, a table for comments, and more such as a table to store status types.
For example tbl_Users should store:
1. UserID
2. First Name
3. Last name
4. Email
5. Password (encrypted)
6. Address
7. City
8. State
9. Country
10. Date of Birth
11. UserStatus
12. Etc
This project sounds like it should be using a relational DB that will pull up records, such as comments, by relative userIDs.
This means that you will need a table that stores the following:
1. CommentID (primary key, int, auto-increment)
2. Comment (text)
3. UserID (foreign key, int)
The comment is attached to a user through a foreign key, which is essentially the userId from the tbl_Users table. You would need to combine these tables in an SQL statement with your script to query the information as a single piece of information. See example code
$sql_userWall = "SELECT tbl_Users.*, tbl_Comments.*, tbl_userStatus FROM tbl_Users
INNER JOIN tbl_Comments ON tbl_Users.userID = tbl_Comments.userID
INNER JOIN tbl_UserStatus ON tbl_Users.userID = tbl.UserStatus
WHERE tbl_Users.userID = $userID";
This statement essentially says get the information of the provided user from the users table and also get all the comments with that has the same userID attached to it, and get the userStatus from the table of user status'.
Therefore you would need a table called tbl_userStatus that held unique statusIDs (primary key, int, auto-incrementing) along with a text (varchar) of a determined length that may say for example "online" or "offline". When you started the write the info out from e record using php, asp or a similar language the table will automatically retrieve the information from tbl_userStatus for you just by using a simple line like
<?php echo $_REQUEST['userStatus']; ?>
No extra work necessary. Most of your project time will be spent developing the DB structure and writing SQL statements that correctly retrieve the info you want for each page.
There are many great YouTube video series that describe relational DBS and drawing entity relational diagrams. This is what you should look into for learning more on creating the tye of project you were describing.
One last note, if you wanted comments to be visible for all members of a group this would describe what is known as a many-to-many relationship which would require additional tables to allow for multiple users to 'own' a relationship to a single table. You could store a single groupID that referred to a table of groups.
tbl_groups
1. GroupID
2. GroupName
3. More group info, etc
And a table of users registered for the group
Tbl_groupMembers
1. membershipCountID (primary key, int, auto-increment)
2. GroupID (foriegn key, int)
3. UserID (foriegn key, int)
This allows users to registrar for a group and inner join them to group based comments. These relationships take a little more time to understand, the videos will help greatly.
I hope this helps, I'll come back and post some YouTube links later that I found helpful learning this stuff.

How do I design a contacts database and store multiple line items per user?

I want to create a small invoicing application. My first step is creating a database with two tables where each client can have multiple addresses and phone numbers.
I think its safe to assume here that I am dealing with a one to many relationship. But how should I design the tables and fields so they can store multiple addresses and phone numbers per user? By multiple I also mean indeterminate since so I can't just have x no of columns in my table. Off Hand, here is what I was thinking:
Clients
- Id
- Notes
CONTACTS
- id
- client_id
- address
- phone number
Now I am trying to avoid a third join table like this:
Clients_Contacts
- id
- client_id
- contact id
because I still want a one to many and not many to many relationship between contacts and clients. Is there something wrong with the way I am thinking about this? Can someone please help me design this database and show me what a sample query querying multiple addresses would look like.
Why would you nead a join table?
I would have
Client
- ID (PK, FK of Contact)
- Notes
Contact
- ID (PK)
- client_id
- address
- phone_number
Then just set the ID of the client to be the value of client_id within the contact information.
This way, multiple Contact records can have the same client_id.
Your first idea looks fine for your use-case (one to many). You'll only need the third join table if you want a many to many relationship, which you do not want.
A sample query to get all addresses from a specific client would be:
SELECT address FROM Contacts WHERE client_id = 1
You say you want to store multiple addresses and phone numbers per user (= client, I assume?). Your current model already supports this. Every client can have as many contacts as needed (each contact would have the client_id set to the client's id). Only if you want to assign a single contact (address/phone number) to multiple clients as well would you need the third table.