I have two tables. 'Products' and 'Discounts'.
Then I create a joining table 'discount_product' for Many-to-many relationship. So far so good.
Now if I want a discount to belong to ALL of the products I have to make insertions into the joining table for as many products I have. That means that having 10000+ products I'll have to insert 10000+ rows for one discount into the joining table? And that's only for one discount! What if I have 1000?
That's compelling me into returning to the old (wrong) way of doing it when I just have a column 'product_ids' in the 'Discounts' table with something like this '1|2|4|7|23|...' (or '*' for 'belongs to all') and then make a small piece of PHP code to check if discount belongs to all or to some products. I know it's wrong way of doing it. So is there a better way to make this properly?
Structure:
**products**
id
description
price
**discounts**
id
procent
value
**discount_product**
product_id
discount_id
I propose to try to change some business logic.
If the discount is not in the discount_product then this means that it applies to all products.
If the discount is in the discount_product then it means that it works only for a certain product.
If you need to ensure that the discount is not applied to any product, add the field is_active in discounts.
It's just my thoughts.
I believe that sometimes it is useful to denormalize the database because of optimization, and I would do as you suggested with the product_ids field.
The following problem comes from: https://cs.senecac.on.ca/~dbs201/pages/Normalization_Practice.htm (Exercise 3)
The unnormalized table appears like this:
To comply with First Normal Form, all repeating groups must be dealt with. In this case, multiple products could appear on a single order, so it must be given its own entity and related back to the original table:
These tables are also in Second Normal Form, because in all of the tables, each non-key attribute is dependent on the primary key in it's table.
Finally, to bring it to Third Normal Form, Customer must be given its own entity and related back to the original Order entity:
Have I properly normalized the original table into Third Normal Form? If not, please provide feedback explaining what I've done wrong.
Store some Customer's Primary details in Order Table which are available on Bill, because once customer details is changed then Bill is differ then original.
Same for Product, Store Product price in Product_Order table, because once Product price changed Bill will change.
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 was simply wondering, how an ISA relationship in an ER diagram would translate into tables in a database.
Would there be 3 tables? One for person, one for student, and one for Teacher?
Or would there be 2 tables? One for student, and one for teacher, with each entity having the attributes of person + their own?
Or would there be one table with all 4 attributes and some of the squares in the table being null depending on whether it was a student or teacher in the row?
NOTE: I forgot to add this, but there is full coverage for the ISA relationship, so a person must be either a studen or a teacher.
Assuming the relationship is mandatory (as you said, a person has to be a student or a teacher) and disjoint (a person is either a student or a teacher, but not both), the best solution is with 2 tables, one for students and one for teachers.
If the participation is instead optional (which is not your case, but let's put it for completeness), then the 3 tables option is the way to go, with a Person(PersonID, Name) table and then the two other tables which will reference the Person table, e.g.
Student(PersonID, GPA), with PersonID being PK and FK referencing Person(PersonID).
The 1 table option is probably not the best way here, and it will produce several records with null values (if a person is a student, the teacher-only attributes will be null and vice-versa).
If the disjointness is different, then it's a different story.
there are 4 options you can use to map this into an ER,
option 1
Person(SIN,Name)
Student(SIN,GPA)
Teacher(SIN,Salary)
option 2 Since this is a covering relationship, option 2 is not a good match.
Student(SIN,Name,GPA)
Teacher(SIN,Name,Salary)
option 3
Person(SIN,Name,GPA,Salary,Person_Type)
person type can be student/teacher
option 4
Person(SIN,Name,GPA,Salary,Student,Teacher) Student and Teacher are bool type fields, it can be yes or no,a good option for overlapping
Since the sub classes don't have much attributes, option 3 and option 4 are better to map this into an ER
This answer could have been a comment but I am putting it up here for the visibility.
I would like to address a few things that the chosen answer failed to address - and maybe elaborate a little on the consequences of the "two table" design.
The design of your database depends on the scope of your application and the type of relations and queries you want to perform. For example, if you have two types of users (student and teacher) and you have a lot of general relations that all users can part take, regardless of their type, then the two table design may end up with a lot of "duplicated" relations (like users can subscribe to different newsletters, instead of having one M2M relationship table between "users" and newsletters, you'll need two separate tables to represent that relation). This issue worsens if you have three different types of users instead of two, or if you have an extra layer of IsA in your hierarchy (part-time vs full-time students).
Another issue to consider - the types of constraints you want to implement. If your users have emails and you want to maintain a user-wide unique constraint on emails, then the implementation is trickier for a two-table design - you'll need to add an extra table for every unique constraint.
Another issue to consider is just duplications, generally. If you want to add a new common field to users, you'll need to do it multiple times. If you have unique constraints on that common field, you'll need a new table for that unique constraint too.
All of this is not to say that the two table design isn't the right solution. Depending on the type of relations, queries and features you are building, you may want to pick one design over the other, like is the case for most design decisions.
It depends entirely on the nature of the relationships.
IF the relationship between a Person and a Student is 1 to N (one to many), then the correct way would be to create a foreign key relationship, where the Student has a foreign key back to the Person's ID Primary Key Column. Same thing for the Person to Teacher relationship.
However, if the relationship is M to N (many to many), then you would want to create a separate table containing those relationships.
Assuming your ERD uses 1 to N relationships, your table structure ought to look something like this:
CREATE TABLE Person
(
sin bigint,
name text,
PRIMARY KEY (sin)
);
CREATE TABLE Student
(
GPA float,
fk_sin bigint,
FOREIGN KEY (fk_sin) REFERENCES Person(sin)
);
and follow the same example for the Teacher table. This approach will get you to 3rd Normal Form most of the time.
I have a 3-table schema. Two of the tables (Trade/Portfolio) have a 1:1 relationship, so the FK on one of these tables has the unique constraint.
The table, as explained above, with the FK (which is Portfolio) relates to a third table. As this third table (Price) is displaying historical information for a Portfolio (there can be many prices for a portfolio over a time-period), there's a bog-standard 1:m relationship.
However, I need to get the various prices for a portfolio. That's easy with a query which works on the portfolio ID. However, is this a feasible way to get the price of a single trade? Is there any limitation in the design that would prevent this?
Apologies for the long title, but could not find a better way to explain the issue!
Thanks
By your description I guess this is your data model. FK TradeID is a unique in Portfolio.
And you wonder if it is possible to get the rows from Price related to Trade.
Here is a query that will give you all rows from Price where TradeID is 1.
select Price.*
from Portfolio
inner join Price
on Portfolio.PortfolioID = Price.PortfolioID
where Portfolio.TradeID = 1
I see nothing in this design that will prevent you from fetching the rows from Price given a TradeID.