Redis насколько верна такая реализация меню?
Сейчас храню меню в Redis, каждый пункт меню представляет из себя отдельную запись. Каждый пункт меню связан со своим родителем (1 к 1) и дочерними меню (1 ко многим).
Создание пунктов в меню выглядит следующим образом:
Создаю пункты меню:
HMSET menu_item:1 menu_title Главное меню
HMSET menu_item:2 menu_title Мой профиль
HMSET menu_item:3 menu_title Моя статистика
Указываю каждому меню, кто его "родитель" (он всегда 1)
SADD menu_item:1:parent 0
SADD menu_item:2:parent 1
SADD menu_item:3:parent 2
Указываю пунктам меню, кто его "дети", если такие есть (их может быть несколько)
SADD menu_item:1:childs 2
SADD menu_item:2:childs 3
Проблема с которой я столкнулся пользуясь такой структурой:
Когда я хочу отобразить пользователю меню, то мне нужно получить все пункты меню у которых родитель == номеру текущего пункта меню пользователя.
Для этого я я получаю "детей" текущего меню с помощью SMEMBERS menu_item:1:childs, который возвращает например {'4','2','6'} и после я вынужден создавать pipeline и внутри, в цикле брать каждого из этих детей по очереди с помощью HGETALL, после чего еще и сортировать силами языка программирования python получившийся массив (у каждого пункта меню свой порядок).
Вопрос Правильно ли я вообще реализовал меню и есть ли способ сделать это лучше, например как-то избежав цикла в pipeline, где приходиться выбирать каждый элемент по очереди? По факту, мне нужно часто выполнять следующий запрос к хранилищу (приведу пример на SQL)
Как бы я получал детей определенного пункта меню в SQL бд:
1) SELECT * FROM `menu_items` WHERE `parent_id` = 1 ORDER BY `position` ASC
Ответы (1 шт):
Предлагаю сериализовать все пункты одного раздела меню в один ключ redis в виде json или чего то подобного. Сам ключ содержит id раздела меню, который описывает. Описание каждого пункта меню в массиве содержит его id и наименование, что позволяет сразу выводить все разделы, не обращаясь за наименованиями в другие ключи redis. В описании элемента меню, помимо входящих в него пунктов стоит добавить id родительского элемента, это упростит задачу редактирования наименования самого элемента, поскольку оно описано в родителе. Пример хранения вышеописанным способом:
key menu_item-0 => { menu: [
{ name: "Меню1", id: 2 },
{ name: "Меню2", id: 3 }
]}
key menu_item-2 => { parent: 0, menu: [
{ name: "Элемент 1-1 (субменю)", id: 4 },
{ name: "Элемент 1-2", id: 5}
]}
key menu_item-3 => { parent: 0, menu: [ .... ]}
key menu_item-4 => { parent: 2, menu: [
{ name: "Элемент 1-1-1", id: 10 },
{ name: "Элемент 1-1-2", id: 11}
]}