Put a table into another table with repeated primary keys - database

Turns out I have these three tables:
Recipes: id(primary key), name, time, difficulty, description, photo_url, amount_pax
Recipe_type: id(primary key), name
Ingredients: id(primary key), name
In my exercise the three tables have to be yes or yes.
I need to put the type of recipe and the ingredients in the recipe table but I don't know how to do it because I could put the id_type_recipe and the id_ingredients as a foreign key but the problem is that in several recipes said id can be repeated because if tomato has the id 1 in another recipe there may be tomato and this is not feasible because they are primary keys in another table that cannot be repeated... how could I put the type of recipe and ingredients in the recipe table?
I attach my E-R diagram.
I started by entering the ingredient id and the recipe type id but I realized that they were going to be repeated and this is not possible as they are primary keys in other tables.

To handle Recipe_Type you can add Recipe_TypeId as an additional column to the Recipes table.
But for Ingredients, expecting each Recipe may need several Ingredients (of different quantities) you will need an additional table.
Let's say you have a Recipes for Tomato Soup and Chicken Noodle Soup with Recipes records like this:
ID
Name
Time
Difficulty
Description
Photo_url
amount_pax
Recipe_Type_ID
1
Tomato Soup
3:00
1
Take tomatos...
http://...
2
1
2
Chicken Noodle Soup
20:00
2
Cook Chic...
http://...
4
1
and a Recipe_type like this:
ID
Name
1
Soup
And Ingredients like this:
ID
Name
1
Tomatoes
2
Milk
3
Salt
4
Chicken
5
Water
6
Noodles
Now you also need an intersection table (named, say RecipeIngredient) that would look something like this:
RecipeID
IngredientID
Qty
Measure
1
1
8
Each
1
2
1.5
Cups
1
3
1
Tsp
1
5
1.5
Cups
2
3
1
Tsp
2
4
2
Lbs
2
5
4
Cups
2
6
1
Lbs
This new table will have a compound key like this: (RecipeID, IngredientID)

Related

How to update in master-detail tables

Example:
Master
ID
Student
1
Cindy
2
Barbie
Detail
ID
ID_FK
Subject
1
1
Math
2
1
Science
3
1
English
4
2
English
5
2
History
Scenario: if i update Barbie to have three subjects, Math, science and english, should i delete all her records first then add the new ones or is there any other way to do this. Thanks.

dish customization in food ordering

I wanted to make sure the design for a particular part is correct or not.
The scenario is:
A pizza can be customized by its size, toppings, crust etc. but the prize of toppings will depend on the size; like when size 7" is selected the prize for each topping will be $1 and for size 14" the prize will be $2 (or some other customization can be dependent on some other one).
One of the customization can be available only for a particular size; like when size 7" is selected then only another customization will be displayed.
(This scenario is just an example and there are many more things other than pizza which will have customization as it is a food ordering app )
Currently for this problem I've designed 3 tables:
Dishes(d_id,name,desc,base_price)
Customization(c_id,d_id(foreign key,name)
options(o_id,c_id(foreign key),parent_id,name,price)
The customization table will hold the name of customization like size, crust, toppings etc.
And the options table will hold the contents of each customization.
The parent_id in options will refer the options table because toppings price will be dependent on the size selected options.
eg:
1) dishes
id name
1 pizza
2) customization
c_id d_id name
1 1 size
2 1 toppings
3) options
o_id c_id parent_id name price
1 1 1 7" 5$
2 1 2 14" 10$
3 2 1 abc 1$
4 2 2 abc 2$
Is there any better way of representing this in the db.
Please guys revert back as soon as possible and please suggest any other changes or functionality I should include in the design(other than this part too).
It will be great if any helpful links are provided.
Thank you.
Is parent_id in options table is the foreign key of d_id in dishes table?

At which Step of normalization i should include the new Primary Key Column

I have a table with the following data.
I need to Normalize them as per Normalization Rules, but I am confused, on which step of normalization I should introduce CustomerId as new PrimaryKey column.
CustomerName Address ObjectRented objectCatetory
-------------------------------------------------------
Mr A Street 1 Obj1,Obj2 Cat1,Cat1
Mr B Street 2 Obj3,Obj4 Cat2,Cat2
MR B Street 3 Obj2 Cat1
In this particular example, you can introduce primary key column even before doing normalization. Your table could just look denormalized like this after adding primary key (simplified structure):
CustomerID CustomerName Address ObjectRented
---------- ------------- ------- ------------
1 Mr A Street 1 Obj1,Obj2
2 Mr B Street 2 Obj3,Obj4
2 Mr B Street 3 Obj2
I am writing this rather quickly, so please do read up on other answers and blogs about normal forms as well.
1NF - Remove repeating group
CustomerID CustomerName Address ObjectRented
---------- ------------- ------- ------------
1 Mr A Street 1 Obj1
1 Mr A Street 1 Obj2
2 Mr B Street 2 Obj3
2 Mr B Street 2 Obj4
2 Mr B Street 3 Obj2
2NF - Remove partial dependency
CustomerID is actually a customer and lives at a particular location. Keep them in a single table. Customer can rent whatever they like...keep whatever they rented in a different table like this:
Customers
CustomerID CustomerName Address
---------- ------------- -------
1 Mr A Street 1
2 Mr B Street 2
2 Mr B Street 3
ObjectRental
CustomerID ObjectRented
---------- ------------
1 Obj1
1 Obj2
2 Obj3
2 Obj4
2 Obj2
During this stage, you can also move Objects into its own table
Objects
ObjectID ObjectName
-------- ----------
1 Obj1
2 Obj2
3 Obj3
4 Obj4
ObjectRental becomes
CustomerID ObjectRentedID
---------- ------------
1 1
1 2
2 3
2 4
2 2
At this point I believe you have automatically gained 3NF. In 3NF, you'd want to make sure that - loosely speaking - none of your child table's primary key associates with a non-primary key in parent table.
Normalization doesn't require you to introduce surrogate keys. It's not about eliminating duplicate values either. The purpose of normalization is to avoid recording the same fact more than once, since multiple instances of the same fact could be updated inconsistently and cause anomalies.
The 1st normal form is slightly different from the rest, since its purpose is to ensure that your data is in a regular arrangement of scalar values so that normalization can be applied systematically. For the 1st normal form, you need to ensure that every field of every row contains a single value. "Obj1,Obj2" looks like multiple values, so you might want to start there. Then, write out your functional dependencies before proceeding to the higher normal forms.

How do I normalize data in a database?

I'm in an intro to database management course and we're learning about normalizing data (1NF, 2NF, 3NF, etc.) and I'm super confused on how to actually go about and do it. I've read up on this, consulted various sites and youtube videos and I still can't seem to get it to click. I am using Microsoft Access 2013 if that's of any help.
This is the data I'm working with.
Thanks.
Edit1: Alright, I think I have the tables set up correctly. But now I'm having trouble actually inputting data to go from one table to the next. Here's my relationship table.
On a very basic level, any repeating values in a table are candidates for normalization. Duplicated data is usually a bad idea. Say you needed to update a patient's surname - you now have to update all the occurrences in this table, and possibly many others throughout the rest of the database. Much better to store each patient's details in one place only.
This is where normalization comes in. Looking down the columns, you can see that there are repeating values for data about dentists, patients and surgeries, so we should normalize towards having tables for each of these entities, as well as the original table that contains appointments, giving you four tables in total.
Extract the entities out into their own tables, and give each row a primary (unique) key - just use an incrementing integer for now. (Edit: as suggested in the comment we could use the natural keys of PatientNo, StaffNo and SurgeryNo instead of creating surrogates.)
Then, instead of each patient's name and number appearing multiple times in the appointments table, we just reference the key of the master record in the Patient table. This is called a foreign key.
Then, do the same for Dentist and Surgery.
You will end up with tables looking something like this:
APPOINTMENT
AppointmentID DentistID PatientID AppointmentTime SurgeryID
----------------------------------------------------------------
1 1 1 12 Aug 03 10:00 1
2 1 2 ... 2
3 2 3 ... 1
4 2 3 ... 1
5 3 2 ... 2
6 3 4 ... 3
DENTIST
DentistID Name StaffNo
--------------------------------------
1 Tony Smith S1011
2 Helen Pearson S1024
3 Robin Plevin S1032
PATIENT
PatientID Name PatientNo
---------------------------------------
1 Gillian White P100
2 Jill Bell P105
3 Ian MackKay P108
4 John Walker P110
SURGERY
SurgeryID SurgeryNo
-------------------------
1 S10
2 S15
3 S13
The first step is to data modelling and denormalization is to understand your data. Study it an understand the domain "objects" or tables that exist within your model. That will give you an idea of how to start. Sometimes a single table or query sample is not enough to fully understand the database, but in your case, we can use the sample data and make some assumptions.
Secondly, look for repeated / redundant data. If you see copies of names, there is a good chance that is a candidate for a foreign key. Our assumption tells us that STAFF_NO is a primary key candidate for DENTIST because each unique STAFF_NO correlates to a unique DENTIST_NAME, so I see a good candidate DENTIST table (STAFF_NO, DENTIST_NAME)
Example in some table of SURGERY:
ID STAFF_NO DENTIST_NAME
1 1 Fred Sanford
2 1 Fred Sanford
3 3 Lamont Sanford
4 3 Lamont Sanford
Why store these over and over? What happens when Fred says "But my correct name is Fred G Sanford", so you have to update your database. In the current table, you have to update the name is many rows. If you had normalized it, you'd have a single location for the name, in the DENTIST table.
So I can take the unique dentists and store them in DENTIST
create table DENTIST(staff_no integer primary key, dentist_name varchar(100));
-- One possible way to populate our dentist table is to use a distinct query from surgery
insert into DENTIST
select distinct staff_no, dentist_name from surgery;
STAFF_NO DENTIST_NAME
1 Fred Sanford
3 Lamont Sanford
SURGERY table now points to DENTIST table
ID STAFF_NO
1 1
2 1
3 3
4 3
And you can now create a view, VIEW_SURGERY to join the DENTIST_NAME back in to satisfy the needs of typical queries.
select s.id, d.staff_no, d.dentist_name
from surgery s join dentist d
on s.staff_no = d.staff_no -- join here
So now a unique update to DENTIST, by the dentist primary key will update a single row.
update dentist set name = 'Fred G Sanford' where staff_no = 1;
Add query view will show the updated name for N rows:
select * from view_surgery
ID STAFF_NO DENTIST_NAME
1 1 Fred G Sanford
2 1 Fred G Sanford
3 3 Lamont Sanford
4 3 Lamont Sanford
In short, you are removing redundancy.
This is just a sample, and one way to do it. Manual normalization like this is not as common when you have modelling tools, but the point is, we can look at data, spot redundancies and factor those redundancies into new tables, and relate those new tables by foreign keys and joins, then build views to represent the original data.

What is the best database structure for a rental system?

I have done rental systems for boats and reservation for rooms and tours apart.
But how could I build up a database which I could use for multiple type of items? It means the items can be rooms, trips, journeys, cars, boats, etc...
Thanks!
Use a table for your items with a reference to an ItemType table:
Item
ItemId ItemType HireDate Hirer
1 2 1 Jan 200
2 3 3 Jan 201
3 6 4 Jan 207
ItemType
ItemTypeID Desc
2 Boat
3 Car
4 Bike
In our rental system I can share the sort of table that we use.
You will need a reservation orders table, and a inventory index that gets updated after each order. Or else you will have terribly slow inventory lookups.
Reservation Orders:
ProductID StartDate EndDate Quantity
Then everytime an order is placed or you manually add or remove inventory, update the inventory index:
Inventory Index:
ProductID Date InventoryAvailable
You will have an entry for each date in your Inventory Index so it will get pretty large, but else there is no fast way to check inventory.
We use this in our rental system here: rental booking software example
I can share other tables we use if that will help, let me know.

Resources