Подскажите как организовать бд под меню

12
D
На сайте с 20.09.2010
Offline
175
1264

Нужно сделать такое меню, в котором запись одновременно может быть и на 2-м и на 3-м уровне вложенности, подскажите как организовать БД под такую структуру:

Главная категория 1

- Подкатегория 1.1

-Подскатегория 1.1.1

-Подскатегория 1.1.2

- Подскатегория 1.2

Главная категория 2

- Подкатегория 1.1.1

- Подкатегория 3.1

Главная категория 3

- Подкатегория 3.1

ДП
На сайте с 23.11.2009
Offline
203
#1

Советую разбить на две таблицы - в одной хранить собственно дерево категорий (тут есть разные подхода - nested sets, materialized path, adjacency list - по этим фразам погуглите, у подходов разные достоинства и недостатки)

А в другой - собственно справочник категорий.

В первой таблице храните просто id нужной категории из справочника и при выборке меню join'ите с таблицей-справочником.

L
На сайте с 12.05.2017
Offline
14
#2
datum:
Нужно сделать такое меню, в котором запись одновременно может быть и на 2-м и на 3-м уровне вложенности, подскажите как организовать БД под такую структуру:

Главная категория 1
- Подкатегория 1.1
-Подскатегория 1.1.1
-Подскатегория 1.1.2
- Подскатегория 1.2
Главная категория 2
- Подкатегория 1.1.1
- Подкатегория 3.1
Главная категория 3
- Подкатегория 3.1

Не нужно БД этим вообще напрягать.

---------- Добавлено 25.02.2018 в 12:29 ----------

Дикий пионер:
Советую разбить на две таблицы - в одной хранить собственно дерево категорий (тут есть разные подхода - nested sets, materialized path, adjacency list - по этим фразам погуглите, у подходов разные достоинства и недостатки)
А в другой - собственно справочник категорий.
В первой таблице храните просто id нужной категории из справочника и при выборке меню join'ите с таблицей-справочником.

Микроскоп не жалко?

Уже не считая того, что это будет медленно работать

---------- Добавлено 25.02.2018 в 12:35 ----------

datum:
Нужно сделать такое меню, в котором запись одновременно может быть и на 2-м и на 3-м уровне вложенности, подскажите как организовать БД под такую структуру:

Главная категория 1
- Подкатегория 1.1
-Подскатегория 1.1.1
-Подскатегория 1.1.2
- Подскатегория 1.2
Главная категория 2
- Подкатегория 1.1.1
- Подкатегория 3.1
Главная категория 3
- Подкатегория 3.1

1. Видимо речь об MySQL? Да, реляционные СУБД хреново работают с иерархией. Впрочем и БД "ключ-значение" тоже с ней хреново работают.

2. Придется реализовывать это 2 раза:

Для хранения

Для выдачи пользователю.

Если сделать один раз, то по причине п. 1 простая примитивная выдача из меню будет нагружать сервер совершенно напрасно.

Для хранения делается одна-единственная таблица

В ней 3 поля:

ID - уникальный идентификатор

ParentID - ссылка на ID родительского пункта меню; очевидно, что у меню на первом уровне здесь пусто.

Name - собственно текст.

Но вот писать запрос для извлечения этого всего из БД - вы задолбаетесь.

Реляционные БД, к коим относится и MySQL, это делают криво-косо. Это их родовая особенность. Не обработки иерархий они предназначены.

Впрочем, если глубина вложенности иерархии всегда одна и то же, то дело легче пойдет. Но я бы не стал.

В описанной таблице с тремя полями ID, ParentID, Name имеет смысл хранить данные только для удобства редактиования.

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

Отдавать же пользователям следует строго из другой структуры - из того же Memcached, например.

ДП
На сайте с 23.11.2009
Offline
203
#3
Микроскоп не жалко?
Уже не считая того, что это будет медленно работать

А memcached не микроскоп? БД-то всяко на сайте будет, вот в ней и хранить.

При хранении с помощью nested sets всё дерево (а также ветка, родительская ветка) выбирается в один запрос с использованием числовых полей в условии - я не особо представляю на каких объемах данных это будет тормозить. Джойн по числовому ключу тоже. Да, вставка там нетривиальна, но сдаётся мне, что она выполняться будет на порядки реже, чем выборка.

Тут человек спрашивает как ему дерево хранить - а вы ему memcached сразу предлагаете, оптимизаторы мамкины.

L
На сайте с 12.05.2017
Offline
14
#4
Дикий пионер:
А memcached не микроскоп? БД-то всяко на сайте будет, вот в ней и хранить.
При хранении с помощью nested sets всё дерево (а также ветка, родительская ветка) выбирается в один запрос с использованием числовых полей в условии - я не особо представляю на каких объемах данных это будет тормозить. Джойн по числовому ключу тоже. Да, вставка там нетривиальна, но сдаётся мне, что она выполняться будет на порядки реже, чем выборка.
Тут человек спрашивает как ему дерево хранить - а вы ему memcached сразу предлагаете, оптимизаторы мамкины.

С иерархическими списками неспециализированные для иерархических данных СУБД работают крайне отвратительно.

Неквалифицированные советчики просто ничего не знают кроме MySQL потому и думают, что весь секрет - похитрее (понепонятнее для программиста, чтобы работать было неудобнее с ними) таблицы наделать - что мол летать будет. Ан, нет.

Лучше человеку сразу понять, что инструменты решения разных задач - разные.

А том у меня есть знакомые "программисты" и с 10-летним опытом, что знают только один ответ на вопрос где хранить

🍿

ДП
На сайте с 23.11.2009
Offline
203
#5
logamagoga:
С иерархическими списками неспециализированные для иерархических данных СУБД работают крайне отвратительно.

Допустим.

Но вы-то что насоветовали? специализированную иерархическую БД или велосипед из (наверно самой неоптимальной) структуры в реляционной БД и key-value хранилища?

Как в вашей структуре надо будет хранить подкатегорию, у которой может быть сразу два родителя? А если это будут две разных по сути категории с одинаковым названием?

L
На сайте с 12.05.2017
Offline
14
#6
Дикий пионер:
Допустим.
Но вы-то что насоветовали? специализированную иерархическую БД или велосипед из (наверно самой неоптимальной) структуры в реляционной БД и key-value хранилища?
Как в вашей структуре надо будет хранить подкатегорию, у которой может быть сразу два родителя? А если это будут две разных по сути категории с одинаковым названием?

Не допустим, а так и есть. Иерархия это противная штука по производительности для всех распространенных СУБД (а к распространенным относятся классические реляционные MySQL/Postgres и т.п.; а также NoSQL, буде то документо-ориентированные или key-value). Не так плохо с иерархией только если уровень вложенности фиксированный и заранее известный программисту (разумеется если программист умеет это учитывать).

Иерархическая БД для данной задачи не нужна.

Предлагаемый вариант - это самая оптимальная структура в БД - потому что самая простая, более-менее естественная и понятная для программиста (ну насколько позволяют реляционные особенности СУБД). Повторяю еще раз - для хранения, для редактирования. Но не для выдачи пользователю. Эту структуру удобно редактировать и генерировать из нее кэшированные данные.

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

---------- Добавлено 25.02.2018 в 14:04 ----------

Дикий пионер:

Как в вашей структуре надо будет хранить подкатегорию, у которой может быть сразу два родителя? А если это будут две разных по сути категории с одинаковым названием?

Ровно столько вариантов хранить сколько будет вариантов отображения этого пользователю.

Если на всех страницах сайта меню отображается всегда целиком - достаточно хранить один-единственный вариант с полным меню.

ДП
На сайте с 23.11.2009
Offline
203
#7
logamagoga:

Ровно столько вариантов хранить сколько будет вариантов отображения этого пользователю.

Т.е. в случае переименования какой-то из подкатегорий ТС надо будет руками каждую подкатегорию переименовывать?

L
На сайте с 12.05.2017
Offline
14
#8
Дикий пионер:
Т.е. в случае переименования какой-то из подкатегорий ТС надо будет руками каждую подкатегорию переименовывать?

Термин "инвалидация кэша" вам о чем нибудь говорит?

M
На сайте с 04.12.2013
Offline
223
#9

И как это сочетается с вашим «Не нужно БД этим вообще напрягать»? Структура хранится в БД. Чистить кэш можно к примеру при любых изменениях таблицы категорий.

Домены и скрипт для коротких ссылок: https://u75.ru/domains-for-shortcuts
ДП
На сайте с 23.11.2009
Offline
203
#10
logamagoga:
Термин "инвалидация кэша" вам о чем нибудь говорит?

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

12

Авторизуйтесь или зарегистрируйтесь, чтобы оставить комментарий