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

Я использую Mnesia с Erlang, но этот вопрос относится к любому db со значением ключа, например couchdb и т. Д.

Я пытаюсь освободиться от мыслительного процесса СУРБД, но не могу Обдумайте, как эффективно реализовать такую ​​схему.

Скажем, у меня есть запись пользователя, и у него много записей SubItemA, которая имеет много записей подэлемента B, поэтому:

User
-SubItem A
--SubItem B
...

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

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

Ответы [ 4 ]

3 голосов
/ 03 марта 2009

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

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

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

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

1 голос
/ 04 марта 2009

Я не уверен насчет 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)
        }
    }
}

Это фактически индексированный список подэлементов B, и вы можете вырезать и склеивать его из списка по своему усмотрению.

1 голос
/ 04 марта 2009

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

0 голосов
/ 08 мая 2009

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

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

...