Current Situation
We have a table called c
with ca. 300,000 rows. In this table we store the competitors for a specific product.
Example:
id | competitors | some infos about competitor | product --------------------------------------------------------------- 1 | C_1 | xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx | P_1 2 | C_2 | xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx | P_1 3 | C_3 | xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx | P_1 4 | C_1 | xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx | P_2 5 | C_4 | xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx | P_2
Every 30 minutes we read in the new competitors. To do so we first delete everyone with the specific product (P_1) and insert afterwards the new ones. So there will never be a competitor in our DB, which isnt at the moment listed for this product.
When we got the new infos, we do some kind of research with the products.
(We also have a table called p
with ca. 100,000 rows. In that table we store the infos about the products.)
So back to the research process. We run through every product an have to get the competitors with their infos. For this purpose we have do do a mysql request like SELECT * FROM c WHERE product LIKE "P_1";
. Not to say that this is not very performant.
My Goal
I want to achieve, that with only one query i got the product information from p
an also the competitor ones from c
where the product id
is the same.
So that these infos get stored in an array like this:
[0]['id'] => '2'
[0]['product_identifier'] => 'P_1'
[0]['c'][0]['competitors'] => 'C_1'
[0]['c'][1]['competitors'] => 'C_2'
[0]['c'][3]['competitors'] => 'C_3'
Possible Solution
To get the needed information with just one query, i came up with this solution.
In table c
the product row contains a foreign key which links to the p
table. That would be very easy to realise. But I am asking myself if it would be possible to delete c
or p
rows easaly. I never worked that intensive with foreign keys – seemed to me always a bit error generating.
And I also wonder if I could make a join that easy, cause I want from p
the related competitors and not the other way around. You know what I mean? Not sure if I can do that this way. And if I could, how to tread this foreign keys. What do I have looking for in order to not get messed up with an unclean database.
Example
We will use our table c
from above, where c.product
stores the foreign key to our table p.product_identifier
. Like this:
id | product_identifier | some infos about the product --------------------------------------------------------------- 1 | P_1 | xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 2 | P_2 | xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 3 | P_3 | xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
I am not sure how this works out or if it's even a good idea, but how has my query look like? If i want to SELECT
every product from p
and also their competitors from c
?
Best Answer
First, if your tables are InnoDB, and column
c.P_ID
is the reference of columnp.P_ID
(note actual column names may be different), then you absolutely should use foreign keys to avoid orphans, but know that you will have to explicitly stateON DELETE CASCADE
, since the default isON DELETE SET NULL
, retaining orphans.But this doesn't really have anything to do with the 'single query' to select the products and information about the competitors.
To achieve:
your query would use a join:
This will get you repeat information for the products (competitor info will be different). And then you will use your application to parse that info into the array you need.
If you want a single row for the products, you can use the
GROUP_CONCAT
function for the competitors:A major caveat you should be aware of:
ON UPDATE|DELETE CASCADE
does not fire triggers on the rows that were deleted/updated by the cascade:This shouldn't stop you from using
CASCADE
if you want to remove orphan rows. But you should be aware of it.