Обычный способ моделирования отношений «основной-подробности» в Riak — сделать так, чтобы основная запись содержала список идентификаторов записей подробностей, возможно, вместе с некоторой информацией о записи подробностей, которая может быть полезна при принятии решения о том, какие записи подробностей нужно извлечь.
В вашем примере у вас может быть два ведра с именами «книги» и «страницы». Основная запись в сегменте «книги» будет содержать метаданные и информацию о книге в целом, а также список страниц, включенных в книгу. Каждая страница будет содержать идентификатор записи «страницы», содержащей данные страницы, а также соответствующий номер страницы. Если вы, например. хотите иметь возможность запрашивать по главам, вы также можете добавить информацию о том, к каким главам принадлежит определенная страница.
Ведро «страницы» будет содержать текст страницы и, возможно, ссылки на изображения и другие мультимедийные данные, которые включены на эту страницу. Эти данные могут быть сохранены в еще одном сегменте.
Чтобы получить конкретную страницу или диапазон страниц, нужно сначала извлечь основную запись из корзины «книги», а затем на основе содержимого записи — соответствующие страницы. Несмотря на то, что для этого требуется несколько операций GET, все они представляют собой прямой поиск на основе ключей, что является наиболее эффективным и масштабируемым способом извлечения данных из Riak, поэтому он будет работать и масштабироваться хорошо.
Этот подход также упрощает изменение порядка страниц и/или глав, поскольку необходимо обновить только основную запись. Однако добавление, удаление или изменение страниц потребует обновления, добавления или удаления основной записи, а также одной или нескольких подробных записей.
Вы, безусловно, также можете решить эту проблему, добавив вторичные индексы к объектам и запросив их на основе этого. Однако запросы вторичного индекса в Riak должны включать обработку покрывающего набора (обычно размер кольца / n_val) разделов, чтобы выполнить запрос, и, следовательно, создают немного большую нагрузку на систему и, как правило, приводят к более высоким задержкам, чем получение один объект, содержащий ключи, посредством прямого поиска ключа (который должен включать только разделы, в которых фактически хранится объект).
Хотя поддержка отдельного объекта, содержащего индексы, добавляет немного дополнительной работы при вставке или удалении страниц/записей, этот подход обычно приводит к более эффективному чтению, поскольку требуется только прямой поиск по ключу. Если ваше приложение интенсивно читает, вероятно, имеет смысл использовать этот подход, в то время как вторичные индексы могут быть более эффективными для приложения с интенсивной записью, поскольку вставки и модификации удешевляются за счет более дорогих операций чтения. Однако вы всегда можете добавить вторичные индексы на всякий случай, чтобы ваши варианты оставались открытыми.
В таких случаях я обычно рекомендую выполнить некоторые тесты, чтобы протестировать решения и проверить, какое решение лучше всего соответствует вашим конкретным требованиям к производительности и масштабированию.
person
Christian Dahlqvist
schedule
23.03.2013