В последнее время, как видим, пошла мода на 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 же приходится прибегать к несложной, но раздражающей магии, типа джойнов/подзапросов. Ну или тупо ещё один дополнительный запрос (что неприятно для производительности).
А вот беда вторая, более серьёзная: вложить список в кортеж ещё труднее. Для этого нужны обратные ссылки. Поясню на примере.
Делаем платформу для блогов. У нас есть три основные таблицы - пользователи, посты и камменты. Ясное дело, что в нашей программе, отображающей страницы блога, посты логичнее всего будут представлены следующим типом:
Но в реляционной БД у нас всё будет иначе. Поле comments из таблицы Post пропадёт, а вместо него в таблице Comment появится поле post_id. А список комментов для конкретного поста будет находиться выборкой по данному полю.
Конечно же, по этому полю будет сделан индекс. Разумеется, выборки будут производиться достаточтно быстро. Но! неприятный психологический факт остаётся неприятным психологическим фактом: совершенно обычные, привычные каждому программисту списки в реляционных БД искажены до неузнаваемости и хранятся в неявном виде, где-то в индексах.
(Заметим, что способы впихнуть списки в кортеж всё-таки есть: например, поле-массив в PostgreSQL или строковой суррогат в MySQL, которым, подозреваю, многие веб-девелоперы малодушно грешат. Но использование их неудобно, связано с ограничениями и вообще не "feels right")
Это раздражает. При переходе из кода в SQL программисту приходится выворачивать мозг наизнанку. Он не чувствует привычного контроля над структурами данных. Знакомые алгоритмы искажаются. Более того, ему не совсем понятно, для чего это нужно.
Зато смотрящему с RDBMS-башни наблюдателю всё, конечно, понятно. Реляционная система хранения оптимизирована для запросов (буква Q в SQL недаром стоит в центре). Перевод списков в индексы превращает упорядоченную структуру данных, привычную программисту, в некоторое аморфное облако, из которого при помощи запросов волшебно извлекаются разнообразные представления. Приверженцам классических RDBMS вообще непонятно как в NoSQL можно делать выборки.
Выборки, тем не менее, в NoSQL делать можно. Просто те же самые индексы вы создадите руками. В нашем примере с блогом, если вам понадобится упорядочивать камменты не только по дате, но и по, например, рейтингам (как это делают на stackoverflow), вы просто добавите в каждый пост ещё один список:
Дублирования данных не будет - это же просто список указателей, по объёму равный тем же индексам.
Короче, вопрос вполне решаем. Просто вся эта возня с индексами (включая их обновление при изменении данных и поддержку консистентности) теперь ложится на плечи программиста. И программист готов платить такую цену. Потому что он, сука, хочет САМ КОВЫРЯТЬСЯ В СВОИХ ПРИВЫЧНЫХ СТРУКТУРАХ ДАННЫХ. А не доверять сложной магии планировщика запросов и его непонятно где спрятанным индексам.
Повторюсь, в ORM стараются решить как раз именно две эти проблемы: автоматическое превращение foreign key в связанную структуру данных (вместо post.user_id => post.user), и превращение обратного foreign key в список (вместо comment.post_id => post.comments).
Именно это мне и кажется причиной недовольства SQL среди разработчиков, и основной причиной попыток бегства с него. Чтобы спасти репутацию SQL, эти проблемы надо как-то элегантно решить - будь то на уровне БД или API доступа к ней.
Благодарю за внимание.
Термин, собака, размыт до черезвычайности, под ним все подразумевают разное, кто во что горазд - кто-то интересуется переработанными RDBMS типа BigTable, кто-то болеет за key-value storage, парни с PostgreSQL вообще пошутили на тему QUEL.
Сконцентрируемся всё-таки на основном значении: системы хранения данных вида key-document. Популярность оных вот свирепо обсуждает с организационной точки зрения zabivator (краткий пересказ: nosql это всё пионерские игрушки, люди просто
У меня на счёт причин этого феномена есть интересная теория.
Люди, как верно замечено, по зову души уходят от 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/121
UPD-3: ВНЕЗАПНО выяснилось, что практикующие со мной тоже в целом соглашаются: http://ivan.begtin.name/2010/06/11/%D1%8
June 10 2010, 11:10:39 UTC 1 year ago
А точнее - язык разработки.
Просто шедевр, сейчас у себя анонсирую.
June 10 2010, 13:17:37 UTC 1 year ago
http://asinitsyn.livejournal.com/33
Вкратце - последствия описаны верно, но у меня свой взгляд на причины.
June 10 2010, 11:21:47 UTC 1 year ago
June 10 2010, 11:27:37 UTC 1 year ago
Отличный пост.
Но ведь были такие попытки(объектные стораджа, например, cache db)? Да и Завалишин чего-то подобное делает в своем Фантоме.Но не пошло. Как вы думаете, почему?
June 10 2010, 11:28:43 UTC 1 year ago
Re: Отличный пост.
Потому что забыты другие аспекты1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
June 10 2010, 11:28:36 UTC 1 year ago
К сожалению, большинство разработчиков, хватающихся сейчас за NoSQL никогда в жизни не слышали слова CODASYL. Поэтому не знают, что история баз данных начиналась с объектно-ориентированных БД, где не было никаких ограничений. Но и искать было крайне затруднительно.
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.
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
Deleted comment
1 year ago
Deleted comment
1 year ago
1 year ago
Deleted comment
1 year ago
Deleted comment
1 year ago
Deleted comment
1 year ago
1 year ago
Deleted comment
1 year ago
Deleted comment
1 year ago
1 year ago
Deleted comment
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
Deleted comment
1 year ago
Deleted comment
1 year ago
Deleted comment
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
June 10 2010, 11:34:46 UTC 1 year ago
Т.е. делая запрос к таблице, мы одно из полей делаем подзапросом, выбирающим список из связанной таблицы и так его и возвращаем. Конечно, придется массово переделывать API, придумывать, как это все дело отобразить(и вставлять тоже) но "выбрать объект и его подчиненные объекты одним запросом" было бы весьма удобно.
June 10 2010, 11:35:43 UTC 1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
June 10 2010, 11:36:12 UTC 1 year ago
(дизайнит базу, которую еще раза три прийдется переделать на этом этапе просто дорого -- и по трудозатратам (если самому), и по деньгам (если нанимать DBA со стороны)
Да и индексы по общему полю в разных объектах иногда доставляют.
(zodb/zope например позволяют индексировать f(x) где x произвольный объект)
June 10 2010, 16:23:42 UTC 1 year ago
1 year ago
1 year ago
1 year ago
Deleted comment
1 year ago
Deleted comment
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
Deleted comment
1 year ago
Deleted comment
1 year ago
1 year ago
Deleted comment
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
June 10 2010, 11:42:55 UTC 1 year ago
Я на это обратил внимание, когда читал книжку Фаулера, про UML. Когда строишь диаграммы классов у тебя направленная ассоциация, это указатель. А когда переводишь это в таблицы, указатель, как правило разворачивается.
Т.е. был пост и массив ссылок на комменты, а появились комменты с id поста.
June 10 2010, 12:00:45 UTC 1 year ago
June 10 2010, 12:05:08 UTC 1 year ago
натянуть сову на глобусиспользовать ORM не оставляю.1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
June 10 2010, 12:47:00 UTC 1 year ago
June 10 2010, 12:49:27 UTC 1 year ago
June 10 2010, 12:56:20 UTC 1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
June 10 2010, 13:00:05 UTC 1 year ago
June 10 2010, 13:26:23 UTC 1 year ago
Более-менее сложные запросы отлаживать на порядок сложнее аналогичных (по выдаваемому результату) императивных конструкций.
Поэтому ORM - это не только инструмент делать "структуру хранилища, отражающую их предметную область", но возможность решать задачу императивно (что многие с радостью используют, чаще закрыв глаза на вопрос производительности).
June 10 2010, 13:48:26 UTC 1 year ago
Поэтому ORM - это не только инструмент делать "структуру хранилища, отражающую их предметную область", но возможность решать задачу императивно (что многие с радостью используют, чаще закрыв глаза на вопрос производительности).
Это скорее инструмент взвалить эту головную больше ORM или тех кто этот самый ORM могут настроить.
June 10 2010, 13:41:08 UTC 1 year ago
June 10 2010, 13:43:14 UTC 1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
June 10 2010, 14:30:49 UTC 1 year ago
почему Post { User, Comment[]}, а не User { Post[] {Comment[]} } например?
June 10 2010, 14:34:28 UTC 1 year ago
1 year ago
1 year ago
June 10 2010, 16:35:18 UTC 1 year ago
Правда программистам редко дают возможность выбирать. За исключением некоторых случаев.
June 10 2010, 16:39:05 UTC 1 year ago
1 year ago
June 10 2010, 23:24:21 UTC 1 year ago
June 11 2010, 06:51:40 UTC 1 year ago
June 10 2010, 23:35:01 UTC 1 year ago
Как раз начинаю смотреть в сторону NoSQL-решений именно из-за избыточности SQL-а. Проанализировав код, который я пишу, пришло понимание того, что SQL-я мне слишком много :)
June 11 2010, 06:58:44 UTC 1 year ago
Весьма спорно.
А вообще, спасибо за ссылки в тексте.
Deleted comment
June 11 2010, 21:35:28 UTC 1 year ago
Это был однократный эффект, не уверен что смогу/захочу его закрепить.
June 12 2010, 19:52:49 UTC 1 year ago
SQL vs NoSQL: а как всё-таки лучше?
Написал длинный вопрос в своём ЖЖ: SQL vs NoSQL: а как всё-таки лучше?asinitsyn > "Как DBA с опытом,"
> zabivator > "3. Я программист, который занимается разработкой движков СУБД"
Хочу задать вопрос одновременно ОБОИМ собеседникам: как в реляционных СУБД, например MySQL, эффективно решить заданный в посте rainman_rocks "Зачем NoSQL программистам" пример: эффективно извлечь несколько записей с подзаписями-списками?
Хотелось бы получить заодно и ваш ответ там.
June 14 2010, 19:05:59 UTC 1 year ago
Re: SQL vs NoSQL: а как всё-таки лучше?
Там же (SQL vs NoSQL: а как всё-таки лучше? Итоги дискуссии ) приведена идея, как можно убрать недостатки SQL на примере, аналогичном вашему, и соответственно лишить NoSQL части преимуществ "очевидности". Небольшая оптимизация базы и драйверов, плюс хороший пример в документации - и многие программеры поймут, как просто и эффективно реализовать вложенные массивы/списки в SQL. :)1 year ago
April 21 2012, 11:38:33 UTC 1 month ago
Много желающих, судя/ по каментам.