Уведомления

Группа в Telegram: @pythonsu

#1 Дек. 3, 2011 19:05:20

Lexander
От:
Зарегистрирован: 2008-09-19
Сообщения: 1139
Репутация: +  33  -
Профиль   Отправить e-mail  

MongoDB и несколько коллекций.

blessmaster
Какбэ необходимость требует по зависимости возможность.
Я не понял смысла этой фразы. Вы подтверждаете мое высказывание, но почему то делаете это в опровергающем стиле.
blessmaster
Какое отношение это имеет к реляционности как качеству БД?
Никакого. Нельзя использовать методы (и их наличие или отсутствие) работы с реляционными БД (объединение таблиц в запросе) для оценки качества объектных.
blessmaster
Каким образом? Что технически ускоряет? Я пока вижу только один фактор - данные одного типа более разрежены, что при чтении требует обращение к большему числу дисковых страниц (вероятность найти соседние записи на одной дисковой странице - ниже).
Для реляционных СУБД, на примере MS SQL Server.
Использование в запросе кластерного индекса, размещенного физически рядом с данными, используемыми в этом же запросе позволяет считать индекс и данные одним махом.
Аналогом сложного объекта в реляционных БД является несколько таблиц. И чем больше таблиц в запросе, тем больше дисковых страниц нужно считать и тем больше будет обращений к дисковой подсистеме. Для СУБД, не работающих в режиме readonly, это оборачивается необходимостью работать дискам в самом медленном режиме - случайного доступа к данным.

Вернемся к ОБД.
Т.к. дисковая подсистема пишет данные постранично (страница при этом достаточно большая - 4кБ по-умолчанию для большинства аппаратных решений), данные объектной БД в одной коллекции будут записаны на диск “рядышком”, в пределах одной страницы.
Для нескольких коллекций вероятность этого существенно меньше. Например, авторы и их сообщения прирастают разными темпами.
blessmaster
О рекомендуемых случаях применения, я бы не против узнать. В данном топике рассматривается один из случаев, когда рекомендуется попробовать.
Как я писал выше, это
- скорость разработки/поддержки при достаточном уровне производительности,
- реализация функционала, недоступного для встроенного языка запросов.
Для п.2. есть разумная граница применения. Это не должен быть костыль, который закрывает недоработки/недостатки архитектуры/структуры.
blessmaster
JavaScript, если я верно понял то, что прочитал о Монго, - блокирующая часть для всей базы, в отличие от хранимых процедур и вероятно, от реализаций map/reduce в других базах, поправьте, если ошибаюсь.
Уточню только по поводу отличия ХП.
Сложная бизнес-логика в одной транзации (а не только в одной ХП) может блокировать множество таблиц на время этой самой транзакции.

Таким образом, отличие сводится только к способу уменьшения времени блокировки. В Монго - горизонтальное аппаратное масштабирование.
Для небольших БД скорость map/reduce не будет иметь существенного влияния.
Для больших БД возникает необходимость создавать шарды, что автоматически будет обозначать распараллеливание map/reduce.
И наоборот, если есть критичный и часто используемый код map/reduce, то для ускорения используется аппаратный способ (кстати, достаточно дешевый) увеличения производительности - шардинг.
blessmaster
Как, говорится, “знал бы где упадёшь, - соломки б подстелил”.
Я вполне допускаю, что описанная автором ситуация могла возникнуть вследствие внезапно изменившихся требований.
Тогда изменить структуру БД (объединить коллекции) будет не только допустимым, но и оправданным, разумным решением.

Единожды проведенный рефакторинг для изменения запросов наверняка повлечет за собой меньше проблем в будущем по сравнению с постепенным замедлением map/reduce.
И то, если мое предположение о возможности использования map/reduce для объединения запросов 2-х коллекций вообще будет работать.



Офлайн

#2 Дек. 3, 2011 20:35:06

o7412369815963
От:
Зарегистрирован: 2009-06-17
Сообщения: 1986
Репутация: +  32  -
Профиль   Отправить e-mail  

MongoDB и несколько коллекций.

Lexander
blessmaster
О рекомендуемых случаях применения, я бы не против узнать. В данном топике рассматривается один из случаев, когда рекомендуется попробовать.
Как я писал выше, это
- скорость разработки/поддержки при достаточном уровне производительности,
- реализация функционала, недоступного для встроенного языка запросов.
Для п.2. есть разумная граница применения. Это не должен быть костыль, который закрывает недоработки/недостатки архитектуры/структуры.
кстати п.1 очень важен, ещё дополню:
- хорошие возможности недоступные в реляцБД, например работа с массивами - мега. фича.

Офлайн

#3 Дек. 4, 2011 15:38:51

blessmaster
От:
Зарегистрирован: 2010-12-07
Сообщения: 15
Репутация: +  0  -
Профиль   Отправить e-mail  

MongoDB и несколько коллекций.

Lexander
Вы подтверждаете мое высказывание, но почему то делаете это в опровергающем стиле
Разве в моей фразе есть опровержение? Всего лишь утверждение, что необходимость никуда не девается от отсутствия возможности. Опровергается другое подразумевающееся утверждение, что раз не равно, то значит и не надо.

Более того, Монго позволяет создавать не просто много коллекций, монго их ещё позволяет группировать иерархически - то есть такой богатый инструмент по разнесению данных лишь для того, чтобы всё свалить в одну-две коллекции?

Lexander
Нельзя использовать методы (и их наличие или отсутствие) работы с реляционными БД (объединение таблиц в запросе) для оценки качества объектных.
В обсуждемом примере нет объединения таблиц. Есть объединение результирующего множества и необходимость провести по нему выборку и сортировку.
Хорошо, есть вообще какая-то ясно описанная граница для NoSQL, а ещё лучше Mongo, где метод доступа “реляционен”, а где - нет? Так-то делать - по-монговски, а так-то - реляционщина?

Lexander
И чем больше таблиц в запросе, тем больше дисковых страниц нужно считать и тем больше будет обращений к дисковой подсистеме.
Не буду цитировать полностью, можно прочитать в посте выше. Рассматривается абстрактная ситуация, когда каждая из таблиц будет полностью перечитываться при каждом запросе, что обычно неверно, не учитывается, что подобное разнесение по таблицам значительно снижает сам объём данных, который нужно анализировать (иначе подобное разнесение лишается смысла) и в итоге может оказаться, что придётся прочитать на порядки меньше, чем в сплошной денормализованной таблице. На практике одним из основных инструментов управления производительностью является возможность выбора между нормализацией и денормализацией.

Но хотелось бы избежать абстрактных споров, потому как лучший критерий - всегда экперимент. Допустим, мы делаем социальную сеть.
В этом разрезе мне интересно, каким образом правильно решается в Монго, такая ситуация: есть некое множество “люди” с рядом характеристик каждого элемента: пол, возраст, список интересов, ещё масса информации о самом человеке, что по объёму занимает порядка одной/двух дисковых страниц. Есть множества “фотографии”, “статьи”, у которых человек является владельцем или автором и на одного человека в среднем приходится несколько сотен таких ресурсов и это число растёт. Люди могут оставлять комментарии к чужим ресурсам и число таких комментариев у каждого человека тоже растёт. Есть группы пользователей, каждый человек может создать множество таких групп, в которые будет заносить своих друзей.
Теперь рассмотрим практические ситуации:
1. Человеку нужно показать последние сообщения и фотографии его друзей, участников его групп.
2. Нужно найти последние фото и статьи близких человеку по интересам людей
3. Мы проводим социологическое исследование и нас интересуют а) комментарии людей ассоциированных с какой-либо темой, а также б) комментарии людей близких первым людям.

1) Вариант с хранением полного профиля человека в каждой записи я отвергаю как невероятный из-за объёма данных, так и создающий огромную нагрузку на дисковую систему в случае малейшего редактирования профиля.
2) Есть DBRef, который назвать нереляционным язык не поворачивается, а в случае запроса - суть замаскированный джойн. Поэтому данный вариант никак не вписывается в Вашу модель.
3) Есть вариант с большим множеством запросов со стороны сервера приложений, но, во-первых, то же самое можно делать и с любой SQL базой, во-вторых, и что куда более существенно, это - изобретение велосипеда из второго пункта.

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

Есть ещё один вариант-предположение - для данной задачи Монго не подходящее решение, и его предназначение в несколько другой сфере, где он может дать существенный прирост? На данный момент я пока не компетентен делать такие утверждения, хотелось бы услышать мнение более опытных товарищей.

///////////////////////

По поводу JS, таки скажите: он действительно блокирует всю базу на время своего выполнения (не важно на какое время), либо несколько разных скриптов могут выполняться параллельно и при этом отрабатываться другие запросы (допустим, ядер для этого хватает, дисковая нагрузка балансируется)? Поскольку утверждение о блокировке может быть неверным/устаревшим, а как по английски спросить гугл, увы, не знаю. Уточню, речь не про шардинг, он лишь ускорит. Или для ускорения/распараллеливания шардинг можно/стоит сделать на одном хосте? О Монго вроде писали, что он сам умеет хорошо параллелиться.

o7412369815963
- хорошие возможности недоступные в реляцБД, например работа с массивами - мега. фича.
Не холивара ради, но это не для всех реляционных баз верное утверждение.



Отредактировано (Дек. 4, 2011 16:04:16)

Офлайн

#4 Дек. 4, 2011 16:23:15

blessmaster
От:
Зарегистрирован: 2010-12-07
Сообщения: 15
Репутация: +  0  -
Профиль   Отправить e-mail  

MongoDB и несколько коллекций.

blessmaster
2) Есть DBRef, который назвать нереляционным язык не поворачивается, а в случае запроса - суть замаскированный джойн. Поэтому данный вариант никак не вписывается в Вашу модель.
Сорри, изучил вопрос DBRef подробней и не нашёл, как DBRef использовать в запросе, то есть джойном он не является и задачу поиска не решает никак, так что он куда ближе к велосипеду из третьего пункта, только с чуть меньшим количеством телодвижений.

Generally, for “contains” relationships between entities, embedding should be be chosen. Use linking when not using linking would result in duplication of data.

http://www.mongodb.org/display/DOCS/Schema+Design
Мысль сводится к “следует выбирать внедрение данных в документ, вместо создания новых сущностей, но если внедрение приведёт к дублированию данных - нужно использовать связывание”. То бишь, нормализация не забыта и рекомендуется, но средств для работы с нормализованными данными, около нуля. Печально…



Отредактировано (Дек. 4, 2011 16:34:48)

Офлайн

#5 Дек. 4, 2011 17:59:00

o7412369815963
От:
Зарегистрирован: 2009-06-17
Сообщения: 1986
Репутация: +  32  -
Профиль   Отправить e-mail  

MongoDB и несколько коллекций.

:( многа буков,

> Не холивара ради, но это не для всех реляционных баз верное утверждение.
Возможно, пример приведете?

> Допустим, мы делаем социальную сеть
> 1. Человеку нужно показать последние сообщения и фотографии его друзей, участников его групп.
> 2. Нужно найти последние фото и статьи близких человеку по интересам людей
> 3. Мы проводим социологическое исследование и нас интересуют а) комментарии людей ассоциированных с какой-либо темой, а также б) комментарии людей близких первым людям.

Я сейчас разрабатываю соц. сеть для забугорной компании, у меня оно так:
1.
1) получаем друзей, // можно и без этого запроса, зависит от реализации
2) получаем 20 последних событий (фото, сообщения …), где автор входит в список друзей.
итого: 1, 2 запроса

2. так же, только фильтр по интересам.

3. а) непонятно, что за тема? пример?
б) типа комменты друзей моих друзей? - так же как п.1, только +1 запрос на получение всех друзей моих друзей.


> 1) Вариант с хранением полного профиля человека в каждой записи я отвергаю как невероятный из-за объёма данных, так и создающий огромную нагрузку на дисковую систему в случае малейшего редактирования профиля.
В некоторых случаях выгоднее хранить ссылку, в некоторых часть профиля.
Пример:
В каждом сообщении нужно выводить имя и фотку автора, у пользователя 30 сообщений на странице от разных авторов, просмотров в день 1000, сам пользователь оставил 100 сообщений, пользователь меняет фотку/имя раз в месяц.
Если храним ссылки в сообщениях: 30 (авторов от сообщений) * 1000 (просмотров) * 30 (дней) = 900к запросов к авторам
Если храним имя и фотку в сообщении: 1 (обновлений в месяц) * (сообщений у пользователя) = 1 update на 100 сообщений.

Сравнение для примера, в данном случае видно что хранить часть информации выгоднее, при том что этот “большой” update можно делать потихоньку, в фоновом режиме, ничего страшного если несколько секунд/минут фотки будут разные в сообщениях.

Офлайн

#6 Дек. 4, 2011 19:59:52

doza_and
От:
Зарегистрирован: 2010-08-15
Сообщения: 4138
Репутация: +  252  -
Профиль   Отправить e-mail  

MongoDB и несколько коллекций.

Не спец по базам данных, поэтому поинтересуюсь.
может разница в след пунктах?
1 при разработке с нереляционной DB меньше трудоемкость поскольку проще ORM.
2 В обычной DB все очень плоско и доступно - те все таблицы глобальны нет скрытых полей(колонок) нет наследования и т.п. Для проектов с большим количеством таблиц/классов это затрудняет разработку.
3 В объектной базе легко реализовать (или уже встроены) специализированные быстрые алгоритмы поиска, отличные от индексированного поиска в больших таблицах строго упорядоченных ключей. Те поддерживаются многомерные массивы
, rtree и.т.п. Конечно такие индексы поддерживаются и обычными RDB, но Мне кажется что конструирование своих индексов в них затруднено (точнее как и в объектных DB они переедут в программную часть).



Отредактировано (Дек. 4, 2011 20:09:23)

Офлайн

#7 Дек. 5, 2011 16:44:46

Lexander
От:
Зарегистрирован: 2008-09-19
Сообщения: 1139
Репутация: +  33  -
Профиль   Отправить e-mail  

MongoDB и несколько коллекций.

blessmaster
В обсуждемом примере нет объединения таблиц. Есть объединение результирующего множества и необходимость провести по нему выборку и сортировку.
Как же нет? В 1-м посте автор темы указал необходимость объединить данные 2-х коллекций. Коллекция=таблица.
blessmaster
Хорошо, есть вообще какая-то ясно описанная граница для NoSQL, а ещё лучше Mongo, где метод доступа “реляционен”, а где - нет? Так-то делать - по-монговски, а так-то - реляционщина?
Давайте для начала вспомним, что использование табличного способа хранения данных - это костыль.
В свое время были причины его использовать, почему и зачем - не будем сейчас об этом.
Вернемся в наше время.

Выбор любого хранилища данных, как вы понимаете (сужу по вашим постам) зависит от конкретной задачи.
Способ обработки данных - следствие выбора хранилища.

Большинство бизнес-задач связаны с обработкой документов, поэтому нужно использовать ОБД.
Одной из полезных особенностей ОБД (в частности, Монго) является простота изменения структуры документа.
В бизнесе встречается не просто часто, это происходит постоянно.
Что это за изменения? Обычно - добавить одно или несколько полей.

Для РБД такие изменения очень болезненны, т.к. нужно вносить изменения сразу в несколько мест: структуру БД, серверный и клиентский код.

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

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

blessmaster
По поводу JS, таки скажите: он действительно блокирует всю базу на время своего выполнения (не важно на какое время), либо несколько разных скриптов могут выполняться параллельно и при этом отрабатываться другие запросы (допустим, ядер для этого хватает, дисковая нагрузка балансируется)?
JS разный бывает.
При map/reduce база не блокируется! Сам скрипт выполняется в одном потоке (не процессе!). Со всеми правилами переключения между потоками, характерными для конкретной ОС.
А вот eval - блокирует. Но не базу, а одну ноду, на которой запущен.

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

blessmaster
Мысль сводится к “следует выбирать внедрение данных в документ, вместо создания новых сущностей, но если внедрение приведёт к дублированию данных - нужно использовать связывание”. То бишь, нормализация не забыта и рекомендуется, но средств для работы с нормализованными данными, около нуля. Печально…
Это не совсем так. Вы опять отталкиваете от реляционной практики.
Для РБД создание одного запроса на выборку данных - идеал разработчика почти для всех СУБД.
Но, во-первых, это совсем не идеал для СУБД. Зачастую несколько последовательных небольших запросов лучше (быстрее, меньше ресурсов), чем 1 большой.
Во-вторых, все производители СУБД рекомендуют делать короткие транзации.

В сводке Монго написано лучше:
Line item detail objects typically are embedded.

Objects which follow an object modelling “contains” relationship should generally be embedded.

Many to many relationships are generally done by linking.

Collections with only a few objects may safely exist as separate collections, as the whole collection is quickly cached in application server memory.

Embedded objects are a bit harder to link to than “top level” objects in collections.

It is more difficult to get a system-level view for embedded objects. When needed an operation of this sort is performed by using MongoDB's map/reduce facility.

If the amount of data to embed is huge (many megabytes), you may reach the limit on size of a single object. See also GridFS.

If performance is an issue, embed.


По поводу размещения на диске.
Для объяснения как работает этот механизм, нужно рисовать.
Текстом долго.
Если коротко, то РБД всегда стремятся разместить в одной странице на диске 1 таблицу.
2 таблицы - 2 страницы. Но где будет физически размещена 2-я страница данных - неизвестно.
Если в 1 SQL запросе используются данные 2-х таблиц 1кБ и 2 кБ, то при размере страницы в 4кБ с диска должны быть считаны 2 страницы (8кБ).

ОБД эти же данные, размещенные в одном документе (а значит - в одной коллекции) разместит на 1-й странице.
Вариант шардинга не рассматриваю из-за малого объема данных :)

При увеличении кол-ва таблиц в запросе ситуация еще хуже.

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



Офлайн

#8 Дек. 5, 2011 16:56:04

Lexander
От:
Зарегистрирован: 2008-09-19
Сообщения: 1139
Репутация: +  33  -
Профиль   Отправить e-mail  

MongoDB и несколько коллекций.

Кстати, о стиле написания запросов.
Написать 2-3 запроса для формирования 1-й экранной страницы данных - это нормально в мире Монго.
При чем не только из-за простоты кода, но и потому, что объем занимаемой памяти каждым запросом для генерации 20-30 строк информации небольшой.

То же самое для РБД - тоже нормально.
Хотя есть возможность оформить получение данных одним запросом. И это тоже нормально. Но для РБД.



Офлайн

#9 Дек. 6, 2011 04:28:33

PooH
От:
Зарегистрирован: 2006-12-05
Сообщения: 1948
Репутация: +  72  -
Профиль   Отправить e-mail  

MongoDB и несколько коллекций.

Lexander
Давайте для начала вспомним, что использование табличного способа хранения данных - это костыль.
В свое время были причины его использовать, почему и зачем - не будем сейчас об этом.
Вернемся в наше время.
Очень сильное утверждение. Обосновать сможете?



Вот здесь один из первых отарков съел лаборанта. Это был такой умный отарк, что понимал даже теорию относительности. Он разговаривал с лаборантом, а потом бросился на него и загрыз…

Офлайн

#10 Дек. 6, 2011 05:58:11

o7412369815963
От:
Зарегистрирован: 2009-06-17
Сообщения: 1986
Репутация: +  32  -
Профиль   Отправить e-mail  

MongoDB и несколько коллекций.

PooH
Lexander
Давайте для начала вспомним, что использование табличного способа хранения данных - это костыль.
В свое время были причины его использовать, почему и зачем - не будем сейчас об этом.
Вернемся в наше время.
Очень сильное утверждение. Обосновать сможете?
Я по большей части согласен с этим.
Конечно для каждой задачи свой инструмент, но если задача будет одинаково хорошо работать на обеих БД, тогда лучше выбрать ту что удобней и проще.
Табличный способ хранения имеет кучу ограничений: фиксированный размер полей, хранить можно только определенные поля, нельзя выкинуть не нужные поля и т.д…. - это все ограничения, а ограничения - есть не удобство.
Поэтому раньше приходилось “мучиться”, из-за отсутствия лучшего - использовали “костыль”. Можно так же взглянуть на другие вещи, сейчас мы используем клавиатуру и мышь - но это же “костыль”.

Да и вообще человеку проще мыслить объектами чем таблицами, в “объектном” мире живем.

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version