Как вы разрабатываете схему для эффективного запроса вложенных элементов в базе данных ключ-значение?

StackOverflow https://stackoverflow.com/questions/607746

Вопрос

Я использую Mnesia с Erlang, но этот вопрос применим к любой базе данных типа ключ-значение, такой как couchdb и т.д.

Я пытаюсь освободиться от мыслительного процесса RDBMS, но я не могу понять, как эффективно реализовать такую схему.

Допустим, у меня есть запись пользователя, и у него есть много записей подпункта, в котором есть много записей подпункта B, так что:

User
-SubItem A
--SubItem B
...

Мне нужно выполнить запросы по подпункту B.Эффективно ли это делать, когда это это вложенное?Должен ли я просто нормализовать это, чтобы это было быстрее?

Я слышал о некоторых людях, использующих дублирование данных, поэтому данные являются одновременно вложенными и отдельными, это смешно или это действительно полезно в некоторых случаях?

Это было полезно?

Решение

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

Сканирование таблиц пользовательского словаря не требует чрезмерных затрат, если вам действительно нужно детально изучить каждый подпункт B, а размер B доминирует над общим размером словаря.

Если этого недостаточно, нормализуйте его, чтобы вы могли избежать предварительного чтения всех данных пользователя и подпункта A при запросе подпункта B.Используйте составной ключ, такой как (userId, SubItemAId, SubItemBId) в словаре SubItem B, если таблица упорядочена, чтобы вы могли выполнять запросы диапазона.

Если это полностью снижает производительность вашего запроса User / SubItem A, то рассмотрите дублирование данных в качестве последнего средства, поскольку оно более подвержено ошибкам.

Другие советы

В CouchDB было бы тривиально создавать записи view для каждого из подпунктов.Это дало бы вам очень быстрый доступ к этим элементам.В зависимости от того, что вы также добавляете в записи просмотра, вы, вероятно, могли бы предоставить любую информацию, необходимую для обратной ссылки на родительские документы / подпункты.

Я не уверен насчет Mnesia, и я только начинаю работать с CouchDB, но я понимаю, что в CouchDB, поскольку вы создаете свои собственные пользовательские индексы ("представления"), вы можете прямолинейно создавать индекс для этих подпунктов.

Пример функции отображения:

function(doc) {
    for(var i in doc.subitems_a) {
        var subitem_a = doc.subitems_a[i];

        for(var j in doc.subitems_a[item_a].subitems_b) {
            var subitem_b = subitem_a.subitems_b[j];

            emit(subitem_b, doc)
        }
    }
}

Фактически это индексированный список подпунктов Bs, и затем вы можете вырезать и соединять из этого списка по своему выбору.

На самом деле, я думаю, это зависит от базы данных, которую вы используете.В CouchDB одна вещь будет работать лучше, в то время как в Mnesia что-то другое было бы лучше.Следует ли вам разбивать данные на разделы и сегментировать их?По каким критериям вы должны это делать?Насколько большого дублирования данных достаточно?

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top