2014-08-30 3 views
5

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

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 может быть пустым, если категория является категорией верхнего уровня.

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

+0

возможно дубликат [SQL - Как хранить и навигации по иерархиям] (http://stackoverflow.com/questions/38801/sql -how-to-store-and-navigate-hierarchies) –

+2

Из-за ограниченных возможностей SQL SQL, я бы так не делал этого в MySQL. Из-за отсутствия рекурсивных запросов у вас будет очень трудно получить данные из этой иерархии. Найдите «модель вложенного набора» для другого дизайна, который может быть реализован с помощью MySQL –

ответ

4

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

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

  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

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