MongoDB
 sql >> база данни >  >> NoSQL >> MongoDB

Redis или Mongo за определяне дали дадено число попада в диапазони?

Противно на предишния плакат, не мисля, че можете да получите O(log n) сложност, като използвате наивно индексиране. Нека разгледаме mongodb например. Можете да дефинирате два индекса (за начални и крайни свойства на диапазоните), но mongodb ще използва само един за решаване на дадена заявка. Така че няма да работи. Сега, ако използвате единичен съставен индекс, включващ както началните, така и крайните свойства на диапазоните, сложността ще бъде логаритмична за намиране на първия диапазон за проверка, но след това ще стане линеен за намиране на последния диапазон, съответстващ на заявката. Сложността в най-лошия случай е O(n) и я имате, когато всички съхранени диапазони се припокриват във вашия вход.

От друга страна, с помощта на сортиран набор на Redis можете да емулирате сортиран индекс (с O(log n) сложност), ако знаете какво правите. Redis е малко повече от просто хранилище на ключ-стойност. Сортираните набори на Redis се реализират с помощта на списък за пропускане и както резултатът, така и стойността се използват за сравняване на елементи.

За решаването на този вид проблем е необходима специална структура за индексиране. Може да искате да разгледате:

http://en.wikipedia.org/wiki/Segment_treeorhttp://en.wikipedia.org/wiki/Interval_tree

Ако проблемът е скоростта над пространството, тогава може да е интересно да изравним индекса. Например, нека разгледаме следните диапазони (използвайки само цели числа, за да опростим дискусията):

A 2-8
B 4-6
C 2-9
D 7-10

Може да се изгради рядка структура, индексираща неприпокриващи се сегменти.

0  []
2  [A C]
4  [A C B]
7  [A C D]
9  [C D]
10 [D]
11 []

Всеки запис съдържа долната граница на незастъпващ се сегмент като ключ и списъка или набора от съвпадащи диапазони като стойност. Записите трябва да бъдат индексирани с помощта на сортиран контейнер (дърво, списък за пропускане, btree и т.н. ...)

За да намерим диапазоните, съответстващи на 5, търсим първия запис, който е по-нисък или равен на 5 (в този пример ще бъде 4) и се предоставя списък с диапазони ( [A C B] )

С тази структура от данни сложността на заявките наистина е O(log n). Въпреки това не е тривиално (и скъпо) да го изградите и поддържате. Може да се реализира както с mongodb, така и с Redis.

Ето пример с Redis:

> rpush range:2 2-8 2-9
(integer) 2
> rpush range:4 2-8 2-9 4-6
(integer) 3
> rpush range:7 2-8 2-9 7-10
(integer) 3
> rpush range:9 2-9 7-10
(integer) 2
> rpush range:10 7-10
(integer) 1
> zadd range_index 0 range:0 2 range:2 4 range:4 7 range:7 9 range:9 10 range:10
(integer) 6
> zrevrangebyscore range_index 5 0 LIMIT 0 1
1) "range:4"
> lrange range:4 0 -1
1) "2-8"
2) "2-9"
3) "4-6"


  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Вложен масив $pull заявка с помощта на C# MongoDB драйвер

  2. mongoDB/mongoose:уникален, ако не е нула

  3. Подобрения в MongoDB 2.6 Aggregation Framework

  4. Какъв е правилният начин за индексиране в MongoDB, когато съществува голяма комбинация от полета

  5. Вмъкване и запитване на дата с MongoDB и Nodejs