Комментарии 17
Хм. А ведь это решение можно обобщить для всех баз данных, не только MongoDB…
0
уже: postgresql hstore + gis/gist
+1
Это какая-то технология, поддерживаемая СУБД?
Я-то говорил про модификацию схемы данных, что можно сделать независимо от используемой СУБД.
Я-то говорил про модификацию схемы данных, что можно сделать независимо от используемой СУБД.
0
такая схема называется «слабоструктурированные данные», под них и заточен hstore с индексами gis/gist.
0
Ну да, можно и в реляционной БД хранить данные в формате key-value, однако сразу огребаем проблемы с типами. Также, невозможно использовать внешние ключи и каскадные операции.
0
Да, с внешними ключами проблема, хотя про невозможность вы зря сказали — гибридную схему никто не отменял.
Про недостатки схемы key-value я давно знаю, а вот тот факт, что у такого способа есть еще и достоинства, я узнал только сейчас.
Впрочем, мне и поиск по всем полям раньше делать не доводилось.
Про недостатки схемы key-value я давно знаю, а вот тот факт, что у такого способа есть еще и достоинства, я узнал только сейчас.
Впрочем, мне и поиск по всем полям раньше делать не доводилось.
+1
> Для наглядности создадим миллион документов состоящих из фиктивных свойств
> for (var i = 0; i < 5000000; ++i)
И всё же миллион или пять миллионов?
> for (var i = 0; i < 5000000; ++i)
И всё же миллион или пять миллионов?
+1
Автор, явно не хватает зависимости времени вставки от варианта решения.
+4
Я не автор, это лишь мой ужасный перевод =) Но я воспроизводил эти примеры и попробовал сделать замер вставки после создания индексов:
P.S без индексов вставка была ~16к insert/s
Решение #1
![](https://habrastorage.org/r/w1560/storage2/7ac/453/3c1/7ac4533c15c2417611a83e1ff0b36762.png)
> beginTime=new Date();for(var i=0;i<1000000;++i){var arr=[];for(var j=0;j<10;++j){arr.push({n:"prop"+j,v:Math.floor(Math.random()*1000)})}db.generic.insert({props:arr})}print((new Date()).getTime()-this.beginTime.getTime());
531189
![](https://habrastorage.org/storage2/7ac/453/3c1/7ac4533c15c2417611a83e1ff0b36762.png)
Решение #2
![](https://habrastorage.org/r/w1560/storage2/485/192/650/485192650865f26017eeae713838ba9a.png)
> beginTime=new Date();for(var i=0;i<1000000;++i){var arr=[];for(var j=0;j<10;++j){var doc={};doc["prop"+j]=Math.floor(Math.random()*1000);arr.push(doc)}db.generic2.insert({props:arr})}print((new Date()).getTime()-this.beginTime.getTime());
532890
![](https://habrastorage.org/storage2/485/192/650/485192650865f26017eeae713838ba9a.png)
P.S без индексов вставка была ~16к insert/s
0
Делал нечто похожее. Только я склеивал ключ и значение. Например: prop0-40, prop1-198. Ваше решение конечно более гибкое, т.к. даёт возможность искать в том числе и по диапазоном, а моё работает только на сравнение.
0
А теперь создадим в 10 раз больше документов и всё равно получаем индекс, не влазящий в оперативную память. А на FreeBSD это гарантированный крэш, даже не торможение.
0
Хм, а почему на FreeBSD индекс, не влазящий в оперативную память, приведет к крэшу?
0
Отлично! Решил после этого поста обновить mongodb и переписать поиск по таблице с пользователями
0
Правильно ли я понимаю что в первом варианте нельзя сделать сортировку, а во втором варианте возможен поиск только по одному полю?
0
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
MongoDB: слишком много полей для индексации? Используйте общий индекс