Дизайн базы данных SQL, рекурсивные родительско-дочерние отношения?

Я хочу представить рекурсивные родительско-дочерние отношения в базе данных MySQL. Я хочу создать _1 _-_ 2_ отношения. Категория может иметь N подкатегорий, и каждая из них может иметь N подкатегорий и так далее. Я думал о том, чтобы иметь одну category таблицу с внешним ключом, указывающим на нее. Вот что я имею в виду:

CREATE TABLE `category` (
  `id` int NOT NULL AUTO_INCREMENT,
  `name` varchar(50) NOT NULL,
  `parent_category` int NULL,
  PRIMARY KEY (`id`),
  FOREIGN KEY (`parent_category`) REFERENCES `category` (`id`)
)

parent_category может иметь значение NULL, если категория является категорией верхнего уровня.

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


person Christos Baziotis    schedule 30.08.2014    source источник
comment
возможный дубликат SQL - как хранить иерархии и перемещаться по ним?   -  person Jim Lewis    schedule 30.08.2014
comment
Из-за ограниченных возможностей SQL в MySQL я бы не стал так поступать в MySQL. Вам будет очень сложно получить данные из этой иерархии из-за отсутствия рекурсивных запросов. Поиск модели вложенных множеств для другого проекта, который может быть реализован с помощью MySQL.   -  person a_horse_with_no_name    schedule 30.08.2014


Ответы (1)


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

Другое решение - использовать объединенную строку, представляющую вашу иерархию. Например :

  1. Европа 1.1 Франция 1.1.1 Париж 1.1.2 Марсель
  2. Америка 2.1 Соединенные Штаты Америки 2.1.1 Вашингтон

DDL будет примерно таким:

   CREATE TABLE `category` (
  `id` int NOT NULL AUTO_INCREMENT,
  `name` varchar(50) NOT NULL,
  `link` varchar(30) NOT NULL DEFAULT '.',
  PRIMARY KEY (`id`),
)

Эта структура данных упрощает ваши запросы, но обновления выполняются медленнее.

Другое решение - модель вложенного набора, в которой вы регистрируете идентификатор узла справа и слева от текущего узла. Это наиболее эффективная структура для запросов, но она затрудняет вставку и обновление.

http://en.wikipedia.org/wiki/Nested_set_model

Я рекомендую вам книгу Джо Селко о деревьях и иерархиях.

person Sébastien Maloron    schedule 03.09.2014