2011-02-16 3 views
1

Я просматривал посты, которые говорят о выборе иерархическую контента из базы данных, но я до сих пор есть сомнения относительно того, как я мог бы реализовать следующее: Я три таблицы:Иерархическая база данных Меню

  • Locations : Здесь я храню место и его корреспондентский родитель (например, Европа-> Великобритания-> Лондон).
  • Здания: Здесь я храню здания. Одно здание должно находиться в одном месте.
  • Местоположение пользователя: Здесь я храню местоположения, которые может видеть конкретный пользователь.
  • User-Buildings: Здесь я храню здания, которые сможет увидеть конкретный пользователь.

Обратите внимание, что администратор может сказать: «Пользователь 1 увидит все здания из Японии, а также он сможет увидеть это конкретное здание из Франции, но только тот».

Со всем этим, я хотел бы построить меню (для конкретного пользователя), что будет что-то вроде:

  • зданий
    • Европа
      • Германия
        • Мюнхен
          • Building_1
          • Building_2
      • UK
        • Лондон
          • Building_3

У меня возникли некоторые сомнения относительно того, как я могу получить эту информацию, и я был бы признателен за любые мысли.

Отредактировано:

Структура таблицы:

1) Здания

  • Id (первичный ключ)
  • Название, описание, ...
  • LOCATION_ID (внешний ключ к местоположению таблица)
  • Company_ID (внешний ключ к столу компании). Здание должно принадлежать j ust одна компания).

2) Места

  • Id (первичный ключ)
  • Имя
  • Родитель Id (внешний ключ к самой таблице .. например: London запись будет иметь внешний ключ для вступления Великобритании .

3) Компания

  • Id (первичный ключ)
  • Название, описание ...

4) Пользователи

  • Id (первичный ключ)
  • company_id (внешний ключ к компании этого пользователя (пользователь принадлежит только одной компании).

5) User-Здания

  • Id_User (Внешний ключ к таблице пользователей)
  • Id_Building (Внешний ключ для строительного стола)

6) Пользователь-Location

  • Id_User (внешний ключ для пользовательской таблицы)
  • Id_Location (Внешний ключ к таблице местоположения)

Идея состоит в том, что компания может назначить здания, которые пользователь может видеть. Компания может назначать определенные здания (не зависимые от местоположения), и поэтому существует таблица User-Building, и они также могут назначать местоположение, поэтому пользователь увидит все здания, принадлежащие этому местоположению.

Спасибо за комментарии, и я надеюсь, что немного разъяснил.

Спасибо.

+0

Что касается хранения иерархических данных в MySql, см. Http://dev.mysql.com/tech-resources/articles/hierarchical-data.html –

+0

Можете ли вы рассказать нам о своей структуре таблиц и, возможно, составить некоторые демо-данные? Этот вопрос касается хранения и извлечения данных. – Bajrang

ответ

1

Если вы хотите придерживаться вашей текущей схемы базы данных, проблема в том, что места, похоже, не имеют фиксированного количества уровней, поэтому вам придется делать уродливую петлю для извлечения подуровней user_location.id_location и их зданий. Это поможет много, если вы сможете отличить уровни местоположения в значимых категориях, таких как регион, страна, город. Таким образом, вы могли бы иметь такое определение таблицы:

CREATE TABLE buildings (
    id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT, 
    name VARCHAR(255) NOT NULL, 
    ... 
    region_id INTEGER UNSIGNED NOT NULL, 
    country_id INTEGER UNSIGNED NOT NULL, 
    city_id INTEGER UNSIGNED NOT NULL, 
    PRIMARY KEY (id), 
    INDEX (region_id), 
    INDEX (country_id), 
    INDEX (city_id), 
    FOREIGN KEY (region_id) REFERENCES locations(id) ON DELETE RESTRICT, 
    FOREIGN KEY (country_id) REFERENCES locations(id) ON DELETE RESTRICT, 
    FOREIGN KEY (city_id) REFERENCES locations(id) ON DELETE RESTRICT 
) TYPE=InnoDB; 

CREATE TABLE user_location (
    user_id INTEGER UNSIGNED NOT NULL, 
    location_id INTEGER UNSIGNED NOT NULL, 
    PRIMARY KEY (user_id, region_id, country_id, city_id), 
    INDEX (user_id), 
    INDEX (location_id), 
    FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE, 
    FOREIGN KEY (location_id) REFERENCES locations(id) ON DELETE CASCADE 
) TYPE=InnoDB; 

Затем вы можете получить свои здания, как это:

SELECT * FROM buildings WHERE id IN (
    (SELECT building_id FROM user_buildings WHERE user_id = ?) 
    UNION 
    (SELECT id FROM buildings 
    LEFT JOIN user_location ON 
    (user_location.location_id = buildings.region_id 
     OR user_location.location_id = buildings.country_id 
     OR user_location.location_id = buildings.city_id) 
    WHERE user_id = ?) 
); 

Возвращенные строки будут содержать информацию, необходимую для построения дерева.

+0

Спасибо за это Алессандо. Моя единственная проблема заключается в том, что даже если пользователь связан с разными местоположениями, и поэтому мы можем получить все здания из этого места, может случиться, что у пользователя есть здание и только одно здание в месте. – Nobita

+0

Это поддерживается. Моя схема позволяет вам определять несколько политик для каждого пользователя: 'user_buildings' содержит разрешения для одного здания, а' user_location' содержит более широкие политики, которые позволяют пользователю видеть все здания в городе/стране/регионе. Если вы хотите, чтобы пользователь видел отдельные здания без предоставления разрешений для всего местоположения, просто поместите строку в 'user_buildings'. – Alessandro

Смежные вопросы