Redis насколько верна такая реализация меню?

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

Создание пунктов в меню выглядит следующим образом:

  1. Создаю пункты меню:

    HMSET menu_item:1 menu_title Главное меню

    HMSET menu_item:2 menu_title Мой профиль

    HMSET menu_item:3 menu_title Моя статистика

  2. Указываю каждому меню, кто его "родитель" (он всегда 1)

    SADD menu_item:1:parent 0

    SADD menu_item:2:parent 1

    SADD menu_item:3:parent 2

  3. Указываю пунктам меню, кто его "дети", если такие есть (их может быть несколько)

    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 шт):

Автор решения: Mike

Предлагаю сериализовать все пункты одного раздела меню в один ключ 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}
]}
→ Ссылка