Database normalization multiple repetitions - database

I am programming an application and I need to do a database to store the data. The information is similar to the next simple example:
There are multiple restaurants and each restaurant has to send their food to the clients.
The database should be something like:
Restaurant | Food | Where to carry | Who carries
There are multiple restaurants (A, B, C, D...), the food is the same in all the restaurants (hamburgers, fish and salads), the people who carries the food could be working in all the restaurants, and the same house could be asking for food to diferent restaurants. All the information should be stored in a database.
In this case, I want to do a database at least in third normal form. Is it a good practice to make a single database and store all the data in this specific case?
I informed a lot but don't know if I'm doing it the right way because in this case the same information is repeated multiple times like Restaurant X food Y.
Thank you in advance!

The best way is to design it like this:
Restaurant table with the restaurant details i.e. id, name, address etc.
Food table with the food details i.e food name, food id, food price etc
Another table, which may be named as Orders, where you have the restaurant id, order id, house address from which the order was placed.
OrderFood table which contains the order id and food id where both are foreign keys and both combine to form the primary key.
And it is not a good practice to store everything in one table which increases redundancy. Hope this helps.

Related

Why is a Order-Product relationship many to many?

In database design, one order can have multiple products, which is no problem. But one product can always be only in one order, isn't it? For example, how can the same iPhone be placed in two different orders?
I think it should be a one to many relationship, instead of many to many. What's wrong with the logic?
Say you are an e-commerce company and have 70000 IPhones in stock.
According to the design you are suggesting, in your "Product" DB table you would store 70000 rows (1 row for each IPhone). This way each "Order" will reference a unique IPhone. Do you see how quickly your db would have a data explosion.
What you should do instead is store the general characteristics of an IPhone (name, price, brand etc) in 1 row of the table and to keep track of the inventory count using a column called "inventory"
Something like this below (Note you can improve this design below further but this will be sufficient to understand the many-to-many logic here)
Product
-------------
id | name | brand | price | inventory
1 | IPhone | Apple | 600 | 70000
Now for every order that has an IPhone in it, the order will reference the same row of the product table. Hence 1 product will be in multiple orders.
Let me know if you need any more clarification. Cheers!
the answer is that one order can have many products and also one product can belongs to many orders
as an example:
you can order many books from an E-commerce website and any book can be ordered many times
Product-Order many to many relationship means that in one order u can order many products e.g. you can buy many products at once and seller will give you one receipt (one order). And the opposite site is one product type can be sealed many times e.g. store ordered (import) iPhone and sealed it. It turns out that the same product has many orders.
For more information have look at Many-to-many (data model) in Wikipedia.
Hope i helped you!

ER Diagram that implements Actors Database [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
Note: This is a rough copy i didnt include constraints, weak entities, ..., etc yet. I still need to have a solid understanding of this question.
Questions:
To keep track of what theater company manages performer, what performer is in two theatre companies do i have to make a unique code for each entity set in other entity sets to keep track of them?
Can start_Location simply point to Place for the theatre company entity?
Can an Actor be Born in a place or does it have to have a attribute that points to place?
Do my relationships so far make sense?
Are there any redundant attributes such as Short_Descript in Plays?
Can i make an attribute in Place called "Town, State/Department/Province"? Or does it have to be a composed attribute?
Please note: I will be editing and updating my diagram if I have more questions and such...
I would appreciate any suggestions or hints.
ERD:
Question Information:
An actor is born in a place and he/she lives presently in a place (this information is mandatory).
We store in the database only the last known place where the actor lives.
We need the following information for an actor: actor number, actor name , date when actor was born, and date when actor died (check if died > born).
An actor is a performer, or/and a theater director.
We store for performer the date when he/she started to perform.
We store for theater director the date when starts his/her last employment as theater director
We consider in DBActors the following types of plays: drama, comedy and tragedy.
For each we like to store the following data: play’s number , play’s title , play’s short description , year when it was written ,date when it was first presented on stage(p_date_p, date).
For dramas we store also the drama type,name of the main positive character, and name of main negative character.
The drama type is one of the following:
“classical”, “medieval”, “renaissance”, “nineteenth-century”, “modern”, and
“contemporary”
For comedies we store the comedy type, the name of main
character , and the name of the second character
The comedy type is one of the following: “ancient mroman”, “ancient greek”, “farce”, “comedy of humors”, “comedy of manners”,
“commedia dell’arte”, and “theater of absurd”;
For tragedies we store the tragedy type(t_type, varchar(20)),and name of main
character
The tragedy type is one of the following: “Greek”, “Roman”, “Renaissance”, “Neo
-classical”, and “Modern”
A play is written by one or many dramatists
It is possible that we do not know the dramatist for certain plays.
We store in the database all known plays even if they were not performed (“closet plays”)
Some actors are also dramatists.
We store in the database all known mdramatists.
An actor is hired by a unique theater company at any timestamp
He/she will stay in the same company the whole year when he/she was hired.
We store in the database the year when he/she was hired by the theater company
(small integer)
It is possible that the actor changes the theater company where he/she is
working during his/her life many times. It is possible that an actor is hired by the same company many times in different years. He/she can perform in
one or many plays (at least one)
which are presented by theater companies.
It is possible that an actor is hired by a theater company and performs in a play presented by another theater company.
It is unusual but possible that the same performer plays in the same play
presented by different theater companies. A theater company performs/presents
one or many plays every year.
Same play can be performed by one or many distinct theater companies.
We like to store in the database the date when the play starts to be performed
by a theater company.
It is possible that the same play is performed by different theater companies starting at same date.
We need to store for a dramatist his/her dramatist number,his/her name.
A dramatist wrote one or many plays(at least one).
The information to be stored in the database for each theater company
is: theater company number,theater company name , date when the
theater company started.
For each theater company we store in the database
the first location (place) where the theater company started
There might be more than one theater company starting in the same place.
A theater company must hire at least one actor.
Each theater company has a unique theater director.
He/she starts his/her work at a specific date.
It is possible that the same theater company has different theater directors but at distinct times and the same theater director manages different
theater companies in distinct times(never at the same date).
It is possible that the same theater director manages the same
theater company at different dates.
The information to be stored for place is: place number, town and state/department/province, place country
Here are my responses to your questions:
Whenever you look at two tables and see a Many to Many relationship, you can solve the problem easily using a linker table. Also known as a junction table “is a database table that contains common fields from two or more other database tables within the same database. It is on the many side of a one-to-many relationship with each of the other tables. Junction tables are known under many names, among them cross-reference table, bridge table, join table, map table, intersection table, linking table, many-to-many resolver, link table, pairing table, transition table, crosswalk, associative entity or association table.” Wikipedia example You saw me use these tables in your previous question. In this case you are stating that an actor can be managed my many Theater Companies and A Theater Company and also manage many Actors. This is a many to many so if you created a link table in between those tables for every relastionship between the two you’d add a new row in the link table that only contains a theater Company id and an actor id. If an actor was managed by many theater companies then you’d add several rows to the link table each holding the same actor id but each row having a different theater company’s id.
Yes, you can have start_Location point directly to place. This means that that Start_Location attribute must be a Foreign Key (FK) pointing the theater company to the Primary Key (PK) of the related Place record.
By all means an actor can be born in a place, but just like above, you need a column in Actor, that is a FK to the Place Table’s PK. You could call this column Birth_Place and all it’d hold is the PK of the record in Place that relates to the actor’s birth place. This column would also need to be NOT NULL because all actor’s need a Birth_Place.
So far it seems like your diagram will work to solve this problem, yes. Just see question 1’s answer for that follow up addition.
You’re getting good at removing redundancies. Your diagram looks good. The only suggestion, I’d make is why do you have a play table and then 3 separate play type tables? Why not add them together in on Table called Play. It’d sit exactly where Play currently sits in your diagram and contain the same attributes it already does, but you also add the following:
a. Type – Would be a string that you could place “Drama”, “Comedy”, or “Tradegy” in so you’d know exactly what type of play it is. Also this would allow you to add future play types to the plays table and not have to add a whole new table to the DB.
b. Sub_Type – Would also be a string and hold the type that you currently have under the separate tables. They are all essentially the same attribute in each table and would just hold different type descriptors depending on the parent Type.
c. Main_Character – Would be a string that holds the main character, because in your three separate tables, you have main characters. You’re just calling them 3 separate things. (get the direction I’m going in here? )
d. Secondary_Character – Would be a string that holds the secondary character. You have a secondary character in your dramas and comedies, but non in your tradegies so in tradegy records this column would wind up being null. See what I did there? You now have one table where you used to have 4, and in that one table you can retrieve all the same information you had in those 4 separate tables. Hopefully that’ll make your life easier.
You can do whatever you like, but I’m assuming you mean by best practices and it would be generally considered best practice to separate this single attribute into it’s Simple attribute sub parts. I.E. make it a composed attribute.

renting a movie entity

Here I have a Movie entity with all the attributes I need. What I am having trouble understanding is what if the DVD store has more than one copy and more than one format of each movie. For example, each copy of these movies is identified with the combination of Movie_ID and item copy number. So what I mean is when a customer rents a Movie Item, he/she actually rents a copy of the Movie - called an item. Example: "Batman" is a Movie...but your DVD copy at home is an Item. So what gets me lost is a customer can rent copies of the same of different Movie Items according to his/her quota. Is this ok what I did ? If not, what is one of the ways to do it ?
Movie item represents the copy of the movie right? the actual disk itself?
Lets rename it for now so i can explain better of course you can rename it to your liking.
Lets call it ProductInformation for now.
so you have a productinformation which in this case is linked to a movie. the ProductInformation needs to have an extra value however it needs to know if its a DVD Blue-Ray or something else.
So we will create another entity called ProductType. this should contain an ID and a TypeName which will contain the values DVD, Blue-Ray or something else.
Create a One to Many relationship between ProductType and ProductInformation.
There, now we have a productInformation with a type and a movie linked to it!
Add CurrentPrice and IsRental columns to this entity remove the price and isrental property from the movie entity.
You should change the relationship between productInformation and Movie as so:
One movie can have many ProductInformation, one ProductInformation can have only one Movie.
Now lets make a Product Entity. The product Entity will represent the actual product (the physical DVD, Blue-Ray or something else).
It will have an ID, maybe a barcode if applicable since it is a store.
Lets create a relationship between the ProductInformation and Product, one product can have one productInformation, one productInformation can have many products.
Now Remove the relationships you've had between your user (rename user to customer) and movie. movie is not physical, the customer will not rent a movie, it will rent a product. movie is nothing more but information about the product.
Now we need to create an entity ProductCustomer or maybe name it Transaction.
This will take care of our many to many relationship between users and products.
Give it an Id, ProductId, CustomerId, Price (Hey we added that at our ProductInformation didnt we?!, Yes we did, but prices change. the transaction will be in the database forever. so for bookkeeping purposes we need to give it a Price aswell, so that we know how much a customer had paid at that time.) move the properties rentaldate and returndate from movie to this entity (productcustomer or transaction), and remove them at movie. aaaand you should have everything fixed, all your worries should be resolved.
Sorry i cant draw a diagram for you, only just got this laptop. :-)
Hope my explanation says as much as a diagram would.
Hop the draft model helps you:

Which is the best way to relate some tables?

I want to make an application where there will be different users and each user will have a set of friends which will be put in categories. There will be some default categories, but the user will be able to add his own. I was wondering which will be the best way to do this.
My idea is to have 3 tables - user, friends and categories.
The user table to have fields (one to many) for friends and categories (but I don't know if the user table will need any information about the friends and the categories at all).
The friends table to have a field for categories (one to many) and a field for the user (many to one).
The category table to have fields for user (many to many?) and friends (many to many?).
I'm not sure about the relations, too. I'm using PHP with MySQL and Symfony2 and Doctrine2. Please help!
EDIT
Maybe I haven't described exactly what I need. When you open the app, you see a login form. If you don't have an account, you should register - the registration creates a new user. This user isn't connected with other users (I'm still new to programming and I want something a little easier so it's something like phonebook). Each user has a list of friends and a firend is a row in a table with fields such as name, addres, phone, email, photo, birthday and so on, but they are added by the current user. The friends are not users. Every user is in fact an account with password and username and when you log in there is just a list of friends. So each user creates categories for himself and he has nothing to do with other users and their categories. The category will have only id and name.
So the idea is that you create an account, then create some categories and add friends to them just to have an organiser when you friends are born or where they live, or which is their phone number, but you create them and add the information about them, they are to users themselves. It's not like a social network. Just a notebook where each user can write info about his friends.
First of all, you need to understand the role of intersection tables: if user A labels user B as a friend (i.e. there is a many-to-many relation from user to itself), and you create a new table to represent that relation (the friends table), any additional information about this "friendship" should be linked to that table. So, if a user categorizes his friends in some way, the category applies to friends, not to user. There's no need for a relation between category and user for this specific purpose.
Update: since friends are not users, the friends table will not be an intersection table (and thus have only one reference back to user, denoting the "owner"), but the rest of the answer still applies.
I'm assuming each category will be a row in the category table. Additional information about the category might be added, but it should be limited to that. For instance, if you want to know which user created a category, you could add a foreign key to user labeled for instance "owner" or "created_by". That might be useful if categories created by one user are not to be seen by others.
Finally, you can relate friends with category. If User A can put user B in at most one category, then a foreign key from friends to category should suffice (i.e. a one to many relation). Otherwise, you might need another many-to-many relation, so an additional intersection table should be created (for instance friend_category).
You could avoid this extra table by employing denormalization, having multiple rows in friends where both users are the same (and in the same order) but the category is different (see also this example). Whether this is advantageous or not is beyond the scope of this answer, but IMHO using an extra table is better for now (it might seem more complicated, but it will be easier to maintain in the long run). (Update: if friends is not an intersection table, denormalizing like this is not really an option, so stick with the friend_category table)
In the end, your layout would look like this:
user friends friend_category category
---- ------- --------------- --------
(user fields) <-- user (owner) <-- friend (category fields)
(friend fields) category --> user (owner) --+
^ |
| |
+--------------------------------------------------------------------+
I can suggest the following table set for this (this scheme applies to the phonebook or social network tasks as well):
Table "Users" that stores all the information about users:
UserId
Name
Phone
Address
... (any other fields)
Table "Categories" that stores information about relationship categories:
CategoryId
Name
Table "Relationships" that stores information about relationships between users:
FirstUserId -> Link to Users table
SecondUserId -> Link to Users table
CategoryId -> Link to Categories table
So, any user is able to add new categories, and then reference them when adding new relationship to another person.
If you need to select all user's friends, you will have to:
select fr.* from Relationships r join Users fr on r.SecondUserId = fr.UserId where r.FirstUserId = <Current user id>

Someone tell me why my database design is stupid, and how I can fix it

So I have these vehicles, many different types of them. Every type has its own table, with many attributes. Then I have a "vehicles" table, which holds the ids and types of all the vehicles in every table. Vehicles can have photos, so I have a "photos" table, with a vehicle_id, linking the photo to the vehicle it belongs to.
Now every vehicle also has a list of equipment it has, which I store as a JSON array in a single "equipment" column.
Something like this: http://pastie.org/353195
How could I do this better, especially with the equipment column?
I would have an equipment table, and then have a join table between the vehicle table and the equipment table with an equipment_id and a vehicle_id.
This gives you the many-to-many relationship between vehicles and equipment.
This will make it much easier to query for, and search for, vehicles which have specific equipment, and your equipment data won't be repeated throughout your JSON packets. You can also make changes to types of equipment without having to update lots of JSON packets.
Storing JSON (or XML) in databases is normally bad, unless there is something inherent about the application such that the data that needs to be extensible.
Your design is quite okay except for the equipment column. I'd recommend having a new table with id and name and then a table linking the vehicle to the equipment it has.
vehicles:
id | type
---------
1 | tank
2 | car
3 | boat
4 | car
equipment:
id | name
---------
1 | radio
2 | abs
vehicles_ equipment:
vehicles_id | equipment_id
2 | 1
2 | 2
your equipment table should look more like your photos table. A vehile_id column and an equipment column. Then your client code can put the equipment into a JSON array (or whatever else is required). You typically should NOT store things in JSON Arrays (or any other format) in your database.
If you take it a step further you can make an equipment table then create a many-to-many relationship between vehicles and equipment.
Why not make equipment a table like the rest? Querying equipments as it is will be hard, you won't be able to do it using SQL alone, will always need some client app to deserialize it.

Resources