Как стать автором
Обновить

Комментарии 44

Идея интересная, хотя я SQL (язык, а не ACID-базы) очень не люблю за свою топорность уровня BASIC'а. Очень много слов, очень подробно там, где не нужно, и чем-то напоминает ассемблер.

Насколько я понимаю, гугловая logica как раз эту задачу и пытается решать.

Местами он многословен, согласен

У меня лично одна придирка к SQL и больше связана даже с различными IDE к нему - сначала пишется что извлекается, а потом откуда. И всякие автоподборы сразу становятся тяжеле, потому что шерстится вся база.

Раньше работал в компании, что строили IDE для SQL, как раз в команде code completion.

Мы там прошли через ад, что бы это подсказывать нормально(писал об этом в блоке Парсинг SQL и диалектов). В целом чаще, как мы выяснили набирают 'SELECT FROM tbl', а потом возвращаются в select list и указывают колонку. Когда сначала ставят * легче, потому что скрипт получается валидный, когда нет, все похуже.

Но в целом притензия здравая.

В разных проектах разные требования. Бывает кода подходит SQL, бывает когда NoSQL. Не нужно пытаться делать лишних обобщенией "всем нужен только SQL, NoSQL сжечь", или наоборот.

НЛО прилетело и опубликовало эту надпись здесь

Требования разные, но большую часть NoSQL действительно сжечь, просто за ненадобностью.

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

Отаются только отдельные случаи типа key-value и колоночно-ориентированных БД, но они настолько разные, что им тем более не нужен хайповый buzzword чтобы загрести их все под одну гребенку.

Если вы не наблюдали или не видели таких систем, это не значит что их нет. Я в своей практике последние 5-6 лет всё чаще вижу системы, которые полностью обходятся без реляционной БД. И тут не важно, комбинируют всё и вся, и key-value, и json (bson) и другие подходы. Тем более это же всё не только про хранение, но и про относительно (обычных классических БД) горизонтальное масштабирование из коробки, доступный и понятный шардинг и многое другое. Это могут обеспечить на хорошем уровне только крупные корпоративные БД типа Oracle для реляционных баз.

P.S. Да, очень много специалистов, которые неправильно работают с NoSQL системами, пытаются туда перенести свой опыт работы с SQL, либо радикально превращают в свалку данных, думая что так и надо.

Та наблюдали-то как раз многие. Один из примеров и приведён в моем комментарии. Наблюдать мало, надо чтобы потом оно еще и работало. А с этим обычно хуже.

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

Ну я разрабатывал и наблюдал как раз рабочие системы без реляционных БД. Всё прекрасно работает, в том числе на больших нагрузках и еще и масштабируется. Конкретно это всякие документно-ориентированные и колоночные бд типа MongoDB, ElasticSearch, Cassandra. Да это были не финансовые приложения, конечно, всякие контентные системы, что-то похожее на социальные сети, CRM, и т.п.

P.S. По поводу примера, если уж разработчики криво спроектировали модель данных для MongoDB, это не значит что она не работает, а заголовок отдает желтушностью и кликбейтом. Я завтра пойду, криво спроектирую модель данных для Postgresql, а потом напишу статью, какой pgsql плохой и не позволяет мне решить какие-то критические проблемы - и напишу статью с заголовком "Почему вы никогда не должны использовать PostgreSQL"

А что, так можно было? В смысле, спроектировать "прямую" модель данных для Монги? В смысле - нормальную реляционную, с уствновлением нужных связей, о которых говорится в статье? И даже перекладивание контроля целостности с БД на программиста - тоже не помеха?

А можете привести контрпример? Ну в смысле основную БД приложения на Монге, спроектированную "правильно"?

В каких случаях удобнее пользоваться NoSQL?

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

Интересно послушать примеры.

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

Ловите плюс! Отличная статья, пытаюсь то же самое доносить до людей

Небольшая претензия к форме, а не содержимому

Только в первом абзаце у вас с запятыми полнейший абзац. Пожалуйста, поправьте. Надеюсь, удалю этот спойлер через пару часов

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

Дополню за JSON в базах данных. Забавно, но тут возможны 2 разных JSON :) Обо всём по порядку:

  • JSON в качестве хранилища. Тема неоднозначная. Допустимо там, где мы данные не обрабатываем средствами СУБД. Как только нам прижало строить индекс по JSON -- рефакторить структуру БД надо было вчера

  • Преобразование в JSON во время SELECT. А вот тут я нашёл много вкусного в JSON_ARRAYAGG и JSON_OBJECTAGG. Как мне -- это удобный способ выжать максимум как из гарантий реляционной структуры, так и из удобства и производительности чтения

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

Кстати, помимо того же JSON многие реляционные базы поддерживают и разного рода объекты: массивы, словари или просто объекты с наборами полей.

P.S. Постарался поправить пунктуацию.

Nosql - это не только json. И видов nosql баз даже не два. И каждый под свою задачу.

Второй вопрос - взаимопроникновение моделей баз данных, когда над nosql строят вполне себе реляционную конструкцию (как в Cache), а в реляционку впихивают нечто графовое, документное или еще какое (в том же postgresql имеется возможности как минимум документной nosql базы данных).

Так что в простом противопоставлении реляционной и nosql модели (особенно без уточнения, какой именно nosql модели) становится все меньше смысла, хотя и раньше его было совсем немного.

Все-таки выбор субд определяется не всякими красивыми словами про ACID и SQL, а требованиями проекта.

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

Как правило, внутри каждого проекта есть данные целостность которых критична. Часто бывает, что целостностью каких-то данных можно принебречь. Если эта возможность как-то развяжит инженерам руки, то можно будет ею воспользоваться.

Если же можно получить и достаточную производительность и целостность всех данных, то лучше получить и то и другое. К тому же снизив сложность найма и упростив общение.

Как правило, внутри каждого проекта есть данные целостность которых критична.

Но бывает, когда другие моменты настолько важнее целостности, что ее контролем на уровне СУБД можно пренебречь.

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

С другой стороны некоторые nosql СУБД предоставляют свои средства для контроля целостности данных (та же IRIS от Intersystems).

Если же можно получить и достаточную производительность и целостность всех данных, то лучше получить и то и другое.

А если нельзя ?

К тому же снизив сложность найма и упростив общение.

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

Но бывает, когда другие моменты настолько важнее целостности, что ее контролем на уровне СУБД можно пренебречь.

Так действительно бывает. Можно попробовать ослабить гарантии в конкретной таблице, возможно этого будет достаточно. Если этого окажется недостаточно, то можно взять для этого конкретного набора данных какую-то более подходящую базу.

Втиснуть-то можно все, но результат превращается в неудобоваримую отвратительно поддерживаемую нелогичную дичь. 

Эти данные так же можно отложить в отдельную СУБД, более подходящую.

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

А если нельзя ?

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

А если забираться в дебри расширений языка от разных производителей СУБД...

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

Не понимаю, за что вас минусят.

Вот есть колоночные базы, зачем они вообще нужны? Очевидно, чтобы читать данные по всем строкам из одной колонки быстро (последовательно). Зачем нужны документные базы? Тоже очевидно, чтобы разом читать целый документ. Есть у них недостатки? Конечно есть, но есть и сценарии, где по-другому будет просто хуже.

А бывают ещё аналитические базы (типа Кликхауса или Друида), использовать вместо них реляционную на нормальной нагрузке просто не прокатит.

В итоге видим, что действительно сравненивать nosql и sql "в целом" абсолютно бессмысленно, они подходят для разных задач. Использовать условную Монгу там, где нужны гарантии и надёжность реляционных баз - глупо и больно. Но точно так же глупо использовать ПГ там, где он не подходит.

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

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

В пустыне встречаются осёл и прапорщик. 
Осёл:
— Ты кто?
Прапорщик посмотрел по сторонам, никого:
— Я офицер, а ты?
Осел посмотрел по сторонам:
— Тогда я — лошадь.

Вот и с noSQL так же.

Консультирую стартап, который решил пере-изобрести стандарт схемы американского банковского кредитования (MISMO). Получилось недоразумение. Обсуждаем переход на SQL.

Часто вижу сценарий:
- революционные идеи (в этой компании описание схемы через Graph DB + JSON),
- корректировка фантазий реалиями (в этой компании изобретение превращается в рассыпающиеся кусочки классов)
- переход на структурированные данные и обычную базку.

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

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

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

Apex :)

Не только можно, это очень популярная архитектура примерно с середины 1990-х годов - использование процедурного расширения SQL СУБД в качестве сервера приложений с тонким клиентом. Примеры, навскидку, "Босс-компания" (не путать с "Босс-корпорацией") и Ultima-Seller, перетекший в открытый код. Подробнее по ссылке.

Ну, существуют же DBD-приложения, где UI -- это морда для SELECT/CALL. Тот же Kondor+, например.
Клиентский доступ к данным только через вьюхи и хранимки. Вся бизнес-логика в хранимках и описана.

Основная проблема того, что называют NoSQL - в непроработанности моделей данных. Зная, что практически все они были известны в дореляционную эпоху (к моменту "великого спора" Кодда с Бахманом их было известно более 40), можно с основанием говорить о неполноте и даже о неполноценности.

Полнота SQL иллюстрируется просто. SQL-запрос над множеством возвращает множество, которое может быть обработано следующим SQL-запросом или подзапросом. В NoSQL даже созданные сверху SQL-подобные языки так не могут, и проблема не в языках, а в модели данных и замкнутости операций. Для выборки, которую не обработать одним запросом, нужно писать программу (здравствуй, Питон). Исключение - KeySQL, где эта теоретическая проблема решена.

Для начала бы рассказали, какого типа NoSQL системы вы имеете ввиду - документно-ориентированные, колоночные, графовые, key-value и т.д. И с какими из них работали. А то похоже на то, что вы поделили всё на черное (NoSQL) и белое (SQL).

P.S. А вижу в тегах MongoDB... ну тогда советую попробовать и другие nosql системы.

Согласен.
Например Paradox - покойник - вполне себе реляционный, хоть и не умеет SQL. :)

Всё так, но вы немного путаете тёплое с мягким.

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

Почему MongoDB, Cassandra и стопиццот других платформ не реляционные? Потому, что реализовать SQL на распределённой системе сложно. То есть неполноценный интерфейс – это плата за распределённость.

Тем не менее, есть и реляционные распределённые СУБД – например, Cockroach. Он вроде как декларирует ACID, но ценой производительности.

Есть в природе и нереляционные монолитные СУБД. Например, GT.M. Зачем их использовать – загадка, потому что SQL реально удобен.

Есть, конечно, и распределённые реляционные СУБД с полноценным ACID – Greenplum, Teradata, Microsoft PDW... Но тут мы уходим вбок по третьей оси – OLTP/OLAP :)

Здесь ещё хочется добавить что сам по себе акроним ACID — очень странный, у него нет строгого смысла за пределами интуиции "как в популярных RDBMS".

В случае Distributed SQL баз (тот самый Cockroach, YugabyteDB, TiDB и прочие) обычно говорят более строго про strict serialisability — эквивалентность наблюдаемого состояния какому-то серийному исполнению, а так же упорядочивание неконкурентных операций в соответствии с их порядком в реальном времени.

О да, если начать детально разбираться, кто что имеет в виду под тем или иным термином, то можно заниматься этим всю оставшуюся жизнь :)

Для nosql и распределенных баз придумали BASE:

  • базовая доступность (англ. basic availability) — каждый запрос гарантированно завершается (успешно или безуспешно).

  • гибкое состояние (англ. soft state) — состояние системы может изменяться со временем, даже без ввода новых данных, для достижения согласования данных.

  • согласованность в конечном счёте (англ. eventual consistency) — данные могут быть некоторое время рассогласованы, но приходят к согласованию через некоторое время.

При возможности выбора СУБД на этапе проектирования проекта надо все таки рассматривать как SQL так и NoSQL варианты. Чтобы потом не пришлось "Совой о пень".

Вот пример из текущего проекта - данные(сотни миллионов строк) содержатся в JSON полях (размер которого бывает до нескольких Мб, неструктурированное дерево с десятком уровней). Изначально был выбран Postgres - ну а потому что знали его больше. А теперь поняли всю глубину промаха - суть еще в том что данные постоянно апдейтятся - миллионы строк в день. А что такое апдейт jsonb поля? это сложный процесс по распаковке в память из xact хранилища, поиску ключа + mvcc ... Параллельно работает до 1000 пользователей. А наши дата-саентисты еще это все в hadoop пытаются запихнуть.

И что решили в итоге? Таки нормализовать это jsonb гуляй-поле? Или вывести его на новую высоту и взять сервис, который из одного джейсона и состоит?

Пока смотрим в сторону колоночных СУБД.

Анализируем каждую на предмет производительности в нашем случае.

Эээ... Честно говоря, я вообще не понимаю, как можно "неструктурированное дерево с десятком уровней" конвертировать в колоночную, т.е. строго структурированную БД.

Видимо, данные изначально были вполне структурируемые, но их, как это обычно бывает, поленились нормализовать :)

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

Принцип garbage in - garbage out никто не отменял. Если вы не можете контролировать чистоту данных при записи в БД, то вам придется делать это потом, при каждом запросе на их извлечение из БД. Это раз. Для подхода "храним все, что прилетает" у вас нет разделения "болота данных" и витрин, это два. 1000 пользователей никогда не работают одновременно над всеми данными, это три.

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

Ему тяжело, но он справляется(рекурсивные CTE)

На практике работал с такими данными, но обычно они обрабатывались до +/- реляционных до попадения в базу.

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

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

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

Хотя, в целом, автора поддерживаю в идее SQL-first и негативе в засиилии nosql подходов там, где это не нужно, применяемых бездумно не к месту. Это просто практичнее. Сковывать себе руки и повышать вероятность отказов без нужды, конечно, глупо.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации