отражение жизни в экране монитора ([info]rainman_rocks) wrote,

Зачем NoSQL программистам

В последнее время, как видим, пошла мода на NoSQL.
Термин, собака, размыт до черезвычайности, под ним все подразумевают разное, кто во что горазд - кто-то интересуется переработанными RDBMS типа BigTable, кто-то болеет за key-value storage, парни с PostgreSQL вообще пошутили на тему QUEL.

Сконцентрируемся всё-таки на основном значении: системы хранения данных вида key-document. Популярность оных вот свирепо обсуждает с организационной точки зрения zabivator (краткий пересказ: nosql это всё пионерские игрушки, люди просто не умеют готовить кошек ленятся нанимать хороших DBA). Я же, будучи всего лишь низменным прикладным разработчиком, попробую разглядеть вопрос со стороны технической.

У меня на счёт причин этого феномена есть интересная теория.

Люди, как верно замечено, по зову души уходят от SQL. Сначала уходили на ORM, теперь бегут на NoSQL. Почему бегут? Причины, как обычно, чисто человеческие: потому что SQL им неудобен. Давайте смотреть где и в каком месте именно неудобен. Для этого достаточно посмотреть в сторону чего бегут.

А бегут они в сторону JSON. JSON есть классический персонаж сказки - Золушок, бедный бастард, порождение флуктуаций мятущегося разума Брэндана Эйка, который был подобран доброй феей-Крокфордом, отряхнут от пыли и выведен в народ. Не обладая ни массивной маркетинговой поддержкой XML, ни идеологическим минимализмом лисповых s-expressions, новичок стал феноменально популярен. Комбинация чисел и строк, упрятанных в произвольно вкладывающиеся списки (= массивы) и кортежи с именованными полями (= объекты, = ассоциативные массивы) оказалась на практике наиболее удобным и универсальным способом представления типичных структур данных.

JSON стал катализатором (если вообще не создателем) моды на NoSQL. Хранилища типа key-value существовали с незапамятных времён (BerkeleyDB был даже встроен в MySQL), но в мэйнстрим так и не пошли, и даже эксперименты с XML-базами ничем особым не запомнились, кроме нескольких статей на The Daily WTF. А тут вот нате: читабельный и естественный формат представления структур данных, мечта разработчика. Знай себе обращайся к именованным полям да работай со списками - ты это и так уже делаешь в любом языке программирования. Заметим, что популярные ORM пытаются свести SQL примерно к тем же операциям. Разработчик хочет работать в привычных ему абстракциях.

Так чем ж оно лучше SQL-модели, чего же у нас из благ JSON'а нету в классической реляционной системе? Реляционная БД - набор таблиц. Каждая таблица суть список кортежей. Элементы кортежа - те же скалярные типы, что и в JSON: числа и строки. So far so good: таблица более универсальна чем список и кортеж, её можно выродить и в тот, и в другой. Все элементы вроде на месте, чего ж не хватает?

Беда первая
: кортеж в кортеж можно вложить только непрямым способом, через foreign key. Foreign key собой представляет, в общем-то, тот же указатель/ссылку, к которым программисты и так привыкли. Другое дело, что в обычных ЯП "разадресация" этого указателя происходит либо прозрачно, либо при помощи простого typecast'а. В SQL же приходится прибегать к несложной, но раздражающей магии, типа джойнов/подзапросов. Ну или тупо ещё один дополнительный запрос (что неприятно для производительности).

А вот беда вторая, более серьёзная: вложить список в кортеж ещё труднее. Для этого нужны обратные ссылки. Поясню на примере.

Делаем платформу для блогов. У нас есть три основные таблицы -  пользователи, посты и камменты. Ясное дело, что в нашей программе, отображающей страницы блога, посты  логичнее всего будут представлены следующим типом:
class Post {
    String title;
    String message;
    DateTime date;
    List<Comment> comments;
    // другие поля
}

Но в реляционной БД у нас всё будет иначе. Поле comments из таблицы Post пропадёт, а вместо него в таблице Comment появится поле post_id. А список комментов для конкретного поста будет находиться выборкой по данному полю.

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

(Заметим, что способы впихнуть списки в кортеж всё-таки есть: например, поле-массив в PostgreSQL или строковой суррогат в MySQL, которым, подозреваю, многие веб-девелоперы малодушно грешат. Но использование их неудобно, связано с ограничениями и вообще не "feels right")

Это раздражает. При переходе из кода в SQL программисту приходится выворачивать мозг наизнанку. Он не чувствует привычного контроля над структурами данных.  Знакомые алгоритмы искажаются. Более того, ему не совсем понятно, для чего это нужно.

Зато смотрящему с RDBMS-башни наблюдателю всё, конечно, понятно. Реляционная система хранения оптимизирована для запросов (буква Q в SQL недаром стоит в центре). Перевод списков в индексы превращает упорядоченную структуру данных, привычную программисту, в некоторое аморфное облако, из которого при помощи запросов волшебно извлекаются разнообразные представления. Приверженцам классических RDBMS вообще непонятно как в NoSQL можно делать выборки.

Выборки, тем не менее, в NoSQL делать можно. Просто те же самые индексы вы создадите руками. В нашем примере с блогом, если вам понадобится упорядочивать камменты не только по дате, но и по, например, рейтингам (как это делают на stackoverflow), вы просто добавите в каждый пост ещё один список:
class Post {
    String title;
    String message;
    DateTime date;
    List<Comment> comments;
    List<Comment> commentsByRatings;
}

Дублирования данных не будет - это же просто список указателей, по объёму равный тем же индексам.

Короче, вопрос вполне решаем. Просто вся эта возня с индексами (включая их обновление при изменении данных и поддержку консистентности) теперь ложится на плечи программиста. И программист готов платить такую цену. Потому что он, сука, хочет САМ КОВЫРЯТЬСЯ В СВОИХ ПРИВЫЧНЫХ СТРУКТУРАХ ДАННЫХ. А не доверять сложной магии планировщика запросов и его непонятно где спрятанным индексам.

Повторюсь, в ORM стараются решить как раз именно две эти проблемы: автоматическое превращение foreign key в связанную структуру данных (вместо post.user_id => post.user), и превращение обратного foreign key в список (вместо comment.post_id => post.comments).

Именно это мне и кажется причиной недовольства SQL среди разработчиков, и основной причиной попыток бегства с него. Чтобы спасти репутацию SQL, эти проблемы надо как-то элегантно решить - будь то на уровне БД или API доступа к ней.

Благодарю за внимание.

UPD: Забыл, совсем забыл! Ещё NoSQL избавляет от ALTER TABLE. Разработчиков заколебало делать ALTER TABLE. Они привыкли одну строчку в коде поменять и перекомпилировать. А тут - несколько минут/часов форсмажора.

UPD-2: Вторая серия - http://rainman-rocks.livejournal.com/121163.html

UPD-3: ВНЕЗАПНО выяснилось, что практикующие со мной тоже в целом соглашаются: http://ivan.begtin.name/2010/06/11/%D1%82%D0%B5%D1%85%D0%BD%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B5-%D0%BF%D1%80%D0%BE-nosql-%D0%B2-%D0%B3%D0%BE%D1%81%D1%81%D0%B5%D1%82%D0%B8/
Tags: программизм

  • Post a new comment

    Error

    Anonymous comments are disabled in this journal

  • 266 comments

[info]zamotivator

June 10 2010, 11:10:39 UTC 1 year ago

Я аплодирую стоя, вы просто шедеврально разобрали причину и дополнили мой пост!
Таким образом, решая проблему "на своём" уровне, разработчики хотят видеть структуру хранилища отражающую их предметную область
А точнее - язык разработки.

Просто шедевр, сейчас у себя анонсирую.

[info]asinitsyn

June 10 2010, 13:17:37 UTC 1 year ago

Написал свое мнение по этому поводу

http://asinitsyn.livejournal.com/33307.html

Вкратце - последствия описаны верно, но у меня свой взгляд на причины.

[info]octo47

June 10 2010, 11:21:47 UTC 1 year ago

отлично. прямо в точку.

[info]gabaidulin

June 10 2010, 11:27:37 UTC 1 year ago

Отличный пост.

Но ведь были такие попытки(объектные стораджа, например, cache db)? Да и Завалишин чего-то подобное делает в своем Фантоме.

Но не пошло. Как вы думаете, почему?

[info]zamotivator

June 10 2010, 11:28:43 UTC 1 year ago

Re: Отличный пост.

Потому что забыты другие аспекты

[info]avnik

1 year ago

[info]avnik

1 year ago

[info]norguhtar

1 year ago

[info]a_v_m

1 year ago

[info]smagen

1 year ago

[info]metaclass

1 year ago

[info]norguhtar

1 year ago

[info]norguhtar

1 year ago

[info]norguhtar

1 year ago

[info]lionet

1 year ago

[info]norguhtar

1 year ago

[info]norguhtar

1 year ago

[info]norguhtar

1 year ago

[info]vitus_wagner

June 10 2010, 11:28:36 UTC 1 year ago

Это из серии "я хочу чтобы у меня все было, и мне за это ничего не было". А так не бывает. SQL хорош тем, что под ним лежит хорошая математика - реляционная алгебра. Эта математика накладывает на возможности представления довольно большие ограничения. Но эти ограничения являются платой за возможность эффективно оптимизировать запросы.

К сожалению, большинство разработчиков, хватающихся сейчас за NoSQL никогда в жизни не слышали слова CODASYL. Поэтому не знают, что история баз данных начиналась с объектно-ориентированных БД, где не было никаких ограничений. Но и искать было крайне затруднительно.

[info]zhengxi

June 10 2010, 14:14:07 UTC 1 year ago

> Но эти ограничения являются платой за возможность эффективно оптимизировать запросы.

Вот взять тот же пример с постами и коментами.
Там ровно наоборот получается - для реаляционного решения нужен индекс по всем коментам, поиск по которому не будет лучше логарифмического (а комментов много, так много, что они и на один сервер могут не поместиться).
При этом post_id используется только для связи поста и коммента.
Есть RDBMS которые это "поймут" и эффективно соптимизируют до O(1), до (неявного, скрытого от автора SQL-запросов) хранения указателей на комменты рядом с постом ?

> К сожалению, большинство разработчиков, хватающихся сейчас за NoSQL никогда в жизни не слышали слова

Еще есть слово IMS, IMS is reportedly IBM's highest revenue software product, and it continues to grow.
Вполне такой NoSQL.

[info]legolegs

1 year ago

[info]legolegs

1 year ago

[info]dmitriid

1 year ago

Deleted comment

Deleted comment

Deleted comment

Deleted comment

Deleted comment

Deleted comment

Deleted comment

Deleted comment

Deleted comment

Deleted comment

Deleted comment

[info]silly_sad

1 year ago

[info]metaclass

June 10 2010, 11:34:46 UTC 1 year ago

Я не понимаю, почему в SQL до сих пор нет типа поля результата "список"?
Т.е. делая запрос к таблице, мы одно из полей делаем подзапросом, выбирающим список из связанной таблицы и так его и возвращаем. Конечно, придется массово переделывать API, придумывать, как это все дело отобразить(и вставлять тоже) но "выбрать объект и его подчиненные объекты одним запросом" было бы весьма удобно.

[info]plumqqz

June 10 2010, 11:35:43 UTC 1 year ago

Ну как нет. Есть. Оракловые курсоры. В постгресе мне пришлось эмулировать.

[info]metaclass

1 year ago

[info]plumqqz

1 year ago

[info]plumqqz

1 year ago

[info]plumqqz

1 year ago

[info]plumqqz

1 year ago

[info]metaclass

1 year ago

[info]dartbear

1 year ago

[info]plumqqz

1 year ago

[info]plumqqz

1 year ago

[info]dartbear

1 year ago

[info]plumqqz

1 year ago

[info]dartbear

1 year ago

[info]plumqqz

1 year ago

[info]metaclass

1 year ago

[info]plumqqz

1 year ago

[info]metaclass

1 year ago

[info]metaclass

1 year ago

[info]plumqqz

1 year ago

[info]metaclass

1 year ago

[info]plumqqz

1 year ago

[info]metaclass

1 year ago

[info]avnik

June 10 2010, 11:36:12 UTC 1 year ago

На самом деле NoSQL с сериализоваными объектами будет рулить на этапе гаражного стартапа, когда только раскапываешь предметную область.
(дизайнит базу, которую еще раза три прийдется переделать на этом этапе просто дорого -- и по трудозатратам (если самому), и по деньгам (если нанимать DBA со стороны)

Да и индексы по общему полю в разных объектах иногда доставляют.
(zodb/zope например позволяют индексировать f(x) где x произвольный объект)

[info]stasikos

June 10 2010, 16:23:42 UTC 1 year ago

Есть несколько странных "гаражных стартапов" типа Twitter, которые начинали с SQL и ушли в NoSQL, я вот почитал-почитал тут кругом и так и не понял почему.

[info]ex_vdom

1 year ago

[info]velkerma

1 year ago

Deleted comment

Deleted comment

[info]metaclass

1 year ago

[info]metaclass

1 year ago

[info]109

1 year ago

[info]metaclass

1 year ago

Deleted comment

Deleted comment

Deleted comment

[info]metaclass

1 year ago

[info]metaclass

1 year ago

[info]metaclass

1 year ago

[info]metaclass

1 year ago

[info]metaclass

1 year ago

[info]metaclass

1 year ago

[info]metaclass

1 year ago

[info]metaclass

1 year ago

[info]silly_sad

1 year ago

[info]fantaseour

June 10 2010, 11:42:55 UTC 1 year ago

Класс.

Я на это обратил внимание, когда читал книжку Фаулера, про UML. Когда строишь диаграммы классов у тебя направленная ассоциация, это указатель. А когда переводишь это в таблицы, указатель, как правило разворачивается.

Т.е. был пост и массив ссылок на комменты, а появились комменты с id поста.

[info]norguhtar

June 10 2010, 12:00:45 UTC 1 year ago

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

[info]metaclass

June 10 2010, 12:05:08 UTC 1 year ago

Мне никак не читали, но после того как я это дело осилил, я стал ярым адептом реляционных моделей :) Но попытки натянуть сову на глобус использовать ORM не оставляю.

[info]norguhtar

1 year ago

[info]norguhtar

1 year ago

[info]norguhtar

1 year ago

[info]norguhtar

1 year ago

[info]metaclass

1 year ago

[info]norguhtar

1 year ago

[info]norguhtar

1 year ago

[info]nealar

1 year ago

[info]_winnie

1 year ago

[info]nuclight

1 year ago

[info]nuclight

1 year ago

[info]cd_riper

June 10 2010, 12:47:00 UTC 1 year ago

интересный пост, спасибо

[info]alexclear

June 10 2010, 12:49:27 UTC 1 year ago

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

[info]rainman_rocks

June 10 2010, 12:56:20 UTC 1 year ago

Мне кажется, Вы некоторым образом неправы. Умные слова здесь всего лишь средство. Я б затруднился свою мысль выразить при помощи неумных слов.

[info]alexclear

1 year ago

[info]alexclear

1 year ago

[info]tonybelol

1 year ago

[info]tonybelol

1 year ago

[info]plumqqz

1 year ago

[info]tonybelol

1 year ago

[info]plumqqz

1 year ago

[info]tonybelol

1 year ago

[info]suvlehim_takac

June 10 2010, 13:00:05 UTC 1 year ago

отлично написано, буду перечитывать на досуге

[info]kuntashov

June 10 2010, 13:26:23 UTC 1 year ago

Есть еще такая особенность SQL, связанная с этой самой Q - его декларативность, в то время как думать человеку проще императивно, в терминах "сделай это, потом сделай то".

Более-менее сложные запросы отлаживать на порядок сложнее аналогичных (по выдаваемому результату) императивных конструкций.

Поэтому ORM - это не только инструмент делать "структуру хранилища, отражающую их предметную область", но возможность решать задачу императивно (что многие с радостью используют, чаще закрыв глаза на вопрос производительности).

[info]norguhtar

June 10 2010, 13:48:26 UTC 1 year ago


Поэтому ORM - это не только инструмент делать "структуру хранилища, отражающую их предметную область", но возможность решать задачу императивно (что многие с радостью используют, чаще закрыв глаза на вопрос производительности).

Это скорее инструмент взвалить эту головную больше ORM или тех кто этот самый ORM могут настроить.

[info]dz

June 10 2010, 13:41:08 UTC 1 year ago

Всё это можно сказать куда короче: гемора с SQL много, а что мы за него получаем - ясно не всем.

[info]metaclass

June 10 2010, 13:43:14 UTC 1 year ago

Как минимум, мы получаем решение, которое могут понять большинство программистов и сторонних программ. А не непонятно чо выпускаемое непонятно каким стартапом.

[info]dz

1 year ago

[info]norguhtar

1 year ago

[info]plumqqz

1 year ago

[info]dz

1 year ago

[info]norguhtar

1 year ago

[info]dz

1 year ago

[info]norguhtar

1 year ago

[info]dz

1 year ago

[info]norguhtar

1 year ago

[info]norguhtar

1 year ago

[info]norguhtar

1 year ago

[info]norguhtar

1 year ago

[info]109

1 year ago

[info]dz

1 year ago

[info]nealar

1 year ago

[info]dz

1 year ago

[info]silly_sad

1 year ago

[info]inv2004

June 10 2010, 14:30:49 UTC 1 year ago

Вот с ходу не ясно:
почему Post { User, Comment[]}, а не User { Post[] {Comment[]} } например?

[info]rainman_rocks

June 10 2010, 14:34:28 UTC 1 year ago

Несущественно, вообще говоря. Можно и так и эдак, как в конкретной задаче удобнее. А скорее всего будет двусторонная связь.

[info]inv2004

1 year ago

[info]b00ter

June 10 2010, 16:35:18 UTC 1 year ago

Хорошо написал.
Правда программистам редко дают возможность выбирать. За исключением некоторых случаев.

[info]rainman_rocks

June 10 2010, 16:39:05 UTC 1 year ago

В полной мере - редко. Но у программиста часто есть возможность прополоскать мозги лиду/манагеру до той или иной степени.

[info]b00ter

1 year ago

[info]ivan_gandhi

June 10 2010, 23:24:21 UTC 1 year ago

O,так, короче, вся промлема в лемме Ионеды, в отсутствии сопряженных функторов степени и произведения. Ето поправимо, в теории.

[info]rainman_rocks

June 11 2010, 06:51:40 UTC 1 year ago

Вспоминается хороший анекдот: "теоретически, сынок, у нас есть два миллиона. А практически - две бляди в доме".

[info]boombick

June 10 2010, 23:35:01 UTC 1 year ago

Молодец, Костик, отличный пост!
Как раз начинаю смотреть в сторону NoSQL-решений именно из-за избыточности SQL-а. Проанализировав код, который я пишу, пришло понимание того, что SQL-я мне слишком много :)

[info]latrommius

June 11 2010, 06:58:44 UTC 1 year ago

Ну или тупо ещё один дополнительный запрос (что неприятно для производительности).

Весьма спорно.
А вообще, спасибо за ссылки в тексте.

Deleted comment

[info]rainman_rocks

June 11 2010, 21:35:28 UTC 1 year ago

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

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

[info]grey3

June 12 2010, 19:52:49 UTC 1 year ago

SQL vs NoSQL: а как всё-таки лучше?

Написал длинный вопрос в своём ЖЖ: SQL vs NoSQL: а как всё-таки лучше?

asinitsyn > "Как DBA с опытом,"
> zabivator > "3. Я программист, который занимается разработкой движков СУБД"
Хочу задать вопрос одновременно ОБОИМ собеседникам: как в реляционных СУБД, например MySQL, эффективно решить заданный в посте rainman_rocks "Зачем NoSQL программистам" пример: эффективно извлечь несколько записей с подзаписями-списками?


Хотелось бы получить заодно и ваш ответ там.

[info]grey3

June 14 2010, 19:05:59 UTC 1 year ago

Re: SQL vs NoSQL: а как всё-таки лучше?

Там же (SQL vs NoSQL: а как всё-таки лучше? Итоги дискуссии ) приведена идея, как можно убрать недостатки SQL на примере, аналогичном вашему, и соответственно лишить NoSQL части преимуществ "очевидности". Небольшая оптимизация базы и драйверов, плюс хороший пример в документации - и многие программеры поймут, как просто и эффективно реализовать вложенные массивы/списки в SQL. :)

[info]wolverrum

April 21 2012, 11:38:33 UTC 1 month ago

Хорошие грибы.
Много желающих, судя/ по каментам.

Create an Account
Forgot your login or password?
Facebook Twitter More login options
English • Español • Deutsch • Русский…