I'm currently working on a project in which i'm about to make a conceptual model for car retail. My major problem is dealing with 1 to 1 realtionship between Invoice_Line table, which is obviously in N-1 relationship with Invoice table, and a table called Car which is supposed to hold information about specific car with it's unique registration number. As far as i know it wouldnt be a problem if i have made the Car table containing only information about specific type of a car, that is it's model, class, etc. However what i want is the invoice looking like that:
...car_registration_number... ...price... ...date...
...
That would mean making a 1 to 1 realtionship between invoice_line and table with specific car_id's, which i want to avoid at all cost. What are the further possibilities to solve that? Because of distinguishable car's each invoice line would hold only 1 car, which is my way of designing it.
An invoice line appears in one invoice so say so in Invoice_Line:
UNIQUE NOT NULL (invoice, invoice_line_number)
The invoices must all appear in Invoice so say so:
FOREIGN KEY (invoice_number) REFERENCES Invoice (invoice_number)
A car is unique in Invoice_Line so say so:
UNIQUE NOT NULL (car_registration_number)
The cars must all appear in Car so say so:
FOREIGN KEY (car_registration_number) REFERENCES Car (car_registration_number)
There is a 1:1 relationship between invoice lines and invoiced cars. But it is not a problem because that relationship is represented by car + invoice line pairs (car + invoice + invoice line number triplets) in Invoice_Line.
Related
I will going to explain my question using the fragment of a problem in which there are two entities:
🔸 Airplane
🔸 Location
And a relationship to link these entities:
🔸 Send
Logic 1:
An airplane send minimum 1 location and at the most it sends many locations (in different moments), therefore, the cardinality is one to many (1,N).
Airplane ——— (1,N) ——— Send ——— (1,N) ——— Location
Logic 2:
An airplane send minimum 1 location but it CAN’T send many locations at the same time, therefore, the minimum is 1 and also the maximum is 1, so the cardinality is one to one (1,1).
Airplane ——— (1,N) ——— Send ——— (1,1) ——— Location
Not only in the ER, but also in a database. Which of these logics is correct?
Many-to-Many
Your business problem may not be clear, so let's look at the canonical example of books and authors. One book can have multiple authors, and each author can potentially contribute to multiple books. So we have a classic Many-to-Many.
A relational database does not handle a many-to-many relationship directly. To do so we add a third table bridging the original two. Naming this third table can be something of a puzzle as it often represents a not-so-concrete business relationship. In this case authorship is appropriate.
Books & Authors
[book]-1-----0-1-M-[authorship]-M-1-0------1-[author]
Tables:
book
pkey (primary key, the unique identifier of each book)
title
planned_publish_date
authorship
pkey (optional, as some folks use the other two columns in a combined key as the primary key for this table)
fkey_book (holds the primary key value of the book on which this author is contributing)
fkey_author (holds the primary key value of author who is contributing to this book)
author
pkey (primary key, unique identifier of each author)
name
phone_number
The cardinality here is:
A book can have any number of authorship rows related: cardinality of 0, 1, M (M meaning more than one).
A planned book can have zero rows in authorship because it is not yet associated with any author. Later, when an author is recruited, we add a row to authorship.
A book with a solo author has one authorship row, linking to the one author.
A book with a pair of authors will have two authorship rows, each with a foreign key linking to the author row.
Ditto for the author-authorship relationship: cardinality of 0, 1, M.
An author who has been recruited but not yet committed to any book will have a row in author table but no rows in authorship.
An author who has worked on only a single book will have one row in authorship.
An prolific author will have many rows in authorship, one row for each book on which he/she has contributed.
An authorship row must be assigned to a book AND assigned to an author: cardinality of 1 with book, and 1 with author.
We do not allow any authorship rows to be “orphaned”, to use the parent-child language some folks like me use in describing table relationships. In other words, on every authorship row, the pkey_book field must have a valid value, and the pkey_author field must have a valid value.
Time
Adding the dimension of time is something of a tricky problem.
One example… To track the period of time when each author's contract for a book starts and stops, we would add pair of DATE columns on the authorship table, titled contract_start & contract_stop.
authorship
pkey (primary key for this table)
fkey_book (holds the primary key value of the book on which this author is contributing)
fkey_author (holds the primary key value of author who is contributing to this book)
contract_start (of type DATE)
contract_stop
A query for contracts currently in effect would compare today’s date as being greater-than-or-equal to contract_start AND less-than contract_stop. Then do a join to get title of book and name of author.
Another example… If our publishing company has a business policy that an author must focus on a single book at a time, and wants the database to enforce that an author's contract cannot overlap… well, that is another problem. I'll not address it for a few reasons, one of which is I do not know if your Question has this issue or not.
Plane-Flight-Location
As for your airplane problem, I am guessing that by Send you mean a flight. If so, I would name the table flight for clarity. By location, I suppose you mean airport. Again, I would name the table airport for clarity.
If this is what you meant, then you have the very same cardinality as discussed above.
A plane joining the fleet may have never flown yet, has flown once, or has flown to many locations. So, 0-1-M.
An airport may become known to our system before we have flown any planes there, so zero flight rows. Later, one or more flight rows as we schedule one or more planes to that airport. So, 0-1-M.
The flight table has columns for date-time of departure and for duration.
flight
pkey (primary key for this table)
fkey_plane (holds the primary key value of the plane to be flown to this airport at this date-time)
fkey_airport (holds the primary key value of the airport to which this plane is departing at this date-time.)
departure (when this flight takes off, of type TIMESTAMP WITH TIME ZONE)
duration (the length of this flight, a number of minutes).
[plane]-1-----0-1-M-[flight]-M-1-0------1-[airport]
Your business rules may vary. If you plan a flight but have not yet assigned an airplane, then we can have a flight row without an assigned airplane. So the cardinality of 1 changes to 0 or 1. But not M, as one particular flight never involves multiple planes. In the case of this business rule, a flight row can be orphaned, lacking a plane parent until eventually when a particular plane is assigned.
[plane]-1-0-----0-1-M-[flight]-M-1-0------1-[airport]
Suppose I have a table for purchase orders. One customer might buy many products. I need to store all these products and their relevant prices in a single record, such as an invoice format.
If you can change the db design, Prefer to create another table called PO_products that has the PO_Id as the foreign key from the PurchaseOrder table. This would be more flexible and the right design for your requirement.
If for some reason, you are hard pressed to store in a single cell (which I re-iterate is not a good design), you can make use of XMLType and store all of the products information as XML.
Note: Besides being bad design, there is a significant performance cost of storing the data as XML.
This is a typical example of an n-n relationship between customer and products.
Lets say 1 customer can have from 0 to N products and 1 products can be bought by 0 to N customers. You want to use a junction table to store every purchase orders.
This junction table may contain the id of the purchase, the id of the customer and the id of the product.
https://en.wikipedia.org/wiki/Many-to-many_(data_model)
I want you to know your opnion about this situation:
I have a table named "movie" with this colums
movie_id
name
price
...... etc
A movie can be available to rent, purchased or both.
If I want a movie available to rent and purchase the price change, for example:
Price for rent: $2.50
Price for purchase: $15.45
The question is:
Is better to make a duplicate in the table movie?
movie_id name price available_for ...... ........
1 300 $2.50 rent
2 300 $15.45 purchase
Or make another table adding the info of price and available_for? Like this:
Table Movie
movie_id name ...... .......... ..........
1 300
2 300
Table Movie_available_for
Id movie_id available_for price
1 1 rent $2.50
2 1 purchase $15.45
I want to know which is the best solution for this
Thanks!
Your relational approach might depend on what level of normalization you hope to achieve. Your question reminds me a lot of the Boyce–Codd normal form (BCNF) vs the 3rd normal form (3NF).
In fact, there is an example similar to your question on this wiki page: Boyce–Codd normal form (Wikipedia)
There is a lot of theory here, but it can many times come down to either what you feel the most comfortable with or whichever technique you can perform the most accurately.
Personally, in this specific case, I would go with the slightly more normalized form (your 2nd example). This is because, the "available_for" and "price" are related variables. If you end up adding more info about movies, that info is potentially going to be duplicated many times. If you add a third "availible_for" or different pricing schemes (1 day for $1.50, 5 days for $4), you will have very significant data duplication.
Besides, when it comes to code, it would be nice to have a movie object that has an array of nested "availible_for" (might name this something else like "offering" or something) objects.
I would suggest you normalize your available_for column as it is repeated and contains few fields only.Store that in another table and create a relation between two tables.
Movie_Available_type
id int, available_for varchar(50)
Then you can use either of two as pointed out by thoughtarray in above post.
I would go with:
Movie (movie_id PK, name, purchase_price, rent_price)
and make the pricing columns nullable. If you don't like nulls, you can decompose it into:
Movie (movie_id PK, name)
PurchasePrice (movie_id PK/FK, price)
RentPrice (movie_id PK/FK, price)
I understand the N:M, 1:N and N:1 relationships.
Let's suppose we have a travel agency and look at the relation "booking a travel". The entities involved in this relation are customers, employees and the destination. Rules are as follows: one customer can book several travels and a destination can be booked by several customers. Apparently, this relationship is N:M:K.
How do you have to read N:M:K? Is it like 1 customer can book M destinations with N different employees? But you also can't book one same travel with more than one employee, so how do I have to rephrase it, if needed, in several sentences?
Thanks in advance
If I understand you correctly:
The "base entities" are customers, employees and destinations.
Now consider a single booking. It is booked by one and only one customer. It has one and only one destination. It also can be booked with one and only one employee.
Thus there will be 4 tables in the database. The bookings table is, using pseudo syntax:
BookingId (PK),
CustomerId (FK of [customers]),
EmployeesId (FK of [employees]),
DestinationId (FK of [destinations])
Now,
SELECT * FROM bookings WHERE CustomerId = xxx
will give you the different bookings to various destinations by the same customer, and each booking is made by only one employee. Similarly to bookings by the same employee or to the same destination as well.
Can anyone help me in constructing a good erd structure for determining health risks.
Say i have both recipe and ingredients table which have id as pk's and fk's on a 3rd table which i use for displaying.
How would i construct tables for the ingredients that would determine their nutritions.
Ingredient(table) -> Nutrition(table)
for comparing, lets say i am a user with diabetes so i am not allowed to eat dishes with too much sugar. I would then need to get all the ingredients of that dish and get the ones with sugar content and calculate how much sugar is there in total and determine if its okay or not.
Regarding of my approach, how would i construct the tables for nutrition. say It has the id of ingredients as its FK.
should i use the id as fk? or the name. and on my ingredient table, make the column of name as unique. Since id is auto increment so if someone inserts another recipe with egg and there is already a recipe with egg. it would create 2 rows of eggs in my ingredients table connected to two different recipes. So ingredient name would be best right?
Nutrition
ingredient id(fk) or ingredient name(fk)
nutrition(string)