user468311
user468311

Reputation:

How do I store nested locations?

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

Answers (3)

user1101733
user1101733

Reputation: 258

You can store it in one tabel and retreive sublocations using self join.

Upvotes: 0

Gordon Linoff
Gordon Linoff

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

StanislavL
StanislavL

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

Related Questions