Отличный вопрос - нужен подробный ответ, но позвольте мне кратко изложить концепцию за счет полной точности.
1 - Первичный ключ в Aersopike - это строка / int / bytes, что бы вы ни выбрали -> хэшируется в 20 байтов клиентской библиотекой, к которой привязано ваше приложение. Эти 20 байт га sh являются «ключом», отправляемым на сервер и используемым сервером для обработки ваших данных записей. Таким образом, вы можете создать строковый ключ: «2020: san_jose: web», и любые данные, связанные с этим ключом, будут сохранены в Aerospike в виде записи. Вы можете сделать sendKey или даже сохранить свой ключ как другой строковый бин в записи. Но Aerospike использует для отслеживания вашей записи 20 байтов га sh из «2020: san_jose: web». Этот вид составного ключа не привязан неявно к бинам данных - вы явно создаете его в своем приложении. Этот метод может использоваться для чтения пакета записей, если вы можете «сгенерировать» эту строку (в своем приложении) для набора записей, которые вас интересуют, а затем использовать API пакетного чтения. Но вы не можете использовать данные в корзинах и сказать Aerospike «сгенерировать» этот ключ для вас, найти подходящие записи и вернуть их.
2 - Можно ли использовать вторичные индексы? В Aerospike вы можете создать до 256 SI, но использовать только один в данном запросе. (Я бы не советовал собирать больше, чем несколько, для оперативной памяти, а также для других эксплуатационных соображений.) Чем выше количество элементов в корзине, тем больше оперативной памяти вам потребуется. Индексы встроены в оперативную память - что имеет свои собственные операционные последствия - и t ie запрашивает хешированные ключи и, следовательно, записи-кандидаты. Итак, допустим, вы используете SI для city == "san_jose" - это даст подмножество записей. (Выберите SI, который отбирает данные до 15% от общего количества, в идеале - предложение.) Теперь это будет извлекать все записи, где мусорная корзина города соответствует san_jose. Это все в оперативной памяти - так что это быстро. После этого он будет читать все эти записи с диска и отправлять их обратно клиенту.
3 - На данном этапе у вас есть дополнительная возможность написать фильтры предикатов значительной сложности. Таким образом, вы можете сказать, что из этого найденного набора пришлите мне записи, где год = 2020 и источник = сеть ... все логические условия ИЛИ НЕ, которые вам нужны, regexes et c. (Я жертвую точностью, чтобы управлять большей точкой. Вы также можете запускать предопределенные фильтры для метаданных записи, которые происходят на уровне ОЗУ до того, как запись извлекается с диска.)
4 - Наконец, почему СИ не рекомендуется в распределенных базы данных? Они отлично работают, если кластер стабилен. Если узлы входят или выходят, данные переносятся для создания копий реплик - запрос SI выполняется параллельно с переносом данных - вы можете пропустить или получить дубликаты. Считайте запрос SI относительно «длительной» выполняемой операцией. В Aerospike, если вы убедитесь, что данные не мигрируют перед запуском запроса SI, есть необязательный флаг, который вы можете установить - failOnClusterChange - так что ваш запрос не будет выполнен (клиент получит информацию), если узел выпадет или присоединится во время активного Запрос СИ. В зависимости от вашей модели данных, вы можете или не можете заботиться о точности запроса SI на 100%.