Reputation:
In my project I have locations of the product, which may look like this:
- Location 1
-- SubLocation 1
-- SubLocation 2
- Location 2
-- SubLocation 3
-- SubLocation 4
Imagine a zones with subzones in the facilty.
I need to store that in DB and then retrive sometime later, like this: SubLocation 1 at Location 1
.
My first guess is to have two tables with one to many ralationship, but that won't scale, it later I'll need to have something like this:
- Location 2
-- SubLocation 3
-- SubLocation 4
---- SubLocation 5
---- SubLocation 6
So my question is what's the best way to store such structure in relational database?
Upvotes: 0
Views: 266
Reputation: 258
You can store it in one tabel and retreive sublocations using self join
.
Upvotes: 0
Reputation: 1269883
Dealing with hierarchical data is difficult in MySQL. So, although you might store the data in recursive tables, querying the data is (in general) not easy.
If you have a fixed set of hierarchies, such as three (I'm thinking "city", "state", "country"), then you can have a separate table for each entity. This works and is particularly useful in situations where the elements can change over time.
Alternatively, you can have a single table that flattens out the dimensions. So, "city", "state", and "country" are all stored on a single row. This flattens out the data, so it is no longer normalized. Updates become tedious. But if the data is rarely updated, then that is not an issue. This form is a "dimensional" form and used for OLAP solutions.
There are hybrid approaches, where you store each element in a single table, in a recursive form. However, the table also contains the "full path" to the top. For instance in your last example:
/location2/sublocation3
/location2/sublocation4
/location2/sublocation4/sublocation5
/location2/sublocation4/sublocation6
This facilitates querying the data. But it comes at the cost of maintenance. Changing a something such as sublocation4
requires changing many rows. Think triggers.
The easiest solution is to use different tables for different entities, if you can.
Upvotes: 1
Reputation: 57381
You can define parent_id reference FK to another record with id (roots have null parent_id).
To define hierarhy and retrieve all subtree in one query you can define an additional field path (VARCHAR). The field should have full path of ids separated with '_'
In your case SubLocation 5 has the path="2_4_5"
To retrieve all the children of SubLocation 4 you can use
select *
from myTable
where path like '2_4%';
There is level depth restriction (size of the path in fact) but for most cases it should work.
Upvotes: 1