Я не могу ответить на вопрос, когда использовать хранилище данных ключ-значение (здесь kv), но я могу показать вам некоторые примеры и ответить на ваш пример stackoverflow.
С доступом к базе данных, большинство из того, что вам нужно, это kv store. Например, пользователь входит в систему с именем пользователя "joe". Итак, вы ищете «user: joe» в своей базе данных и получаете его пароль (конечно, хеш). Или, может быть, у вас есть его пароль в разделе «user: pass: joe», это действительно не имеет значения. Если бы это было переполнение стека, и вы рендерили страницу /5626196/kogda-ispolzovat-hranilische-klychei-dlya-veb-razrabotki
, вы бы посмотрели «вопрос: 6935566» и использовали его. Просто увидеть, как kv store может решить большинство ваших проблем.
Я бы хотел сказать, что kv store - это подмножество функций, предоставляемых традиционной RDMS. Это связано с тем, что дизайн традиционной RDMS предоставляет множество проблем с масштабированием и, как правило, теряет функции при масштабировании. KV-магазины не поставляются с этими функциями, поэтому они не ограничивают вас. Однако эти функции часто могут быть созданы в любом случае, спроектированы с учетом масштабируемости ядра (потому что это сразу становится очевидным, если это не так).
Однако это не значит, что есть вещи, которые вы не можете сделать. Например, вы упоминаете запрос. Это ловушка многих магазинов кв, так как они, как правило, не имеют значения (не всегда верно, например, redis и т. Д.) И не могут найти то, что вы ищете. Хуже того, они не предназначены для такой быстрой работы, они просто очень быстро ищут ключ.
Одним из решений этой проблемы является лексикографическая сортировка ключей и разрешение запросов по диапазону. По сути, это «дай мне все между вопросом 1 и вопросом 5». Теперь этот пример довольно бесполезен, но есть много вариантов использования запросов диапазона.
Вы сказали, что хотите, чтобы все дома стоили более 100 000 долларов. Если вы хотите сделать это, вы должны создать индекс домов по цене. Скажем, у вас были следующие дома.
house:0 -> {"color":"blue","sold":false,"city":"Stackoverville","price":500000}
house:1 -> {"color":"red","sold":true,"city":"Toronto","price":150000}
house:2 -> {"color":"beige","sold":false,"city":"Toronto","price":40000}
house:3 -> {"color":"blue","sold":false,"city":"The Blogosphere","price":110000}
В SQL вы должны хранить каждое поле в столбце, а не хранить все это в одном (в данном случае JSON) документе. И мог SELECT * FROM houses WHERE price > 100000
. Кажется, все хорошо, но, если индекс не построен, для этого необходимо просмотреть каждый дом в вашей таблице и проверить его цену, что, если у вас есть пара миллионов домов, может быть медленным. Так что для магазина kv вам нужен индекс. Основное отличие состоит в том, что база данных SQL будет тихо делать медленную вещь, когда хранилище kv не сможет.
Если у вас нет запросов диапазона, вам нужно будет вставить свой индекс в один документ, что затрудняет его безопасное обновление и означает, что вам придется загружать весь индекс для каждого запроса, опять же, ограничивая масштабируемость.
house:index:price -> [{"price":500000,"id":"0"},{"price":150000,"id":"1"},{"price":110000,"id":"3"},{"price":40000,"id":"2"}]
Но если у вас есть запросы диапазона (часто называемые сканированием ключей), вы можете создать такой индекс:
house:index:price:040000 -> 2
house:index:price:110000 -> 3
house:index:price:150000 -> 1
house:index:price:500000 -> 0
И затем вы можете запросить ключи от house:index:price:100000
до house:index:price::
(символ ':' - это символ после '9'), и вы получите [3,1,0]
, что на все дома дороже, чем $ 100 000 ( они тоже в порядке в порядке). Еще одна приятная вещь в этом - это то, что они, вероятно, будут находиться в одном «разделе» вашего кластера, поэтому этот запрос займет примерно то же время, что и одиночное получение (плюс крошечные дополнительные издержки передачи), или два получения, если ваш диапазон окажется выше граница сервера (но это может быть сделано параллельно!).
Итак, это показывает, как выполнять запросы в хранилище kv. Вы можете запросить все, что можно упорядочить в виде строки (почти все), и быстро найти его. Если у вас нет запросов диапазона, вам нужно хранить весь индекс под одним ключом, который отстой, но если у вас есть запросы диапазона, это очень удобно и очень быстро. Вот более сложный пример.
Я хочу непроданные дома в Торонто стоимостью менее 100 000 долларов. Мне просто нужно спроектировать свой индекс.(Я добавил пару домов, чтобы сделать их более значимыми). Сначала вы подумали, что вы можете просто создать другой индекс для каждого свойства, но вы быстро поймете, что это означает, что вам нужно выбрать каждый непроданный дом и загрузить его из базы данных.(Это то, что я имел в виду, когда говорил, что проблемы масштабирования сразу очевидны.) Решение заключается в использовании мультииндекса.После сборки вы можете выбрать именно те значения, которые вам нужны.
house:index:sold:city:price:f~Fooville~000010:5 -> ""
house:index:sold:city:price:f~Toronto~040000:2 -> ""
house:index:sold:city:price:f~Toronto~140000:4 -> ""
house:index:sold:city:price:t~Stackoverville~500000:0 -> ""
house:index:sold:city:price:t~The Blogosphere~110000:3 -> ""
house:index:sold:city:price:t~Toronto~150000:1 -> ""
Теперь, в отличие от последнего примера, я вставил идентификатор в ключ.Это позволяет двум домам иметь одинаковые свойства.Я мог бы объединить их в значение, но тогда добавление удаления индексов становится более сложным.Я также решил разделить мои данные с ~
.Это потому, что это лексикографически после всех букв, гарантируя, что полное имя будет отсортировано, и мне не нужно дополнять каждый город одинаковой длины.В производственной системе я бы, вероятно, использовал байт 255 или 0.
Теперь диапазон house:index:sold:city:price:f~Toronto~100000
- house:index:sold:city:price:f~Toronto~~
выберет все дома, которые соответствуют запросу.И важно отметить, что запрос масштабируется линейно с количеством результатов.Это означает, что вам нужно создать индекс для каждого набора свойств, которые вы хотите индексировать (хотя индекс в нашем примере также работает для запросов на продажу и проданный город).Это может показаться большой работой, но, в конце концов, вы понимаете, что вы делаете это, а не ваша база данных.Я уверен, что скоро мы увидим библиотеки для подобных вещей: D
Немного расширив тему, я показал:
- Некоторые варианты использованияkv store.
- Как выполнять запросы в kv store.
Я думаю, вы обнаружите, что kv-store достаточно для многих приложений и часто может обеспечить лучшую производительность и доступностьчем традиционные RDMS.При этом каждое приложение уникально, и поэтому невозможно ответить на оригинальный вопрос.