Ну, есть очевидный способ, который использует идентификатор для указания на родителя, подобного этому
CREATE TABLE Regions (
region_id INT AUTO_INCREMENT PRIMARY KEY,
parent_id INT,
region_name VARCHAR(100) NOT NULL,
FOREIGN KEY (parent_id) REFERENCES Regions(region_id)
);
Но в вашей ситуации это может считаться анти-паттерном, поскольку не так просто выполнить запрос по иерархии (особенно если меняется количество уровней)
Другой подход мог бы использовать что-то вроде Перечисление пути , где вы сохраняете путь иерархии, подобный, например, путям Unix. Э.Г.
CREATE TABLE Regions (
region_id INT AUTO_INCREMENT PRIMARY KEY,
path VARCHAR(100),
region_name VARCHAR(100) NOT NULL
);
Это позволит вам хранить вашу иерархию следующим образом
---------------------------------------------
| region_id | path | region_name |
---------------------------------------------
| 1 | 1/ | subregion_1 |
| 2 | 1/2/ | subregion_11 |
| 3 | 1/2/3/ | region_111 |
| 4 | 1/2/4/ | region_112 |
---------------------------------------------
Таким образом, при запросе таблицы предложений (где каждое предложение будет иметь ссылку на region_id) и при просмотре, скажем, предложение для субрегиона_1 (с идентификатором 1), ваш запрос может выглядеть примерно так:
select Offers.SOME_COLUMN, ......
from Offers, Regions
where Offers.region_id = Regions.region_id
and Regions.path like '1/%'
Существуют другие шаблоны для моделирования ваших иерархических данных, такие как Вложенные наборы и Таблица закрытия ( может быть релевантна ), которые вы может быть интересно посмотреть также. у каждого свои плюсы и минусы с точки зрения выбора / вставки / удаления производительности
EDIT:
Я только что заметил, что вы редактировали свой вопрос, а также то, что предложения могут принадлежать более чем одному региону. Выше может потребоваться корректировка для поддержки назначения более чем одного региона, но основная идея все еще может быть применена.