Проектирование реляционной базы данных - использовать иерархические модели данных или избегать их? - PullRequest
5 голосов
/ 05 февраля 2011

Я проектирую базу данных, и у меня есть некоторые сомнения по поводу использования иерархических моделей данных в реляционных базах данных.

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

Кстати, я использую PostgreSQL.

Извините за мой плохой английский.

С наилучшими пожеланиями,

Ответы [ 3 ]

18 голосов
/ 05 февраля 2011

У вас есть несколько вариантов хранения иерархий:

  • Список смежности
  • Рекурсивный запрос в списке соседей
  • Перечисление пути
  • Вложенные множества
  • Закрытие стола

Если у вас PostgreSQL версии 8.4 или новее, вы можете использовать рекурсивные запросы , чтобы упростить задачу. Это, безусловно, самое простое решение, легко запрашивать, легко вставлять новые записи, легко обновлять текущие записи, легко удалять записи, и у вас есть ссылочная целостность. У всех других решений есть детали, которые трудно решить.

Список приставок:

CREATE TABLE categories ( 
  id SERIAL PRIMARY KEY, 
  parent_id BIGINT, 
  category TEXT NOT NULL, 
  FOREIGN KEY (parent_id) REFERENCES categories(id) 
);

INSERT INTO categories(parent_id, category) VALUES(NULL, 'vehicles');
INSERT INTO categories(parent_id, category) VALUES(1, 'cars');
INSERT INTO categories(parent_id, category) VALUES(1, 'motorcycles');
INSERT INTO categories(parent_id, category) VALUES(2, 'SUV');
INSERT INTO categories(parent_id, category) VALUES(2, 'sport');
INSERT INTO categories(parent_id, category) VALUES(3, 'cruising'); 
INSERT INTO categories(parent_id, category) VALUES(3, 'sport'); 


WITH RECURSIVE tree (id, parent_id, category, category_tree, depth) 
AS ( 
    SELECT 
        id,
        parent_id,
        category,
        category AS category_tree,
        0 AS depth 
    FROM categories 
    WHERE parent_id IS NULL 
UNION ALL 
    SELECT 
        c.id,
        c.parent_id,
        c.category,
        tree.category_tree || '/' || c.category AS category_tree,
        depth+1 AS depth 
    FROM tree 
        JOIN categories c ON (tree.id = c.parent_id) 
) 
SELECT * FROM tree ORDER BY category_tree;

Результат:

'1', '', 'автомобиль', 'автомобиль', '0'

'2', '1', 'авто', 'автомобиль / автомобили', '1'

4 ', '2', 'внедорожник', 'автомобиль / автомобили / SUV', '2'

'5', '2', 'Спорт', 'автомобиль / автомобили / спорт', '2'

* +1032 * '3', '1', 'мотоциклов', 'транспортное средство / мотоциклы', '1'
* +1034 * '6', '3', 'крейсерской', 'транспортного средства / мотоциклы / крейсерская', '2' * * тысяча тридцать-пять

'7', '3', 'спорт', 'транспортное средство / мотоциклы / спорт', '2' * * тысяча тридцать семь

1 голос
/ 15 мая 2013

Если вы используете Postgres, вы можете сохранить иерархию в массиве как материализованный путь .

Этот подход также полезен для индексации GIN, которая в моих экспериментах показала лучшую производительность, чем рекурсивный запрос.

0 голосов
/ 05 февраля 2011

Что вы подразумеваете под «иерархической моделью данных»?Если вы просто имеете в виду моделирование иерархии в реляционной базе данных или базе данных SQL, то это совершенно обычное и разумное решение.Существует большое количество литературы по базе данных на предмет того, как моделировать иерархии реляционно.В этом нет ничего «нереляционного».

Однако термин Иерархическая модель данных чаще относится к типу СУБД (не к СУБД или SQL).СУБД).Иерархические / сетевые / графические СУБД работают по принципам, отличным от СУБД - они используют навигационные или основанные на указателе модели, а не реляционную модель.Реляционная / SQL-модель в значительной степени (но не полностью) заменила этот тип СУБД.Если вы не используете иерархический тип СУБД, вам не нужно об этом беспокоиться.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...