Хранение иерархии каталогов в хранилище данных ключ-значение - PullRequest
36 голосов
/ 25 октября 2009

Что такое чистый / эффективный метод хранения иерархии каталогов / дерева в базе данных Key-Value (в моем случае MongoDB, но любой из них)?

Например, древовидная структура

- Cars 
   + Audi 
   + BMW
      - M5
   + Ford
- Color
   + Red
      - Apple
      - Cherry
   + Purple
- Funny

Метод, который я использую сейчас, каждый объект ссылается на своего родителя

{ 
  dir: "red"
  parent-dir: "color"
}

Это позволяет очень эффективно / быстро вставлять и изменять порядок любого аспекта дерева (например, если я хочу переместить красный и все его дочерние элементы в каталог Cars).

Но этот метод отстой, когда я хочу, чтобы все подкаталоги и их дочерние элементы были заданы рекурсивно. Чтобы сделать его более эффективным, я могу иметь структуру, например,

{ 
  dir: "red"
  children: "audi, bmw, ford"
}

{ 
  dir: "bmw"
  children: "m5"
}

Но если я хочу изменить дерево, нужно коснуться и изменить целую кучу объектов.

Существуют ли другие способы хранения структуры каталогов в хранилище KV?

Ответы [ 4 ]

58 голосов
/ 14 декабря 2009

Метод, который вы сейчас используете, называется модель списка смежностей .

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

Очень простой метод: вы можете хранить путь для каждого объекта - для них должно быть легко запрашивать деревья в базах данных NOSQL:

{ path: "Color", ... }
{ path: "Color.Red", ... }
{ path: "Color.Red.Apple", ... }
{ path: "Color.Red.Cherry", ... }

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

редактировать: этот метод называется материализованный путь

Наконец, вот сравнение различных методов для иерархических данных в базах данных NOSQL .

1 голос
/ 02 ноября 2009

У меня нет большого опыта работы с NOSQL, так что это не окончательный ответ, но вот как я к нему подхожу:

Я бы, вероятно, использовал ваш первый подход, где у вас есть:

{
  dir: 'dir_name',
  parent_dir: 'parent_dir_name'
}

А затем настройте map-lower для быстрого запроса дочерних элементов каталога. Функциональность MongoDB для уменьшения карты все еще доступна только в ветви разработки, и я еще не работал с ней, но в CouchDB (и я предполагаю, с небольшой модификацией в MongoDB) вы можете сделать что-то вроде:

map:
function(doc) {
  emit( doc.parent_dir, doc.dir );
}

reduce:
function(key, values) {
  return( values );
}

Что даст вам список подкаталогов для каждого родительского каталога.

0 голосов
/ 17 декабря 2009

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

например

{ "id:xxx", "id:yyy", "sub-heap-id:zzz"....}

Если это не ясно, оставьте комментарий, и я объясню больше, когда вернусь домой.

0 голосов
/ 16 декабря 2009

Сделайте индекс!

http://www.mongodb.org/display/DOCS/Indexes

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...