Mysql, list of values in a column - mysql

I have a table that stores information about categories ('cats' let's say) and another table (say 'cars' meaning it stores infos about cars - a lame example, but that doesn't matter) that has a column called 'parent_cat_id' which should reference 'id' col in 'cats'.
Now comes the problem: any car from 'cars' could belong to more then one category.
There's an obvious, but very lame, solution: store in parent_cat_id a delimited list of numbers, but, if i apply that, I couldn't have any foreign key constraint and should jump into parsing these values. Although parsing isn't such a big deal, but I can't believe MySQL doesn't have anything pre-built.
Also it looks like selecting cars by category will involve some substring and other things.
Having no foreign key is a far bigger problem.
The only thing I was able to find is a 'SET' type, but it should be pre-defined what values it can store during database development, also it can have only 64 pre-defined values while there could be 100s of categories.

The normal way of modeling this kind of many-to-many relationship is to introduce a third table (a junction table) that holds information about relationships between items in the two other tables.
In your example you would have three tables:
Category
Cars
CarCategory which has foreign keys to both the primary keys in Category and Cars
This is pretty fundamental relational modeling and you might want to look at a nice tutorial or book to get further knowledge about the concepts.
Just as you recognize storing delimited lists of keys is a bad idea as it breaks the model.

Related

Can a many to one relationship be represented in a logical ER diagram?

I have a particular problem from my assignment which goes like this :
"Each product making up a set is supplied by a single supplier and is given a unique ID,. Products are always sold as part of a set, never on their own."
So based on this is assumed Many Products creates One Package(aka set), but i don't know if i'm right, if so how can I visually show a Many to One relationship as an ER diagram.
I have constructed my own Conceptual and Logical ER diagram, I just need to know if i'm right or wrong so that i can continue with the rest.
Here's a breakdown of the assignment and what I get from it:
Each product making up a set is supplied by a single supplier and is given a unique ID,. Products are always sold as part of a set, never on their own.
From this I get that we have these entities:
Product
Supplier
Package (Set)
You should know that each Entity needs its own primary key. Pros will either call this id, or product_id. There are ORM's that tend to work best out of the box, if you name the pk for each table 'id', especially when it is a simple sequence number.
It's also better not to do what you are doing with attribute names. In sql people stick with either all uppercase or all lowercase naming rather than camelcase. Also I'd suggest that you don't name the price attribute pPrice just because it's in the Package table. Just name it price, because it can be referred to as Package.price if you need to tell it apart from some other table that also contains a price column.
The important thing to understand is that the relationship between Package and Product is Many to Many
One Product can be part of Many Packages.
One Package can contain Many Products
In order to create entities for a Many to Many relationship, you need a table that sits between the 2 tables and will have foreign keys to both tables in it. Typically people will pick whatever they consider the dominant side -- I would probably use Package, and name the table "PackageProduct" to reinforce the idea that this table lets me package products together and sell or distribute them.
PackageProduct
--------------
id (pk)
package_id (foreign key to Package table)
product_id (foreign key to Product table)
You also need a supplier table, but you were informed that the relationship between Package and supplier is that a Package can have one and only one Supplier.
This is code for: create a one to many relationship between Supplier and Package. In doing this, Package will have a foreign key in it that stores the Supplier.id (or supplier_id)
So to conclude you should have these entities (tables):
Package
Product
Supplier
PackageProduct
ERD
Here's an ERD rendered with "Relational" format which I find a bit more descriptive, as the many sides of the connections use the crowsfoot, so it's very obvious.
According to your description your schema will have one to many relation i.e your single package comprises many products.
You can also find out your ERD diagram

database design two tables vs join table, which is better

I have two tables matches and tournaments with below structure,
MATCH
MATCH_ID
PLAYER_ID_1
PLAYER_ID_2
RESULT
TOURNAMENT_ID
and
TOURNAMENT
TOURNAMENT_ID
NAME
OTHER_DETAILS
with one tournament will have multiple matches
and a match may or may not have tournament id
use Cases:
retrieve all matches
retrieve all matches by tournaments
Is it good to have tournament id in match table? Or should I create a separate joining table for tournament and match mapping? Which will have good performance when the volume increases?
TOURNAMENT_ID has a 1:M relationship to MATCH. It seems to be a straightforward foreign key. The standard way of implementing foreign keys - even optional foreign keys - is a column on the child table with a foreign key constraint. This would support both your use cases.
A separate table would normally be a head scratcher. I say "normally" because there are schools of thought which abominate NULL columns in databases; either for practical reasons - NULLs can do weird things to our code and need wrangling - and academic reasons - NULL is contrary to Relational Algebra. So, if you have a data model which forbids the use of nulls you will need a TOURNAMENT_MATCH table to hold Matches which are part of a Tournament. It also would be likely to perform slightly worse than a foreign key column on MATCH, but unless you have a vast amount of data you won't notice the difference.
There is a use case for join tables (also known as junction or intersection tables) and that is implementing many-to-many relationships. Suppose we add a third table to the mix, PLAYER. A Player can participate in many Tournaments and a Tournament has many Players. Classic M:N relationship. So we can resolve it with a join table REGISTERED_PLAYER. which as a compound key of (TOURNAMENT_ID,PLAYER_ID) and the appropriate foreign keys to TOURNAMENT and PLAYER.
For the sake of completeness I will mention Link tables from Data Vault modelling. This is an interesting modelling technique for Data Warehouses, where - gross simplification alert - tables are defined as Hubs (business and technical keys) and Satellites (immutable attribute records). This approach allows for the capture of data changes over time. Foreign key relationships between Hubs are implemented through Link tables, to support changing relationships over time.
There are several benefits to Data Vault for wrangling large amounts of data in a time-sensitive fashion but an easy-to-understand physical data model isn't one of them. Anyway, find out more.
The simple rule: for one-to-many mapping always prefer a foreign key association to a join table association.
It is hard to control a join table using a standard #OneToMany Hibernate mapping — you can't just delete rows from a join table, or add an additional row. You will need to use list on the Tournament side to do things like that. Another option is to use an additional entity for a join table.
Note: Match can has a tournaments list too, but looks like Tournament is the owner of the association.
A few opinions have been offered in other answers, here is mine.
You do NOT want a separate join table, you would only need that if a Match can be in multiple Tournaments. In your example, just use a foreign key.
The only other suggestion is that if the Match is not part of a Tournament then it is not actually "unknown" which is the meaning of NULL, it is actually something else like "Individual Match". So consider adding a row to your Tournament table, maybe using a known key like 0 or -1, and using that for matches that are not part of a tournament.

MySQL database design: one-to-many relationship with two parents and one child

What is the proper design for the following situation:
I have people (t_people) who have phone numbers (t_numbers).
Looks like a simple one to many relationship with a foreign key in the numbers table.
EER diagram 1
But not only people can have phone numbers - companies (t_companies) can have phone numbers too.
I want to use only one phone number table. It looks like I need two one-to-many relationsships with one table (t_numbers) refering to either the t_people OR to t_companies.
Should I use two foreign keys allowing both of them to be NULL.
EER diagram 2
Or should I simply not use foreign keys at all?
E.g. I could have one "reference column" with the ID of EITHER one or the other table and a second one in which the table is stored to which the first column refers to.
[I am not allowed to post a third image ...]
How is such a problem usually solved?
(Or shoudl I just give up my plan of having just ONE phone number table and make one for people and one for comapnies.)
I think your should stick with your first diagram and simply add a type (person or company) column to the t_people table (may be renaming the table to something more generic).
If you want it normalized (and you will) It should be a good idea to create the entity type table with at least 2 rows (person and company) and relate this table with the "t_people"
Can two members of the same family have the same phone number? Can a person list his company phone?
But...
Let's not design the schema until we have a good picture of what SELECTs, etc, are needed.
If you only need to display "all phone numbers for a given entity", then a VARCHAR could have a commalist of numbers.
If you need to answer "who/what does this number belong to", then you need to focus on a table of phone numbers as the dominant table. It could have multiple rows for the same phone number. Or there could be a many-to-many table (or more than one such) to map phone numbers to entities.
Or maybe "Entity" is the focus. And Entity could be a Person or a Company. That smells like 3 tables -- Entity, Person, and Company.
Postpone thinking about the FOREIGN KEYS; get the logic right first, then the FKs will fall into place.

mysql handling nested data for a known number of levels

Now I have a hierarchical structure that looks like this:
.stage
...grade
.....semester
.......subject
.........unit
...........lesson
At first they were all stored inside the same table with an id parent relationship; however, each level of those 6 levels has its own data. For example, a lesson has featured_video_id and a subject has a language_id.
Now I'm thinking of creating 6 tables: one for each level and connect them with foreign keys. I'm thinking of all the possibilities and thought that a professional opinion will help. Will that division be of any good or it will be something that I will regret in the future?
I t makes a lot of sense to have separate tables for stages, grades, semesters, ...
You have already mentioned the best reason for this, you can add individual data for each of these levels. You can name the foreign keys in a sensible way (i.e. stage_id in the table for the grades). And I doubt you will ever need a list of subjects mixed in with lessons or semesters.
I'd do a bit of both:
Have a master table that contains all of the items at all levels with a common primary key. Include only the attributes that are common across all levels of the hierarchy. Link them with a parent key here.
Have separate tables for only the attributes that are unique to a particular level of the hierarchy. Use the primary key in the master table as a foreign key in these "detail tables."
This lets you separate your concerns. The structure of the hierarchy is in the master table. The details of each level are in the detail tables.

Shared Primary Key

I would guess this is a semi-common question but I can't find it in the list of past questions. I have a set of tables for products which need to share a primary key index. Assume something like the following:
product1_table:
id,
name,
category,
...other fields
product2_table:
id,
name,
category,
...other fields
product_to_category_table:
product_id,
category_id
Clearly it would be useful to have a shared index between the two product tables. Note, the idea of keeping them separate is because they have largely different sets of fields beyond the basics, however they share a common categorization.
UPDATE:
A lot of people have suggested table inheritance (or gen-spec). This is an option I'm aware of but given in other database systems I could share a sequence between tables I was hoping MySQL had a similar solution. I shall assume it doesn't based on the responses. I guess I'll have to go with table inheritance... Thank you all.
It's not really common, no. There is no native way to share a primary key. What I might do in your situation is this:
product_table
id
name
category
general_fields...
product_type1_table:
id
product_id
product_type1_fields...
product_type2_table:
id
product_id
product_type2_fields...
product_to_category_table:
product_id
category_id
That is, there is one master product table that has entries for all products and has the fields that generalize between the types, and type-specified tables with foreign keys into the master product table, which have the type-specific data.
A better design is to put the common columns in one products table, and the special columns in two separate tables. Use the product_id as the primary key in all three tables, but in the two special tables it is, in addition, a foreign key back to the main products table.
This simplifies the basic product search for ids and names by category.
Note, also that your design allows each product to be in one category at most.
It seems you are looking for table inheritance.
You could use a common table product with attributes common to both product1 and product2, plus a type attribute which could be either "product2" or "product1"
Then tables product1 and product2 would have all their specific attributes and a reference to the parent table product.
product:
id,
name,
category,
type
product1_table:
id,
#product_id,
product1_specific_fields
product2_table:
id,
#product_id,
product2_specific_fields
First let me state that I agree with everything that Chaos, Larry and Phil have said.
But if you insist on another way...
There are two reasons for your shared PK. One uniqueness across the two tables and two to complete referential integrity.
I'm not sure exactly what "sequence" features the Auto_increment columns support. It seem like there is a system setting to define the increment by value, but nothing per column.
What I would do in Oracle is just share the same sequence between the two tables. Another technique would be to set a STEP value of 2 in the auto_increment and start one at 1 and the other at 2. Either way, you're generating unique values between them.
You could create a third table that has nothing but the PK Column. This column could also provide the Autonumbering if there's no way of creating a skipping autonumber within one server. Then on each of your data tables you'd add CRUD triggers. An insert into either data table would first initiate an insert into the pseudo index table (and return the ID for use in the local table). Likewise a delete from the local table would initiate a delete from the pseudo index table. Any children tables which need to point to a parent point to this pseudo index table.
Note this will need to be a per row trigger and will slow down crud on these tables. But tables like "product" tend NOT to have a very high rate of DML in the first place. Anyone who complains about the "performance impact" is not considering scale.
Please note, this is provided as a functioning alternative and not my recommendation as the best way
You can't "share" a primary key.
Without knowing all the details, my best advice is to combine the tables into a single product table. Having optional fields that are populated for some products and not others is not necessarily a bad design.
Another option is to have a sort of inheritence model, where you have a single product table, and then two product "subtype" tables, which reference the main product table and have their own specialized set of fields. Querying this model is more painful than a single table IMHO, which is why I see it as the less-desirable option.
Your explanation is a little vague but, from my basic understanding I would be tempted to do this
The product table contains common fields
product
-------
product_id
name
...
the product_extra1 table and the product_extra2 table contain different fields
these tables habe a one to one relationship enforced between product.product_id and
product_extra1.product_id etc. Enforce the one to one relationship by setting the product_id in the Foreign key tables (product_extra1, etc) to be unique using a unique constraint.
you will need to decided on the business rules as to how this data is populated
product_extra1
---------------
product_id
extra_field1
extra_field2
....
product_extra2
---------------
product_id
different_extra_field1
different_extra_field2
....
Based on what you have above the product_category table is an intersecting table (1 to many - many to 1) which would imply that each product can be related to many categories
This can now stay the same.
This is yet another case of gen-spec.
See previous discussion