Difficulty in database design - mysql

I am experiencing difficulty in MySQL database design.
I have the following tables:
school_table
id | school_name
---------------------------
1 | success primary school
stage_table
id | stage_name
---------------------------
1 | nursery
2 | primary
3 | secondary
school_stage_table
id | school_id | stage_id
---------------------------
1 | 1 | 1
2 | 1 | 2
school_stage_table is a linking table. This is because there is many to many relationship between school and stage, that is a single school may have many stages, and the same stage may have many schools.
The problem comes here:
Each stage has different attributes, and therefore different attribute values for different schools.
How do I model this scenario in a database? Need your help.

As you previously said that you are having some issues that how to store different attributes of each stage of each schools.
Here you can take one table which will store all the attributes of each stage. You can use following table for storing attributes.
Table :
school_stage_attributes_table
id | school_stage_id | attributes_name | attributes_value
------------------------------------------------------------
1 | 1 | attrib_1 | value_1
2 | 1 | attrib_2 | value_2

One option here would be to create a stage_attribute table containing at least the following four columns:
stage_attribute
id | school_id | stage_id | attribute
Each record in this table would correspond to a single attribute for a single stage, e.g.
1 | 1 | 1 | 'nap time'
2 | 1 | 1 | 'breakfast'
3 | 1 | 3 | 'phys ed'
I suspect that some of the difficulty in your mind was with the possibility of adding attribute columns to the stage_table for each attribute. Of course, this is problematical because each stage could have different numbers or types of attributes, and it won't scale for many attributes. The option I gave above eliminates many of these problems by using an arbitrary number of records to store the stage attribute information.

You should use table school_stage_table for this different attribute values for different schools.
If You will use the same attributes schema for multiple schools, then there should be one more table called for example school_stage_options with fields
school_stage_options_id | stage_id | option1 | option2 ....
and later use school_stage_options_id in school_stage_table instead of using stage_id.

Related

Good practice on saving properties in relational database

Let's assume I have two types of users in my system.
Those who can program and those who cannot.
I need to save both types of users in the same table.
The users who can program have lots properties different to those who can't, defined in another table.
What's either advantages of the following solutions and are there any better solutions?
Solution 1
One table containing a column with the correspondig property.
Table `users`:
----------------------------
| id | name | can_program |
----------------------------
| 1 | Karl | 1 |
| 2 | Ally | 0 |
| 3 | Blake | 1 |
----------------------------
Solution 2
Two tables related to each other via primary key and foreign key.
One of the tables containing the users and the other table only containing the id of those who can program.
Table users:
--------------
| id | name |
--------------
| 1 | Karl |
| 2 | Ally |
| 3 | Blake |
--------------
Table can_program:
---------------------
| id | can_program |
---------------------
| 1 | 1 |
| 3 | 1 |
---------------------
You have a 1-1 relationship between a user and the property that allows him to program. I would recommend storing this information as an additional column in table users. Creating an additional table will basically results in an additional storage structure with a 1-1 relationship to the original table.
Why not just have some kind of programmer_profiles table that the users table has a one-to-many relationship with?
If there's an associated record in programmer_profiles then they can program, otherwise it's presumed they can't.
This is more flexible since you can add in other x_profiles tables that provide different properties even if some of these have the same names.

Storing similar products with different attributes

I need to store similar products with different attributes (like length or color), should I add this products with different ids or as one product with many attributes?
Main problem that I need possibility to see quantities of products by attribute (4 red boots, 3 blue etc) and need to implement attribute selector on product page.
If create one id how to store attributes in cart table with selected attributes and how to manage quantities?
If create many ids it is easy to manage quantities but how to implement attributes selection?
I think about some SKU for linking product id with attributes and attribute values. But how to link all together?
If you're building an ecommerce site, this domain concept is generally known as "variant"; see here.
Typically, you have a "products" table containing the major attributes of the item, and a "variants" table, linked back to the product by product ID.
If you're only ever dealing with similar products, you can have the variant table contain columns for all attributes (e.g. size, price, colour); if you have lots of different types of variant (e.g. clothes, shoes, sports equipment), you are at the "inheritance modeling using relational databases"; see this answer.
Tables are there to store any data which you have. If you need any particular information about those entries you have to use different queries. For example assume the following product table:
+----+-------------+-------------+
| ID | ProductNAme | ProductType |
+----+-------------+-------------+
| 1 | Product A | Type A |
+----+-------------+-------------+
| 2 | Product B | Type A |
+----+-------------+-------------+
| 3 | Product C | Type B |
+----+-------------+-------------+
You can get the quantity of Type A Products by writing the following query (view This Link for a better understanding):
Select count(*) as CountOfProduct from Product where ProductType="Type A";
EDIT
You mentioned in your comment that one product could possibly have different types and different quantities. You can do that in one table but that looks messy. If you want this to happen you need two build a 1-Many **relationship** between two tables called product and type.
The type table could be something like this :
| TYPE_ID | TYPE |
|---------|--------|
| 1 | Type A |
| 2 | Type B |
| 3 | Type C |
and your product table could be something like this:
| PRODUCT_ID | PRODUCTNAME | QUANTITY | TYPE_ID |
|------------|-------------|----------|---------|
| 1 | Product A | 3 | 1 |
| 2 | Product B | 2 | 1 |
| 3 | Product C | 1 | 2 |
| 4 | Product C | 5 | 3 |
**take note that type_id is the foreign key which builds the relation between these two tables. And since you can have multiple products with the same type (like product C in this example) this table will be your many table and type table will be your one table. Hence, with putting the foreign key in the many table you will establish the one to many relationship.
Now, in order to combine (or in other words to join) these two tables you will need to write a join query as following:
select ProductName,quantity,Type from Product p
inner join type t on t.type_id=p.type_id
and the result will be what you want:
| PRODUCTNAME | QUANTITY | TYPE |
|-------------|----------|--------|
| Product A | 3 | Type A |
| Product B | 2 | Type A |
| Product C | 1 | Type B |
| Product C | 5 | Type C |
Check this link out for the fiddle

Best way to normalize this data

I have two tables, 'Product' and 'Product Packs'.
One product can appear in many product packs and a product pack can have many products (A many to many relationship).
I have also created a linking table to try and resolve this relationship but I am left with the following conundrum:
-------------------
| Linking table |
-------------------
| Prod_Id | PP_id |
| 1 | 3 |
| 1 | 4 |
| 1 | 5 |
| 1 | 6 |
| 1 | 7 |
| 2 | 5 |
| 2 | 7 |
| 2 | 8 |
| 2 | 10 |
| 2 | 4 |
Is this normal practice for database design? Could this be refined further?
You have a good starting point.
Taking it here you should consider, making the two fields of the table into a composite primay key. That would prevent duplicate records as noted by #musical_coder.
You might also consider adding an integer column that indicates the quantity of products in the package.
Finally, you might want to add some metadata columns such as CreatedWhen, CreatedBy, LastUpdatedWhen, and LastUpdatedBy. These tend to come in handy from time to time.
In my experience I would say that's no problem with this kind of relationship, but you need to be very careful when analysing data, but how you model is logical that a product is in a package and a package contains n products. So that's not bad.
Edit: This is an obsolete answer since the poster fixed his example data to not contain duplicate tuples anymore
From a database normalization perspective, this design is a bit tricky: If having two identical tuples in that table is supposed to have a meaning (e.g., a count), then this table has a multi-set semantics, which does not mix well with the relational model, since you don't have a key.
Having a table (Prod_ID, PP_Id, Count) with primary key (Prod_ID,PP_Id) is be a better (third normal form) design.
Edit:
So your table becomes
create table t (Prod_Id int, PP_Id int, Count int, primary key(Prod_Id,PP_Id));
insert into t values
(1,3,2),
(1,4,1),
(1,5,1),
(1,6,1),
(1,7,1),
(2,5,1),
(2,7,1),
(2,8,1),
(2,10,1),
(2,4,1);
select * from t;
Prod_Id PP_Id Count
---------- ---------- ----------
1 3 2
1 4 1
1 5 1
1 6 1
1 7 1
2 5 1
2 7 1
2 8 1
2 10 1
2 4 1

Best method of organizing database?

MORE DETAILS:
Both of you recomend using JOIN. But the main problem is how to assign multiple SUBJECTS PER EACH CLASS without using multiple duplicate values. I will have ~200 de classes, with ~30 subjects per class. That means if 2 classes share the same 20 subjects, i will have 40 rows, all with "class_id = 1" but with "subjects_Id =1, subjects_id=2, etc" Its not very ergonomic. Any other ideas? Thanks for your time!
So, I am here again asking for your time and help friends.
I have a database that its almost ok. But I am stuck at trying how to link multiple values from a table to on collumn on another.
Let me be more explicit.
I have this table:
CLASSES
id | class_name | Matters |
-----------------------------
1 | Class1 | 13.4.2013 |
2 | Class2 | 14.4.2013 |
And this table:
Subjects
mat_id | show title |
-----------------
1 | English |
2 | French |
Now the problem is this. Each CLASS (e.g. CLASS1) should be able to study more Subjects at once. For example, CLASS 1 should be linked with subject (mat_id) 1, 3, 5, 6.
How to do this without repeating myself, and optimize the database? I tought that I should do it like so, but its not convenient :
CREATE A NEW TABLE named
SUBJECTS_PER_CLASS
id | class_id | mat_id |
----------------------------
1 | 1 | 1 |
2 | 1 | 3 |
BUT then I dont know how to query it. Any ideas? Any help will be greatly appreciated!
THANKS!
SELECT
*
FROM
CLASSES
JOIN
SUBJECTS_PER_CLASS
ON
CLASSES.ID = SUBJECTS_PER_CLASS.class_id
JOIN
Subjects
ON
Subjects.id = SUBJECTS_PER_CLASS.mat_id
You can use join command.
Reference 1
Reference 2

How to store family tree data in a mysql database

I have a family tree. I would like to store it in a mysql database. I have a table with a column called "family members," but i don't know how to arrange these family members. For example, I am under my dad and my son is under me. So i guess, how can i store this type of tree in a database?
So, you said you have a table with a column called "family members". For me, that's just inappropriate because it doesn't respect normalization :) First of all I would call it "familyTreeId". Now, let's move to the FamilyTree table.
This table would be something like this:
FamilyTree(id, motherId, fatherId, etc) --> etc: if you have additional data
id will be the primary key of the table
motherId will link to the row in the FamilyTree table that belongs to the mother
fatherId will link to the row in the FamilyTree table that belongs to the father
So the rows will be:
+--------+--------------+--------------+
| id | motherId | fatherId |
+--------+--------------+--------------+
| son1 | yourwife | you |
| son2 | yourwife | you |
| you | mother | father |
| mother | grandmother1 | grandfather1 |
| father | grandmother2 | grandfather2 |
+--------+--------------+--------------+
Other option would be to store the couples
FamilyTreeParents(id, motherId, fatherId)
FamilyTreeNodes(id, familyTreeParentsId)
id will be the primary keys of the tables
familyTreeParentsId will be a foreign key to a FamilyTreeParents table
motherId will be a foreign key to a row in the FamilyTreeNodes table that belongs to the mother
fatherId will be a foreign key to a row in the FamilyTreeNodes table that belongs to the father
So the rows will be:
FamilyTreeParents
+----+--------------+--------------+
| id | motherId | fatherId |
+----+--------------+--------------+
| 1 | yourwife | you |
| 2 | mother | father |
| 3 | grandmother1 | grandfather1 |
| 4 | grandmother2 | grandfather2 |
+----+--------------+--------------+
FamilyTreeNodes
+--------+---------------------+
| id | familyTreeParentsId |
+--------+---------------------+
| son1 | 1 |
| son2 | 1 |
| you | 2 |
| mother | 3 |
| father | 4 |
+--------+---------------------+
Data is more normalized this way because you are not repeating information (like you and yourwife for son1 and son2 as I did in the other solution. However, this solution might be less efficient in terms of speed because there will be needed more joins.
I would keep two tables, one with persons, other with relations.
Question here is if you should keep the realtion in one record (eg husband - wife) or also from the other person's view (1:husband - wife, 2:wife - husband)
Advantage of second approach is quick searches so fast rendering of eg a layout but also larger table with more writes when data change and possible errors.
I would take the first approach and use some index to make the searches quicker.
So with a minimum of connections you could write out the following family
grandfather louis(id1)
x grandmother clothild(id2)
father francois(id3)
x mother diana(id4)
me peter(id5)
x my first wife fabienne(id6)
my son laurent(id9)
x my second wife jane(id7)
my son tristan(id10)
my brother hans(id8)
as
1x2
3x4
5x6
5x7
1>3
2>3
3>5
4>5
3>8
4>8
6>9
5>9
5>10
7>10
or shorter
1x2>3
3x4>5
3x4>8
5x6>9
5x7>10
So in a databasetable this gives
id_partner1 id_partner2 id_child
1 2 3
3 4 5
3 4 8
5 6 9
5 7 10
You can have schema like this
Family( Parent_name, Child_name ). The "tuple" (Parent_name, Child_name) are the key of your table. Assuming there is no duplicate (Parent_name, Child_name) exist in your family tree. If you have anything like Social Security Number to uniquely identify a person in the family tree, then you should the Parent_ssn, Child_ssn instead of names and have a separate table to store the relation between ssn and name, whose key would be ssn
items in this table can be
[Your dad, you]
[Your mum, you]
[you, your son]
[you, your 2nd son]
[your wife, your son]
Hope this helps
The schema can be this:
id
person
related_person
relation
comments
1
Mac
Mac's Brother
Brother-Brother
2
Mac' mother
Mac
Mother-Son
3
Mac
Mac' mother
Son-Mother
actually same as 2
Support more relationships, even ex-wife and ex-husband.
Also cost-saving, only one row is required between any two people, because their relationship can be reversed.
MARK: It is feasible for a small amount of data.