Консультации по иерархическому проектированию базы данных MySQL

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

Для простого примера:

Раздел 1

Раздел 1.1
Подраздел 1.1.1
Подраздел 1.1.2

Подраздел 1.2
Подраздел 1.2.1
Подраздел 1.2.2

Раздел 2

Подраздел 2.1
Подраздел 2.1.1
Подраздел 2.1.2

Подраздел 2.2
Подраздел 2.2.1
Подраздел 2.2.2

Структура дерева не изменится, пользователи будут просто загружать продукты, которые попадут в подразделения (отраслевой способ организации большого количества продуктов). Я провел исследование списков смежности и вложенных наборов, но я склоняюсь к трем отдельным таблицам, каждая из которых ссылается на свой родительский первичный ключ (поскольку верхние уровни дерева практически никогда не изменятся). Когда загружается новый продукт, он будет ссылаться на всех трех своих родителей (если он зарегистрирован в подразделе 1.1.2, он обязательно является частью раздела 1, подраздел 1). Окончательное дерево будет состоять из 4 разделов, по 10 разделов в каждом разделе и 10 подразделов в каждом разделе. Имеет ли это смысл в качестве стартовой стратегии?

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

Будем признательны за любые рекомендации или ссылки на литературу / учебные пособия!


person NallyRoll    schedule 22.03.2012    source источник
comment
Если у вас никогда не будет более трех уровней, вы можете пойти «дешево», просто иметь (section_id, div_id, subdiv_id) и хранить все это в одной таблице. однако он будет уязвим для ошибок иерархии, таких как sec #1, div 2.1, subsec 1.1.1.   -  person Marc B    schedule 22.03.2012
comment
Я согласен с Марком Б. технически ваша структура является иерархической, но ее структура недостаточно динамична, чтобы гарантировать расширенную структуру данных. вы можете избежать ошибок категорий с помощью простых ограничений   -  person David Chan    schedule 23.03.2012
comment
Большое спасибо Марку и Дэвиду! Дэвид, не могли бы вы подробнее рассказать о том, что вы подразумеваете под простыми ограничениями? Марк Б, если все продукты должны быть отнесены к подразделу (например, Macintosh Apple Orchard Билла, внесенный в список AmericanFruit ›Apple› Macintosh), я прав, когда говорю, что у меня будет одна таблица, описывающая неизменное дерево, а затем вторая таблица, которая содержит конкретную информацию и идентификатор для Macintosh Apple Orchard Билла и ссылку на его родительский subdiv_id? Надеюсь, это понятно :)   -  person NallyRoll    schedule 23.03.2012


Ответы (4)


Поскольку «структура дерева не изменится» вам потребуются таблицы section, division и subdivision (также продукты).

create table section (
  id int primary key,
  name varchar(100) 
);

create table division (
  id int primary key,
  name varchar(100) ,
  section_id int references section
);

create table subdivision (
  id int primary key,
  name varchar(100) ,
  division_id int references division
);

create table product (
  id int primary key,
  name varchar(100) ,
  subdivision_id int references subdivision
);

Для других требований, например:

  • Неизвестное дерево глубины.
  • Распределите продукты по нескольким древовидным уровням.

Вы будете искать решение родитель-ребенок, например:

create table tree (
  id int primary key,
  parent_id int null references tree,
  name varchar(100) 
);

create table product (
  id int primary key,
  name varchar(100) ,
  subdivision_id int references tree
);
person dani herrera    schedule 22.03.2012
comment
Большое спасибо за это! Это именно то, что я пытался выразить. Я начал этот процесс, но не был уверен, было ли это приемлемым решением. - person NallyRoll; 23.03.2012

Поскольку категории (разделы) более или менее статичны, вы можете присвоить каждой категории «высокий» и «низкий» номер, например

catid  name        low      high
1      Section1     1       20
2      Div1.1       2       10
3      Div1.2       11      19
4      Section2     21      40
5      Div2.1       22      29
6      Div2.2       30      39

Тогда создайте отдельную таблицу для содержания:

id   catid   content
1    2       fileA 
2    2       fileB
3    5       fileC

Чтобы затем запросить ВСЕ элементы в разделе 1, вы просто запрашиваете все элементы в категории с высоким и низким значением от 1 до 20. Чтобы получить все элементы в Div2.1 (и ниже), вы запрашиваете все элементы, у которых есть категории, высокие и низкие - от 22 до 29. Это позволяет очень легко отслеживать количество элементов в подкатегориях.

Я забыл название этого фактического подхода (если есть окончательный), но я использовал его несколько раз. Для структур, которые не сильно меняются, работать с ними намного проще, чем с традиционной структурой типа parent_id-child_id.

person GrandmasterB    schedule 22.03.2012
comment
Я думаю, это называется вложенными наборами: mikehillyer.com/articles/managing-hierarchical- данные в MySQL - person Nathan; 23.03.2012
comment
GrandmasterB и другие, спасибо за вклад. На самом деле я ранее рисовал схему на диаграмме вложенных наборов (это заняло много времени, около 400 возможных подразделений). Мои вопросы начинаются со второй описанной вами таблицы. Элементы ДОЛЖНЫ быть разделены на категории, поэтому вся вводимая информация всегда будет на одном уровне. Как будет выглядеть фрагмент кода для ввода fileC в раздел 2, раздел 2, подраздел 1 (из вашего примера)? Также (снято в темноте) есть ли простой способ присвоить низкие / высокие числа большому количеству узлов дерева? - person NallyRoll; 23.03.2012
comment
Вы можете преобразовать рекурсивную таблицу во вложенный набор. Отметьте это сообщение: sqlblog.com/blogs/adam_machanic/archive/2006/07/12/ Также это: jsimonbi.wordpress.com/2011/02/14/nested-set-hierarchy - person Nathan; 24.03.2012
comment
@TheNally, добавьте «нижний» столбец для обозначения категорий, которые находятся внизу дерева. Затем при добавлении файлов разрешите добавление файлов только в эти категории. - person GrandmasterB; 25.03.2012

Хорошим решением была бы рекурсивная таблица.

Проверьте это сообщение в StackOverflow: Иерархические данные в MySQL

Таким образом, ваш дизайн будет поддерживать большее количество уровней вниз по дереву.

Другие интересные статьи по этой теме:

Управление иерархическими данными в MySQL

Иерархические данные в MySQL: родители и дети в одном запросе

Иерархические данные в MySQL: просто и быстро

Рекурсия -без хранения иерархических данных в реляционной базе данных

person Nathan    schedule 22.03.2012
comment
спасибо за ссылки, некоторые из них я проверил, но я обязательно изучу рекурсивные таблицы. Еще раз спасибо! - person NallyRoll; 23.03.2012

Взгляните на вложенные наборы и вложенные интервалы:

person Rid Iculous    schedule 24.09.2013