Дизайн базы данных - предметы и регионы - PullRequest
0 голосов
/ 03 декабря 2011

У меня проблема проектирования структуры базы данных.Цель состоит в том, чтобы иметь базу данных для предложений, которые наши клиенты предлагают в некотором географическом регионе.Каждое предложение может быть предложено во многих регионах.

Регионы находятся в иерархии - пример:

subregion_1
  subregion_11
    region_111
    region_112
  subregion_12
    region_121
    region_122
subregion_2
  subregion_21
    region_221

Теперь я хочу сохранить в базе данных offer_1 и регионы для этого предложения.Я приведу 3 примера того, что я должен достичь:

  • , когда мое предложение_1 хранится в region_111, тогда я хотел бы отобразить это предложение, когда пользователь просматривает subregion_1, subregion_11 и region_111
  • Если предложение_1 хранится в регионах subregion_11 и region_121, тогда предложение должно отображаться, когда пользователь просматривает субрегион_1, subregion_11 и все ветви субрегиона_11, subregion_12 и region_121
  • , когда мое предложение_1 сохраняется в субрегионе_1, тогда предложениеотображается на странице subregion_1, а все ветви - в subregion_1.

Также я должен предоставить способ динамического и очень быстрого расчета количества различных предложений в каждом регионе.Есть ли у кого-нибудь совет, как можно подойти к этому дизайну?

Вот что у меня есть.

Regions
------------------------------------------------------------
| id     | level1 | level2 | level3 | name         | level |
------------------------------------------------------------
| 02     | 02     | null   | null   | subregion_1  | 1     |
| 0201   | 02     | 01     | null   | subregion_11 | 2     |
| 020103 | 02     | 01     | 03     | region_111   | 3     |
------------------------------------------------------------

Offers to regions
------------------------
| offer_id | region_id |
------------------------
| 1        | 020103    |
| 1        | 0202      |
------------------------

Я создал идентификатор для регионов из конкатенации level1, level2 и level3.В таблице Offers_to_regions я храню предложение и регион.Здесь у меня есть регион на уровне 3 (020103) и регион на уровне 2 (0202) для предложения 1. При таком дизайне у меня возникают проблемы с тем, как запрашивать количество разных предложений для региона и как запрашивать предложения для регионов на уровне 1, уровне 2.и 3 уровня.

1 Ответ

1 голос
/ 03 декабря 2011

Ну, есть очевидный способ, который использует идентификатор для указания на родителя, подобного этому

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:

Я только что заметил, что вы редактировали свой вопрос, а также то, что предложения могут принадлежать более чем одному региону. Выше может потребоваться корректировка для поддержки назначения более чем одного региона, но основная идея все еще может быть применена.

...