Comments 131
Реляционные базы данных обречены!*

* — Обречены ли они? Конечно, нет. По крайней мере, пока**

** — Что может быть лучше старых добрых реляционных СУБД…
Не всякая структура данных легко переезжает на ключ-значение. Да и иногда спасает разнесение данных по категориям на различные сервера с частичной репликой: на самом монструозном сервере — горячие данные, статистика — на другом, история, персональная информация пользователей… (вставить своё) — т.е. «холодные данные» — на третьем и т.д. Такой подход у нас пока прекрасно держится.
Не обречены, просто всему своё. И откуда вы достали такое лого MongoDB?
Они давно уже не Mongo и лого тоже давно поменяли:
Пока не придумают хороших средств аналитики для NoSQL, РСУБД будет жить.
А чего именно вам не хватает? Какую задачу вы не можете решить или вам не удобно решать?
Дано: 10'000'000 заказов и 1'000'000 товаров.
Найти: Хочу посмотреть все товары красного цвета, которые встречались в субботних заказах с общей суммой больше $100.

На реляционных — мгновенно.
Ага, щаззз
Если есть индексы по нужным полям. это раз.
Два, если таких запросов по разным полям у вас много, то индексов будет дофига. Соотвественно вставка у вас будет «весьма быстрой».
И 3 для аналитики надо использовать OLAP в связке с другим хранилищем с регулярной выгрузкой данных из него в OLAP. Да, мы не сможем получить мгновенный отчет на данную минут, но это чаще всего и не требуется, зато запросы будут действительно мгновенные и вставка не будет тормозить.
Если ложить индексы на другой RAID, а не на тот на котором данные всё будет очень быстро, а главное понятно и структурировано «прямо из коробки». Ну и очень реляционно.
Хотя может я старовер и чего-то не понимаю. ((-:
Но тема noSQL мне очень интересна.
Совершенно не обязательно, достаточно чтобы таблицы помещались в память. Сейчас это легко может быть :)
Простой проимер у меня есть список товаров которые купили в магазине за год. Надо агрегировать данные сначала по месяцу, а потом по количеству товаров. Грубо говоря нужен куб вида товар — месяц — количество. На SQL это делается довольно просто, а вот на NoSQL вам прийдется нелегко.
UFO landed and left these words here
Мы в ew.am используем две базы данных — postgresql для почти всех данных, для вещей вроде биллинга, для которых очень важна транзакционность и целостность данных. А MongoDB используем для аналитики, и кучи других вещей, которые сложно запихать в реляционную систему.
Например, в MongoDB мы храним системы достижений, учета посещения одним пользователем профиля другого — пресловутые «ваш профиль недавно смотрели» и т.п.). Ну и интернационализация (i18n) вся в MongoDB лежит, так как скорость доступа очень высока, и можно динамически через админку редактировать эти данные.

Сразу предупрежу, что у нас все на RoR написано, поэтому в этом контексте могу сказать про легкость использования:
В нашем случае, нереляционная база не требует большего количества кода, чем реляционная.
По факту, и с Postgre, и с MongoDB мы работаем через driver и ORM. Для Postgre это стандартный RoR'овский ActiveRecord, а для MongoDB — MongoMapper. Они оба умеют проксировать объекты базы данных на обычные ruby-классы, и транслируют методы-обращения в нужный язык запросов (sql для postgres, javascript api для Mongo).

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

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

Хочется добавить…
Много сказано про типизированность данных в таблицах. mishinoleg, прав про рост кода в самом приложении. Все приводит к тому, что можно назвать, _самостоятельной реализацией части функций СУБД в своем коде под конкретную задачу_. (выделил подчеркиванием, к сожалению тэги недоступны)

В целом, могу из собственной практики сказать, что нормализация таблиц, по своей сути, близка, к тому, чтобы стать «хранилищем». Достаточно перестать использовать в запросах «join» и начать делать это руками в коде. Последнее, приведет к тому, что вы будете компоновать данные из таблиц наиболее оптимальным для вашей задачи способом. А это скажется на производительности. По сути, таблица в обычной базе с Primary Key и Blob-ом или длинной строкой, вполне может служить таким хранилищем, как ключ/значение. Учитывая наработки в движках SQL, запросы с выборкой по «основному ключу» врятли смогут быть уделаны различными свежими API. Скорее всего, они все таки выиграют.
Все что я хочу сказать, что если использовать реляционную базу просто, не нагружая ее семистраничными запросами, а нормализовав, реализовать большую часть математики и логики на уровне приложения, можно добиться и производительности и масштабируемости.

А вот если бы расписали иерархическую модель данных или сетевую… да еще бы нашли софт, который умеет с этим работать… совсем бы интересно было.
К слову сказать, иерархическая модель очень схожа с XML-структурой.
>>нормализация таблиц, по своей сути, близка, к тому, чтобы стать «хранилищем»

>>не нагружая ее семистраничными запросами, а нормализовав

Вы имеете в виду «денормализовав»?
По сути, да. Не корректно выразился. Тут два пути.
Можно расколотить все много мелких таблиц с одинаковыми ключами, либо писать пары «ключ/значение», где значение структурировано как то другим способом (CSV, XML...)
Всё так и есть. Реляционная модель никуда не исчезает, но используя все плюшки современных SQL-решений можно вполне реализовать на них и хранилища вида «ключ-значение». С тем же самым шардингом и прочими скйлэбилити-приспособами.
Именно!
Кстати, в таком ключе, до неприличия упрощаются SQL-запросы, что делает код совместимым с практически любой СУБД.
В дополнение к вашим словам можно перефразировать 10е правило Гринспена:
Любая достаточно сложная программа, использующая NoSQL БД, содержит заново написанную, неспецифицированную, глючную и медленную реализацию половины РСУБД.
… причем именно то, благодаря чему ожидалось увеличение производительности, скорее всего станет причиной её снижения, ведь никто же в начале рукописного join'а не озадачится хотя бы вопросом «а не отсортированы ли две таблицы». Просто возьмёт и напишет вложенные циклы.
Обычно заметки про то, что SQL-базы обречены пишут те, кто про SQL ничего не знает, или знает на уровне банальных SELECT и UPDATE.

Уже на SELECT XML у многих разум пасует.
Да уж, не говоря о таких вкусностях как PL/SQL и динамический SQL.

Навряд ли в ближайшее время появится такая NoSQL, которая способна всю логику работы с данными держать у себя, а клиентскому приложению отдавать уже только сформированные данные.

А отложенные и ленивые транзакции, а приоритеты действий с данными, а авто-дефрагментация…

Но для кого мы здесь распинаемся? Большинство ведь даже не в курсе, чем InnoDB отличается от MyISAM
>Большинство ведь даже не в курсе, чем InnoDB отличается от MyISAM
Да оно и не надо нам с тех пор, как используем postgres :)
Уже появились, упомянутая в топике CouchDB позволяет писать сколь угодно сложную логику на JavaScript или Erlang. По крайней мере на ограничения я пока не наткнулся, хотя плотно и не работал, равно как не работал с хранимыми процедурами и триггерами в MySQL — просто предубеждение с начала 2000-х на хранение кода в БД, основная причина — не попадалось на глаза удобных инструментов работы с ним (отладка, VCS и т. п.)

Интересно, а зачем всю логику работы с данными держать в базе данных?

Не, я понимаю, если специфические случаи, где это действительно нужно. Но таких случаев, как я понимаю, где действительно необходим такой подход, не намного больше, чем случаев, где действительно необходим BigTable.

Но в большинстве случаев куда как разумнее хранить всю бизнес-логику — и логику работы с данными в том числе в коде приложения, используя СУБД только как хранилище, из которого достают данные крайне простыми SELECT'ами.

Я имею ввиду, что куда как лучше с точки зрения архитектуры, поддержки и развития системы, если она написана на одном ЯП и вся логика описана в нем, чем иметь систему, в которой бизнес-логика тонким слоем размазана по системе: часть выпихнута в БД через какие-нибудь хранимые процедуры, часть в ЯП.

Это же ынтерпрайз по канонам. Чем больше логики в СУБД, тем больше получают SQL-специалисты, тем веселее всё это поддерживать и тем плотнее идёт подсадка на иглу. Пример тому — всё семейство FoxPro и типичные системы на ЭмЭсЭсКьюЭль.

ЗЫ. Я представляю, о чём говорю. Ну и в каждой шутке есть доля шутки.

Причин три

1. Более высокая скорость получения данных
2. Более высокая скорость разработки ( т.к. даже простейшая СУБД предоставляет кучу функций для работы с данными, до которых большинству клиентских языков как от Находки до Парижа — чего стоит, например, работа с датой )
3. На клиенте не нужна полная реализация структуры данных, можно обойтись элементарными функциональными вызовами, что позволяет вообще не думать о том, что у нас есть слой логики доступа к данным.

Если Вы этим не пользуетесь, это не значит, что другим оно не нужно.

Кроме того, проектов, где это могло бы активно применяться, не так уж и мало — просто большинство об SQL знают на уровне, описанном в книжке по PHP.

Не даром есть профессия — DBA.
DBA — это не профессия, а стиль жизни. Как «фанатик функционального программирования» или «профессиональный программист на PHP».

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

Да, в БД можно положить минимальную валидацию данных и поддержку целостности, но когда туда кладут стейт-машины или что посерьёзней — это болезнь головного мозга. Без обид.
Как-то писали небольшое приложение, которое надо было интегрировать с готовой базой данных. А там — батюшки, стопицот триггеров, валидация и эксепшены прямо в базе реализованы!)
Фанатизм в IT — это всегда бедствие.

Кроме того, логика тоже разная бывает.

Вот пример:

Нужно получить сумму пенсионных отчислений работников за последний квартал с детализацией по их часовой выработке.

На этом примере четко видно, что «за последний квартал с детализацией по их часовой выработке» — это логика, которая должна быть на уровне БД, а «получить сумму пенсионных отчислений» — это логика на уровне клиентского кода.

Для себя я вывел одно простое правило:
К процедуре получения данных надо ВСЕГДА относиться очень бережно, т.к. это самая медленная и одна из самых частых процедур в системе.
А где здесь бизнес-логика? Агрегация чистой воды, параметры которой необходимо задавать снаружи БД. Можно её бережно сохранить внутри БД, повысив реентерабельность кода для бОльшего количества средств, могущих получить к ней доступ. А можно выбросить её на уровень выше. Всё зависит от конкретных требований к системе.

Бизнес-логика — это не логика генерации вторичных документов. Это логика поведения приложений.
Я Вам про Фому, Вы мне про Ерему.

«логика доступа к данным» != «бизнес-логика»

но там и там, это — логика.

Неужели Вы никогда не сталкивались с кодом, который долго и упорно формирует дерево, получив данные простейшим селектом?

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

НО! нет там этой агрегации :(
Я не про Ерёму, простите. Я допустил досадную оплошность, не конкретизировав в пред-предыдущем комментарии то, что подразумевал под логикой.

Вы правы.
Ну я и говорю, что на самом деле не так много мест, где оно надо.

1) Далеко не везде она так уж критична. Какая разница, построится html-страничка за 70 мс или за 20 мс, если клиент ее грузит в любом случае за 1 секунду?
Ну и во-вторых, если уж на уровне приложений данные закешируются (а во всех современных мейнстримовых ORM'ах эта фича из коробки идет), то скорость доступа к данным из кеша будет куда как быстрее, чем через СУБД. А с учетом этого получается, что даже перенесение всей логики работы с данными из клиентского кода в базу данных выдаст не слишком большой прирост в производительности.

Оговорюсь: бывают случаи, когда разработчики, не понимая особенностей работы СУБД, городят такое (типа классической N+1 проблемы), что насущной становится необходимость пригласить DBA для навешивания люлей и выпрямления рук.
Опять же, в некоторых особо узких местах было бы глупо не перенести тяжелую логику в БД. Но сами понимаете, при грамотном проектировании всей системы, таких мест на самом деле немного. Бывает даже, что в достаточно большом проекте вообще таких мест нет.

2) Кхм. Я сам большой поклонник PL/SQL, и его возможности впечатляют. На минутку давайте отставим его в сторону (и особенно возможность запустить из него java код :)

И сравним возможности SQL ANSI 92 с каким-нибудь малоизвестным языком программирования вроде java. Вы что, действительно готовы сравнить DSL с возможностями платформы типа java со всеми библиотеками, написанными под нее?
Я, наверное, чего-то не понимаю в этой жизни, но любой мейнстримовый ЯП со всеми библиотеками, написанными под него, сто очков вперед даст стандартному SQL по возможностям работы с данными. Даже в случае работы с датами.

3) Это и называется выкинуть существенную часть бизнес-логики в БД :)
Это может быть очень удобно, если приложение ориентировано в основном на работу вокруг данных, как какой-нибудь классический CRUD.
И может быть чревато очень хитрыми и сложновыловимыми багами, если приложение имеют много логики, не выложенной в БД, и много логики на ЯП.

Ну и с точки зрения бизнеса, куда как лучше иметь систему, написанную, скажем, на java, чем систему, которая в равных долях написана на java и pl/sql. Ибо в первом случае для поддержки и развития надо нанять, скажем, одного java-разработчика, а во втором — одного java-разработчика и одного dba.
Опечатка:
И может быть чревато очень хитрыми и сложновыловимыми багами, если приложение имеют много логики в БД, и много логики на ЯП.
Похоже вы просто мало работали с SQL. Какой-нибудь хитрый селект с условными джойнами и группировками — нет, все это можно написать на джаве или там пехапе, только на sql это будет проще и логичнее (не говоря уже о скорости выполнения). В отличие от универсальных языков программирования узкоспециализированный SQL не позволяет сделать все на свете, зато умеет такие трюки, которые на всех остальных языках делать очень и очень долго, и вы получите в итоге «свой SQL с блекджеком и багами».
И не надо говорить, что мол таких задач не бывает.
«Сформируйте-ка мне сводный топ-100 лидеров продаж в штуках за период с… по… по Сибири в категориях „штуковины“ и „фиговины“ производства Китай и Вьетнам с разбивкой по поставщикам, мы хотим оптимизировать логистику».
Каждый раз запрос будет обрабатываться заново, пусть по индексам, но заново. Можно конечно закешировать, но что делать при обновлениях, вешать триггеры, а потом судорожно искать баги? А вот в кауче написав однажды вьюху при обновлении данных она будет обновляться автоматически, причем весьма быстро.
Не все так просто… недавно читал где-то статью про нагруженный сервак, переехавший с кауча на монго из-за того, что создание таких вьюх на их объемах данных занимало по несколько часов.
Создание или обновление. Если создание, то понятно. Вот если обновление, то это уже сложнее. Но в любом случае что мешает поднять вторую ноду? У кауча репликация мастер-мастер, то есть вы сможете коннектиться в любой из нод, и таким образом перераспределять нагрузку. Если я не прав — поправьте меня.

Вся прелесть как раз вот в таких преиндексированных вьюхах. Иначе весь смысл пропадает. Я не знаю, как у этим с монго.
JOIN и GROUP BY это очень здорово и полезно, но хотелось бы узнать о более сложных штуках.

Скажите, пожалуйста, как часто вы используете в работе процедуры, функции и триггеры в SQL и в каких случаях действительно оправдано ли их использование?
И в дополнение есть еще куча банковских систем, написанных на связке тонкий-клиент Delphi+бизнес-логика в БД, от которых до сих пор не могут отказаться в силу сложности миграции на другую платформу и очень выскоих рисков.
>А отложенные и ленивые транзакции, а приоритеты действий с данными, а авто-дефрагментация…
Напишите пожалуйста, мне было бы очень интересно послушать
О чем конкретно Вы бы хотели услышать?
Задавайте вопросы, расскажу.
Но, очень прошу, пользуйтесь гулом перед тем как задавать вопрос.
Навряд ли в ближайшее время появится такая NoSQL, которая способна всю логику работы с данными держать у себя, а клиентскому приложению отдавать уже только сформированные данные.

А как же map/reduce в MongoDB и CouchDB?
Чтобы уж совсем ясно выразить свою позицию, допишу:

Все любят поругивать php-разработчиков, полагающих себя программистами после прочтения книги «Научись делать веб-сайты за 24 часа».

Но их существование имеет смысл. В конце концов, для каждой задачи — свой инструмент.
И в большинстве веб-приложений, по факту, нафиг не нужны возможности какого-нибудь MySQL на уровне выше «select * from articles where id = 'params[:id]'».

Я даже больше скажу, в огромном количестве приложений и бизнес-логики, и базы данных, и application-сервера не нужно :)

Вон, за примером далеко ходить не надо: у меня standalone блог был на wordpress, там в целом набежало порядка 30-ти постов и около 1000 комментариев. Apache отъедал при средненькой загрузке 100mb оперативы (mysql не посмотрел, извините, но тоже какая-то нагрузка была, думаю, пару метров-то отожрал точно).
Теперь я перевел его на статические страницы (у меня теперь есть 30-ть файлов в формате markdown, которые при выкладке через простейший шаблонизатор конвертируются в html-странички).
И теперь при той же нагрузке все накладные расходы сервера на блог — 9Мб оперативной памяти, занимаемой nginx'ом.

Попробую свести все написанное к внятному выводу:
У РСУБД очевидно есть огромная область применения и, разумеется, никто их не убъет (да и не собирается, в общем-то :)
У NoSQL тоже есть область применения.
На самом деле, нет жесткой необходимости пихать в каждое веб-приложение СУБД (реляционку или NoSQL). Более того, в большинстве приложений возможности языка, СУБД не используются даже на 5%.
select * from articles where id = 'params[:id]'
как-то некрасиво :) select * from articles where id = '#{params[:id]}' но все равно «некрасиво», мало ли SQL инъекцию кто пришлет :)
Ну это типа псевдокод был, так сказать, проиллюстрировать принцип :)
В начале 90-х я кодил в системе Numps (навание уже точно не помню). Эта система ставилась на один комп и к нему через определенное устройство подключалось несколько терминалов, с которых производился набор данных. Эта система было многозадачной. Но не это самое интересное, самое интересное это встроенных язык программирования (извините но задавностью лет не понмю названия). Так вот, в нем было такое понятие как Глобалы, это что-то типа базы данных, в ней данные были представлены в виде пары (<множество ключей>, <значение>). Причем система позволяла также производить выборку ключей, что-то типа как в прологе. Оперировать такими данными было достаточно просто так как они были похожи на многомерные массивы. Вот для примера:
myvar( 1, «one», «first», 0 ) = 1111, тут система смотрела есть ли данные по заданным ключам (в скобках), если есть, то заменяла значение, если нет, то создавалась новая запись. Для извлечения ключей использовались специальные переменные, что-то типа:
myvar( 1, %v,, ) — тут в через переменную v последовательно можно было выбрать все значения 2-го ключа, при известном значении 1-го. Что самое интересное, ключи выбирались в отсортированном виде.
По сути база данных была огромным массивом который хранился на диске, а выборка данных была встроена в сам язык программирования через многомерные массивы. Это было очень удобно, ничего подобного я не встречал и по сей день.
Это MUMPS системы, сейчас из них остались Cache и GT.M.
И для NoSQL систем это почти идеальная основа, если смириться с весьма специфическим языком.
Более того появляется еще, например MiniM, новая разработка
Язык очень даже хорош, не знаю чем вас не устраивает его специфичность, но на нем получаются очень даже неплохие приложения
UFO landed and left these words here
UFO landed and left these words here
> NoSql означает Not Only SQL
где вы это читаете? NoSql просто термин под под которыми понимают no relation базы данных. Нет никакой расшифровки (особенно такой глупой, когда 'Only' вместо 'only')
UFO landed and left these words here
Многие вещи банально удобнее хранить в Mongo или Couch из-за отсутствия жёсткой схемы, вне зависимости от скорости, масштабируемости и т. п.
UFO landed and left these words here
Как-то вторую часть вашего коммента я понял так, что NoSQL нужны только там, где требуется масштабируемость гугловских масштабов.
или документно-ориентированная база с очень гибким форматом записей
придет… убьет… xQuery и CoutchDB — первая ласточоко… SQL — клеит ласты как умеет…
— Да. И все языки программирования тоже обречены, кстати. И мы все обречены. :)
CouchDB не хранит данные в JSON (полагаю, что и MongoDB также). Данные, хранящиеся на физическом носителе, представлены в виде B-Trees, а JSON является форматом обмена данными с client приложениями.
И Монго не хранит данные в JSON, кстати. Он их хранит в BSON (а это немного другое, как ни странно, да)).
Спасибо за статью, немного привёл в порядок свои знания по этой теме.

Единственное, не нашёл ответ на один свой вопрос. Я очень много слышал, что у NoSQL хранилищ есть ещё один огромный плюс по сравнению с СУБД — скорость выполнения запроса. Говорилось, что разница огромна. И вот я хотел бы узнать, как достигается такая скорость? Именно на низком уровне. В СУБД если использовать индексы, то при запросе не будет происходить полного скана всей таблицы и время запроса можно значительно сократить. А как в NoSQL? При запросе там проверяются все записи или есть какие-то внутренние системы для оптимизации чтения? Спасибо, если кто-то сможет разъяснить :)
На хабре была статья как MySQL может выдать 750000 операций в секунду.
Очень просто — прямое управление в стиле NoSQL.
Много времени уходит у SQL систем на подготовку — парсинг, планирование…

И если в NoSQL вам нужен поиск — вы должны сами позаботиться об индексах и об их быстродействии
Любая структура данных типа «ключ-значение» позволяет получить значение по ключу с асимптотической сложностью O(1). Кроме того, при обращении к view-функциям (возьмем для примера CouchDB), как правило, возвращается результат из кеша. В подобных системах view-функции не имеют побочных эффектов, и как следствие, позволяют кешировать результаты выполнения для каждого определенного набора аргументов.
Там просто нет индексов, доступ возможен только по «первичному ключу». Если нужны выборки по значениям данных, то либо руками строить индексы, либо использовать встроенные возможности, которые не везде есть. В результате, скорость аналогичная РСУБД и геморрой. В этом, извините, заключается жопа nosql решений.
Например Couch для каждого view(считайте что это запрос) атоматически строит B+ дерево. То есть выборка будет оптимальна. Да и обновление этого дерева будет так же быстро за счет чистоты функции map. То есть для нового документа достаточно посчитать ключ и воткнуть в нужное место дерева.
Правда целостного ответа так никто и не написал, должна же где-то быть ложка дегтя…
она в том, что всё ложится на плечи программиста.
Грубо говоря
вместо SELECT * FROM thebigtable WHERE somefield=42;
вам придётся самому сделать и поддерживать индекс для «обратного» поиска по значениям somefield
Ничего вам не придется. По крайней мере не во все NoSql СУБД. Это как раз в SQL субд вам надо озаботится о наличии индексов, а кауч все сделает наиоболее оптимальным образом для конкретного запроса. Естественно запрос должен быть описан во vew.
Ну так key-value семейство и предназначено для хранения key-value. Если вам нужна выборка по полю, то делайте дублирование и добавляйте записи у которых ключом будет это поле, а значением — набор объектов. Ну либо используйте что-то более подходящее.
По крайней мере хотя бы знаю, что поискать на досуге для укрепления знаний ;) На самом деле меня этот вопрос очень давно интересовал. Сколько я всего читал, даже был на одном семинаре, так всё же для себя точно не уяснил, чем обусловлены плюсы NoSQL. Всмысле, все плюсы и минусы уже давно знаю, но я хотел бы узнать, почему так происходит на низком уровне. Как устроены движки этиз баз и принципы их работы? Вобщем, попробую нарыть что-то по этому вопросу…
В самом плохом случае вам дают просто key-value хранилище, в котором можно хранить всё что угодно. Данные режутся на небольшие блоки и по ключу автоматом раскидываются по серверам. Дальше крутитесь как хотите :)

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

Но за все плюшки надо платить, скажем обычно индекс должен жить только на одном сервере, репликация есть, но нет распределённых индексов. В Монго вообще забава, индекс должен влезать в оперативку, не влезает — всё извините, живите без индекса. Хотите возможность перебирать данные по ключу в порядке возрастания значения ключа, теряете в распределении нагрузки по серверам. Хотите хранить большое кол-во атрибутов по каждому ключу, готовьтесь к построению субиндексов по их именам, благо это делается автоматом при большом кол-ве атрибутов, но они начинают жрать память даже когда не нужны, т.к. становятся частью значения.

Скорость появляется в тех задачах, где достаточно исользования key-value хранилища, как key-value хранилища. Плюс к этому, полная согласованность данных не гарантируется, а иногда вовсе понижается до того, что только один сервер в кластере может иметь актуальные данные. Поэтому, запись в базу может выглядеть просто как сохранение в оперативку с отложенной на неизвестный срок репликацией — соответсвенно, скорость при «записи» очень большая.

Если сравнивать с РСУБД, где всё предсказуемо, то пока nosql это зыбучие пески, но это моё мнение. Особняком стоит Редис — сервер структур данных, имхо, в нём есть некоторые просчёты, но сама идея выносить реализацию и хранение структур данных очень притягательная. Короче много всего у nosql, и плюсов и минусов, долго и лень писать, сотрясая воздух :)
Скажу я. Не могу сказать за все СУБД, потому буду про кауч.

В NoSQL нет джойнов. соответсвенно если у вас большое число разнотипных и больших оьъектов, связанных между собой, то хранение их в кауче (а точнее выборка) будет не слишком эффективно и вот почему.

Если хранить с полем, содержащим идентификатор связанного документа, то можно будет сделать квази-джойн на 1 уровень в глубину (на самом деле это не джойн, а просто сахар, для связанного id уже после мапа прогружается документ). Обсуловлено это тем, что функция map (в которой собственно происходит выборка) явяется чистой и для получения результата может пользоваться только переданным ей документом. Это нужно для оптимизации автоматического построения и обновления индексов.

Есть вариант хранения многоуровневой иерархии в одном документе, но это содержит ряд недостатков.
1. Документу нельзя только обновить поле. Надо загрузить документ, исправить поле и залить документ. Отсюда получаем, что для больших документов будет неэффективно.
2. Если требуется часто менять вложенные подобъекты, то вам придется самому озаботиться обновлением этих подобъектов во всех документах. Кстати аналогично будет и при денормализации БД в РСУБД.

Поэтому для себя делаю вывод, что в частности кауч подходит для хранения плоских или почти плоских моделей, без глубоких взаимосвязей. Причем оптимально его использовать для моделей с нечеткой структурой. НУ и само собой, когда нужна или планируется горизонтальная масштабируемость.
>> разработчики удалили ряд функций (включая представления, триггеры, скомпилированные выражения, хранимые процедуры, кэш запросов, ACL, и часть типов данных)

Ну и зачем нужна такая база данных?
Может вы удивитесь, но у многих сайтов на MySQL практически всё это не используется, кроме разве что кэша, который дублируется кэшем на уровне приложения.
Ответ прост — для веба в основном используются/нужны простые выборки т.е. взять контент и отдать юзеру. А как уже упоминалось в том же MySql, он в топе по скорости выборок, почти 50% времени уходит на разбор запроса. Вот и спрашивается зачем ждать — народ сел почесал репу и пришел к выводу что для для таких задач такие навороты нах не нужны. Вот так и появился проект.
Имхо:
1. Чем принципиально NoSQL отличается от простых запросов по primary key?
2. SQL плох тем, что у каждого производителя СУБД свой диалект.
3. Делать аналитику на SQL сильно проще.
4. Интересным подходом кажется HandlerSocket + MySQL — обход SQL уровня и прямой доступ к таблицам по ключам.
1. Тем, что структура данных не жесткая — каждая запись может иметь собственный набор полей. Реализация этой фичи в реляционной базе данных громоздка и неудобна (как раз сейчас с этим возимся)

2. NoSQL или SQL? SQL в сравнении с NoSQL является супер-стандартным. Каждая NoSQL база данных имеет собственный API, собственный язык запросов, собственные правила работы с индексами, и кучу ограничений и особенностей.

3. без комментариев

4. ИМХО, очень частный и достаточно трудоемкий случай
1. Ок. Имеем Primary Key + BLOB. BLOB — может быть каком угодно формате. Скажем, JSON. В чем сложность? Если запросы не по индексу, все равно нужно просматривать все записи.
2. Суть в том, что просто SQL не бывает. Так же как NoSQL
3. А что? в sql глазами данные посмотреть сильно проще.
1. А как вы в случае, если во втором поле хранится, например, JSON, сделаете выборку по одному из полей этого JSON'a? И это самый простой пример.
3. В той же CouchDB из коробки есть веб-админка, в которой можно смотреть как сами коллекции, так и их view-функции.
1. А люди думают, что NoSQL — это только простейшие хешмапы, а map/reduce — деление одного английского глагола на другой :)
2. Про то, что для запросов в map/reduce вообще не нужно специального языка (например в монго и кауче используется совершенно обычный javascript) они тоже не в курсе. И то, что это не тупой перебор всех документов по очереди, тоже не подозревают
3. Про то, что аналитика на SQL при огромных хранилищах — самоубийство, тоже не в курсе. Нормальные люди используют OLAP.
4. Я не знаю, что это такое, поэтому промолчу
Встречный вопрос: почему кеши страниц (да и запросов) вида ключ — значение не хранят в базе?

ЗЫ. Провокационный вопрос, прошу без холивара ;)
Реляционной? Имхо достаточно очевидно — вопрос надежности. Если база потеряет данные — это очень плохо. Если кеш — то не очень.
Не поняли — подтекст вопроса был в скорости работы, а именно в накладных расходах на соединения разбор синтаксиса и пр. вещи. Поэтому хешовые базы в этих ситуациях выигрывают.

ЗЫ. И потеря кеша это совсем не страшно, через время он заполнится снова.
Проблемы с масштабируемостью реляционных СУБД несколько преувеличены. Точнее, несколько недооценены объемы данных, на которых начинают возникать проблемы с масштабируемостью. А это сотни терабайт и петабайты данных, которые есть наверное меньше чем у пары сотен компаний в мире. Кроме того, масштабируемость реляционной СУБД зависит от ее архитектуры. Например shared-nothing (MPP) масштабируется горизонтально куда лучше чем shared-disk (SMP).

Другой вопрос — что постепенно отмирает подход «универсальная реляционная СУБД на все случаи жизни», поэтому например для аналитических систем стоит использовать специализированные аналитические реляционные СУБД. Но здесь пока все еще начинается. Хотя этот вариант интересен тем, что стоимость перевода существующей системы с универсальной реляционной СУБД на специализированную, но все равно реляционную СУБД, будет намного ниже, чем переход на нереляционную СУБД вообще.

Здесь есть перевод неплохой статьи на эту тему — citforum.ru/database/articles/one_size_fits_all/

PS. Накиньте, плиз, пару поинтов в карму — не хватает чтобы опубликовать из черновиков статью про колоночные СУБД.
Причины такого доминирования неочевидны. На протяжении всего существования реляционных БД они постоянно предлагали наилучшую смесь простоты, устойчивости, гибкости, производительности, масштабируемости и совместимости в сфере управлении данными.

А это разве не перечисление очевидных причин доминирования?
ИМХО забыли некоторую мелочь — это увлечение потребностей и обьемов информации. Хранилища этого вида досихпор очень плотно используются, даже есть соотв. типы данных, к примеру на perl это хеши.
>В последнее время появилось много нереляционных баз данных.
>Это говорит о том, что если вам нужна практически неограниченная масштабируемость по требованию, вам нужна нереляционная БД.

Это говорит ровно о том, что «в последнее время появилось много нереляционных баз данных» и ни о чем более.

Реляционных БД достаточно в 99.9% проектов. При наличии прямых рук — в 99.99% :)
Достаточно — да, оправдано ли чем-нибудь кроме необходимости изучать новые способы работы с данными — вряд ли, имхо.
А разве она справедлива только относительно NoSQL, а не для любой распределённой системы?

«Разные задачи по-прежнему требуют разных инструментов. » согласен, это наверно вечное ограничение.
Она этот пост на Хабре вымарывает жёлтым. Автоматически :)
Этот юмор слишком тонок для меня.

Не могу понять почему Cancel считает(в отличии от автора теоремы) решения SQL не уязвимыми.
А зачем вы мне приписываете чужие мысли? Я ничего про неуязвимость SQL не говорил.
Для подчёркивания мифичности серебрянной пули не нужно было упоминать CAP-теорему.
А я и не говорил про NoSQL. Она действительно для любой системы справедлива. Смысл был в том, что серебряной пули нет.
Я рыдал :)
"- Если все, что тебе нужно, это впечатляющие цифры бенчмарков, то почему бы тебе не посылать данные в /dev/null?"
"- А /dev/null поддерживает шардинг?"
"- o_O"
UFO landed and left these words here
Ну и бредятина

Почти все системы баз данных, которые мы используем, являются реляционными, такие как Oracle, SQL Server, MySQL, Sybase, DB2, TeraData и так далее.

Причины такого доминирования неочевидны.


… автору статьи. Потому что остальные знают про язык SQL, который и явился причиной взрывного роста РСУБД.

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

Однако чтобы обеспечить все эти особенности, реляционные хранилища невероятно сложны внутри.



Что это за аргумент — «сложно устроен внутри»? А с чего устройство-то должно быть простым?
Потому что автор дебиловат и не может понять?

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


А где, соб-но, доказательства этого утверждения?

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



Конечно, конечно, только из-за дисков и нормализуют базы.
Как насчет целостности и достоверности?
Если у нас 13 копий одной и той же записи счета клиента с разными значениями суммы на счете — чо делаем?
Случайно выбираем одну, остальные удаляем?

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


Автор статьи наивно умолчал проблемы, связанные с распределенным хранением данных.
Он как бы подразумевает, что если я разложу записи с ключами по разным серверам,
то это автоматически ХОРОШО и решило все проблемы.

Ага, конечно.

Проблемы-то никуда не ушли, наоборот, только увеличились. Транзакционность? Достоверность? Распространение обновлений? Гарантия непротиворечивости?

Ну и напоследок, делаем NOSQL.

Берем SQLITE. Ну или другую БД, не суть.

CREATE TABLE NOSQL(key int not null primary key autoincrement, obj text not null)

В obj заносим JSON объекта.

Скорость выборки? Фантастическая.

Масштабируемость? Для SQLITE, см. www.sqlite.org/limits.html

Транзакционность? Осталась.

SQL? Полноценный, остался.

Фсе, построили NOSQL. Расходимся.

Проблема (очевидная) со складыванием JSON в CLOB заключается в том, что с этим текстом ничего нельзя сделать, только прочитать весь целиком. Тогда как в документно-ориентированном хранилище можно по полям делать выборки, сортировки и т.п.
Это если есть соответствующие индексы. Иначе все равно всю базу сканить придется.
Да и не во всех NoSQL есть сортировка.
Господи, сколько раз говорить что каждой задаче — свой инструмент.

Реляционные СУБД никогда не уйдут, потому что они подходят для многих задач. В то же время для других задач начали появлятся удобные key-value СУБД. Никакой убийца SQL не появился, появился лишь еще один инструмент. И все.
Раз уж мы заговрили о том как нам не нравятся реляционные модели, то не так давно я работал .Net с проектом GraphDS. Сетевая модель. Разработчик www.sones.com.
Они рекомендуют размещать ее на Azure. Суть в том, что они просто сделали хорошую реализацию: внедрили язык запросов по графу копилируемый GraphQL и довольно серьезную основу, на которой работает сама база. Кстати LINQ тоже при деле. Жаль она работает медлено. В общем рекомендую поинтереосваться хотя бы для общего развития, самим подходом к решению задач. Я ее в своем проекте применить не смог.
Затронутая тема и спор из разряда «что лучше лобзик или деревообрабатывающий станок». Выбор инструмента всегда зависит от решаемой задачи.
Only those users with full accounts are able to leave comments. Log in, please.