Можно ли хранить целочисленные ключи/значения в LevelDB?

Я искал хранилища значений ключей, которые поддерживают целые ключи и целые значения. LevelDB кажется хорошим вариантом, хотя я не могу найти информацию о том, поддерживаются ли целочисленные значения/ключи.


person Rosh Cherian    schedule 10.01.2012    source источник


Ответы (4)


В LevelDB можно хранить практически все что угодно. Вы предоставляете непрозрачные фрагменты данных в LevelDB через Slice. Вот пример:

int intKey = 256;
int intValue = 256*256;

Slice key((char*)&intKey, sizeof(int));
Slice value((char*)&intValue, sizeof(int));

db->Put(leveldb::WriteOptions(), key, value);

И это почти все!

Однако следует отметить, что, хотя обычно можно хранить целые числа в LevelDB (как ключи, так и значения), они будут упорядочены через BytewiseComparator, поэтому ваш ключ должен поддерживать побайтовое сравнение. Это также означает, что если вы полагаетесь на определенный порядок ключей, вы должны помнить о порядке следования байтов в системе.

Вы также можете написать собственный компаратор через интерфейс Comparator. что позволит вам заменить BytewiseComparator по умолчанию.

person Kiril    schedule 23.01.2012
comment
Но Get не дает мне слайс, верно? Если данные не заполнены «0», как это будет работать? Или я что-то здесь упускаю? - person vinothkr; 16.10.2013
comment
Get возвращает std::string, который может содержать произвольный массив байтов. Вы также можете использовать итератор и выполнять поиск с его помощью, чтобы иметь возможность получить срез, указывающий на значение, без какого-либо копирования. Это рекомендуемый подход для очень больших значений. - person Andy Dent; 11.12.2013

Во многих случаях лучше выбрать более сложную схему кодирования целочисленных ключей. Одним из вариантов является упаковка int в его представление с двумя дополнениями в char* (как предлагается в другом ответе на этот вопрос); Кодировка varint — еще одна (экономит место для небольших целых чисел, может хранить произвольные числа без верхней границы).

person wouter bolsterlee    schedule 10.12.2012
comment
Разве varint не является оптимизацией метода двух дополнений? - person amirouche; 22.08.2015
comment
нет. varints (у которых есть несколько вариантов) используют переменный размер, а числа с двумя дополнениями используют фиксированный размер. это означает, что варинты теоретически не ограничены (но не в практической реализации), в то время как числа с двумя дополнениями имеют диапазон от -2 ^ n до 2 ^ n-1. кроме того, варинты нуждаются в зигзагообразном кодировании для отрицательных чисел, в то время как 2 дополнения резервируют для этого бит знака. - person wouter bolsterlee; 25.08.2015

Чтобы расширить ответ Линка, отчасти потому, что я только что играл именно с этой вещью в рамках книги, которую я пишу, вы можете увидеть результаты BytewiseComparator, о которых он / она говорит ниже.

Другой подход состоит в том, чтобы преобразовать ваши двоичные целые числа в формат с обратным порядком байтов, чтобы они нормально сортировались с помощью компаратора по умолчанию. Это облегчает составление ключей. long flippedI = htonl(i);

Обратите внимание, что LevelDB работает очень быстро. Я провел тесты на iPhone4 с 50 000 записей с текстовыми ключами и вторичными ключами, то есть около 100 000 пар ключ/значение, и все заработало.

Очень легко написать собственный компаратор, который будет использоваться вашей базой данных навсегда и по-прежнему будет использовать ByteWiseComparator для ключей, отличных от ваших чисел. Самая большая проблема заключается в том, чтобы решить, какие ключи покрываются вашими пользовательскими правилами, а какие нет.

Тривиальным способом было бы сказать, что все нецелочисленные ключи имеют длину более 4 символов, поэтому вы предполагаете, что 4-байтовый ключ является целым числом. Это означает, что вам просто нужно убедиться, что вы добавили конечные пробелы или что-то еще, чтобы подтолкнуть это. Все это очень произвольно и зависит от вас, но помните, что у вас есть только две части информации: ключевое содержание и его длина. Для данного ключа нет других метаданных.

Часть результатов образца для стандартного компаратора с ключами int, начинающимися с 1 и возрастающими от 1 до 1000, с использованием базы данных со стандартным BytewiseComparator

Listing the keys in decimal and hex
 256 ( 100)
 512 ( 200)
 768 ( 300)
   1 (   1)
 257 ( 101)
 513 ( 201)
 769 ( 301)
   2 (   2)
 258 ( 102)
 514 ( 202)
 770 ( 302)
   3 (   3)
 259 ( 103)
 515 ( 203)
 771 ( 303)
...
 254 (  fe)
 510 ( 1fe)
 766 ( 2fe)
 255 (  ff)
 511 ( 1ff)
 767 ( 2ff)
person Andy Dent    schedule 13.08.2013
comment
Вы имеете в виду перевернуть в порядке с обратным порядком байтов, а не с прямым порядком байтов. Вы использовали htonl в своем примере, что означает, что хост-сетевой и сетевой порядок байтов имеют обратный порядок байтов. LevelDB может быть быстрым по сравнению с другими старыми базами данных, но он довольно медленный по сравнению с LMDB. - person hyc; 10.12.2013

LMDB имеет явную поддержку целочисленных ключей (и значений, если вы используете отсортированные дубликаты). http://symas.com/mdb

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

Отказ от ответственности: я являюсь автором LMDB. Конечно, это не меняет фактов.

person hyc    schedule 09.12.2013
comment
Вопрос был про LevelDB. Пожалуйста, прекратите спамить другими вопросами, пытаясь продвигать LMDB. - person Andy Dent; 10.12.2013
comment
В вопросе говорится, что я искал, что означает, что он все еще ищет варианты. И LevelDB — это доказуемо худший вариант, а LMDB — доказуемо лучший вариант. - person hyc; 12.12.2013
comment
@hyc, это скорее зависит от ваших требований. Я только что просмотрел LMDB и обнаружил, что он совершенно не подходит, но похоже, что LevelDB делает именно то, что мне нужно. - person Alnitak; 27.01.2015
comment
Конечно, зависит от ваших требований - это справедливое утверждение. Большинство людей, использующих базу данных, должны надежно извлекать данные, которые ранее хранились в качестве требования. Они также требуют, чтобы данные хранились с предсказуемой задержкой. LevelDB терпит неудачу по обоим пунктам. usenix.org/conference/osdi14/technical-sessions/presentation/ riak-users.197444.n3. nabble.com/ Таким образом, если вы не пишете еще одно хранилище данных с потерями, такое как MongoDB, где вы на самом деле не заботитесь о извлечении своих данных, LevelDB, как правило, не подходит в качестве хранилища ключ-значение. - person hyc; 29.01.2015
comment
Было бы вежливо раскрыть вашу роль в развитии LMDB, говоря как человек, ищущий мои варианты. - person Michael Theriot; 23.08.2016
comment
Добавлен отказ от ответственности. Я добавлял его в разные посты, но не использовал последовательно во всех постах. Тем не менее, факты есть факты: twitter.com/brokencodebot/status/723504249037008896 - person hyc; 25.08.2016