Pull to refresh

Comments 105

Великолепный репортаж из параллельной вселенной: «баз до 70х не было, SQL и noSQL появились на голом месте, целая история суперкомпьютеров ориентированных на обработку баз данных и упор на централизацию знаний вышвырнули из реальности, истории с затыком IBM на естественные языки и COBOL не было, и кодасил к nosql никак не относится...» и как там во вселенной самопроизвольных вспышек и озарений?!
А у нас все иначе, озарений не было, был исторический процесс, войны моделей и стандартов, война инженерии с маркетингом, и окончательная победа маркетинга и виртуализации реальности.
Приторный привкус эпичности после прочтения статьи.

Тот редкий момент, когда пропустив половину истории получается не укорочённая версия, а совсем другая история и другие выводы.
Особенно доставило, что про джойны(которые в случае острой необходимости довольно прямо лепятся поверх любого kv-хранилища) есть, а про распределенные транзакции, в которые все реляционки очень бодро упираются — нет.


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

А почему вдруг стало проще расти вертикально? Тактовая частота не растет уже лет 10 (еще и падать начала у многоядерных E5 к примеру, из годам в год), системы с больше, чем четырьмя сокетами стоят космических денег (правда, может intel scalable family исправит ситуацию, хз). С облаками так вообще, надо уметь горизонтально масштабировать.

Из реальной практики, была задача год назад, где надо хорошую однопоточную производительность на серверном железе обеспечить. Взяли e5-2643v4 (3.4 GHz частота, максимум, что есть на рынке). На домашних дешевых процессорах куда веселее цифры, увы.

Потому что инстанс с терабайтом озу стоит семь баксов в час?
Есть ощущение, что это очень сильно уменьшает потребность в горизонтальном масштабировании.

Да, посмотрел, есть такое. Заодно приятно удивлен, что в облаке можно арендовать систему с 4 * E7-8880V3, не знал.

А зачем вы упираетесь в тактовую частоту?


Я вот сравнивал core i7-2600 6-летней давности и порезанный core i5-2.0 из макбука — они по производительности на ядро идут нога-в-ногу уже (отличаясь по тестам ровно в два раза по multi-core, что соответствует разнице в количестве ядер). При этом i5 в 10 (десять!) раз энергоэффективнее.

Тест-тесту рознь. Мне кажется, что вы немного приукрашиваете ситуацию.95W vs 15W у i5-6300U это не десятикратная разница, а 6. Учитывая двукратную разницу в ядрах — уже в 3. Достигается за счет невысокой тактовой частоты. При росте тактовой частоты потребление растет нелинейно. Рост производительности в расчете на ядро — да, заслуживает уважения. Но опять же, 6300U слабее в значительном числе тестов. На 10-20%.
подключать NoSql базы данных к приложениям было сложнее, что заставляло писать тонны неустойчивого связующего кода;
— Java + MongoDb = просто добавить три строки кода(депенденси), все работает и устойчиво

Это наверное потому, что связующий код уже написали за вас.

Вы хотите предложить всем писать собственный связующий код с sql базами?

sarcasm mode on
Конечно!
Во-первых это красиво.
sarcasm mode off

"Narrow waist" не надо переводить как "узкое место". "Узкое место" в техническом сленге носит ярко выраженный негативный оттенок, ближайший аналог в английском это "bottleneck". Узкое место — это плохо, его надо или ликвидировать, или обойти.


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

Забавно, что как сетевики пытаются съехать с IPv4 на IPv6, так и программисты тяготеют к созданию локальных коммьюнити. Выглядит так, будто "narrow waist" это вынужденная мера, от которой при необходимости попытаются избавиться.


Надо ли адаптировать SQL как "narrow waist" в данных, когда там и так справляются многообразием технологий и языков? Получается, вопрос весьма дискуссионный.

нас учили, что есть три модели данных: иерархические, сетевые (более гибкие), и реляционные (более удобные и которые вытеснили остальные). И насколько я понимаю, то что сейчас называется документоориентированными системами это и есть иерархические системы представления данных (MongoDB, CouchDB..), т.е хорошо забытое старое
но все такие есть еще один подход, который правда базой не назвать. из парадигмы бигдата. k-v хранилище с табу на update/delete. в value храниться сложный объект (например avro-parquet). учитывая, что это все заморочено ради параллельной обработки, то все таки это нечто новое и мало похожее на все, что было ранее.
UFO just landed and posted this here
ничего общего. иерахические это ничем не примечательны. одна нода, нафигация по иерархии, update/delete, блокировки, транзакции и прочее. то о чем я говорю из другого мира. тысячи нод и просто файлики, никаких транзакций, update/delete, блокировок и прочего. в файликах просто ключь-значение. это и не субд даже, это подход.
UFO just landed and posted this here
во первых k-v хранилище не иерархия, во вторых если я натолкаю в dbf таблички ссылку на парент, фокспро не превратиться в иерархическую субд.
там все реально по другому. суть иерархической субд — нафигация по индексу, суть того о чем я говорю противоположна. там зачастую читают абсолютно все данные начала времен.
UFO just landed and posted this here
30 лет назад никому в голову не приходило читать параллельно с тысячи нод принципиально все данные, абсолютно все субд тогда доставали данные по индексу и соревновались методиках сокращения кол-ва чтений. что иерархические, что рсубд.
UFO just landed and posted this here
да, они работают ровно так же как и 30 лет назад. что рсубд, что нафигационные. поэтому подход читать в параллель все без разбору, не разбираясь нужно или не нужно выглядит чем-то новым. 30 лет назад о таком никто и помыслить не мог.
UFO just landed and posted this here

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

Вам нужно отзеркалить КДПВ. Обычно все хорошие бегут направо, все плохие налево. На вашей картинке Рэй готовится погибнуть от меча товарища с ушами.

После длительного увлечения NoSQL, я начинаю задумываться о том же. Колоночные NoSQL со всей их спецификой (гиганские объемы данных, данные очень регулярны, потери отдельных строк не важны) имеют права на жизнь, но для всего остального проще использовать SQL


  • современные SQL базы не медленны — постгрес на слабой машине тянет тысячи запросов по денормализованной таблице в секунду
  • с большим кол-вом данных проблем тоже нет
  • в 21 веке не нужно уродовать структуру и индексы для аналитических запросов — данные просто экспортируются в любимую колоночную СУБД или индексатор
  • шардинг средствами современных технологий легко реализуется на стороне клиента
  • с availability сложнее, но значительно проще, чем раньше
    И помимо этого, SQL базы дают транзакции, мощный язык запросов, качественные атомарные бэкапы, проверенный временем мониторинг, аудит и средства восстановления после аварий.
а как добавление sql иниерфейса связано со смертью nosql хранилищь? то что им добавили sql интерфейс их не сделало реляционными базами данными
Как минимум понятие NoSQL теряет смысл. На сколько я понимаю в принципе, грубо говоря (в каждой конкретной реализации свои нюансы, конечно) NoSQL-база — это база со скромным индексированием (индексируется только первичный ключ) и без SQL в качестве языка запросов. SQL в NoSQL добавили (т.е. уже оксюморон), индексированием в «обычных» СУБД можно управлять достаточно гибко, индексировать и нормализовывать всё никто не заставляет, возможность оперировать данными, храняшимися в форматах XML и JSON уже давно можно. Осталось добавить в стандартную поставку классических СУБД HTTP-интерфейсы и всё, со стороны приложения никакой принципиально разницы уже нет, разница останется только на уровне реализации конкретных хранилищь.

Для SQL РСУБД само собой подразумевается наличие ACID. С этим у NoSQL все очень плохо, поддержку ACID заявляют только мифический Google Spanner, глюкавый OrientDB и ныне почивший FoundationDB. Языковая обертка совсем не спасает — SQL в NoSQL используют почти исключительно для OLAP.


В другую сторону, для NoSQL часто подразумевается почти линейная масштабируемость и shared-nothing. С этим у классических РСУБД все очень плохо — транзакционный движок это нерасширяемый SPOF, мастер-мастер репликация это безнадежно, универсальное шардирование не совместимо с контролем строгости внешних ключей и т.п.

Для SQL РСУБД само собой подразумевается наличие ACID.

Спорное утверждение. В общем, конечно, как бы да, но строго говоря не обязательно, ACID — это всего лишь фича, которая может быть, а может отсутствовать. Сам, например, прекрасно живу с энджином Aria (улучшенный MyISAM) в некоторых bigdata (но не hiload) проектах с MariaDB — вполне себе классический SQL, но без ACID и шурует достаточно быстро по сравнению с InnoDB на больших таблицах.

А вообще ваши доводы, конечно, ясны, всё так, да.

На заре хайпа про NoSQL у этой аббревиатуры было еще одно значение — Not Only SQL. Что идеологически гораздо более правильно, но вот только про хорошие примеры SQL + что-то ещё в одном флаконе мне неизвестно.

NoSQL-база — это база со скромным индексированием (индексируется только первичный ключ)

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

NoSQL — это отсутствие SQL. А что там индексируется или не индексируется, это вопрос отдельный. Никто не мешает создавать и поддерживать любые индексы. SQL — это просто язык запросов.
Мне кажется «А. Версия в реляционной алгебре» выглядит в сто раз лучше, чем «В. Версия в Sequel (SQL)». Давно мечтаю о таком языке запросов, как в этой версии А. Ради такой лаконичности определённо стоит изучить несколько специальных значков и добавить их в раскладку клавиатуры (благо это в наше время очень легко). Особенно если учитывать, что в наше время неспособные на это «пользователи, не прошедшие курс математики или компьютерного программирования» запросы всё-равно не пишут, а работают исключительно через создаваемые для них программистами GUI.
Блин, прямо восторг от варианта A, вот смотрю и прямо «кипятком ссу». Хочу-хочу. Можно такую нотацию к каким-то современным СУБД прикрутить как-то? И нет, я ни разу не математик.
UFO just landed and posted this here

Так о чем же в итоге статья — о языке запросов SQL или о реляционной модели хранения данных, в которой этот язык применяется. Spanner, к примеру, не реляционка, но при этом использует SQL.
А мы вот, например в своей NoSql СУБД используем модифицированные XQuery и XUpdate, и очень довольны. Запросы проще и выразительней чем SQL на порядки. Пользователи легко осваивают язык за пару недель. Прикручивали SQL, но разработчики не приняли после XQuery, не стали развиваить.

Наверное, стоит разделить слой хранения данных и слой DML.
В Oracle, строго говоря, данные хранятся не в плоской таблице, а в дереве, но это не делает его NoSQL СУБД. Слой хранения может быть разным — может быть на одном узле как в MySQL, может быть на распределенном block storage, как в Aurora, может быть размазан по многим узлам, как в CockroachDB или Spanner. Значение имеет всё же интерфейс взаимодействия.
И реляционная модель ни слова не говорит про хранение — это логическая модель данных, не физическая, которая просто утверждает, мы можем оперировать с данными как с множествами кортежей, и можем пользоваться булевой алгеброй для задания предиката, применение которого вернет множество нужных элементов.


Запросы проще и выразительней чем SQL на порядки
модифицированный XQuery

а можно пример, пожалуйста? Интересно стало.
Просто всегда думал, что XML — это не тот язык, который могут писать живые люди.

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

Всё есть, пусть и специфичное для базы. Хинты, select for update, WITH ROWLOCK и т.п.

Я говорю про то что в стандарте SQL этого нету, и в такой БД как Postgres то же нету. Мы же сейчас про язык, а не про конкретные хаки вашей СУБД. Хаки я и сам знаю, только не легче от них от перехода одной бд к другой.

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

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

Он так и задуман, чтобы переложить на автоматический оптимайзер всю сложность с оптимизацией по правильному доступу к данным. Иногда не работает — верно, и тогда сделать почти ничего нельзя. Но тогда нужно просто брать другой инструмент )

Вот здесь я склонен немного не согласиться, потому что
или часто правильно написанный +0 при джойне в Firebird,
или грамотно подсунутый хинт индекса в MySQL,
или грамотно построенный индекс для MS SQL,
или грамотно переписанный запрос с использованием фишечек (оконные функции, CTE) в PostgreSQL,
или переписывание запроса на (о ужас :-) ) хранимую процедуру PL/SQL с простой линейной логикой (привет, Oracle),
способны исправить любую глупость оптимизатора.
И это всё тоже остаётся в рамках SQL (за исключениме хранимых процедур разве что).
Проблема в другом — эти решения применимы только для конкретного движка СУБД, т.е. имеем примерно такую же фигню как с NoSQL — для эффективной работы с каждым хранилищем данных приходится как-то по-особенному приседать — писать запросы, продумывать структуру таблиц, что развеивает миф о возможности существования всемогущего, одинакового для всех БД, языке.

Ну да, это иллюзия универсальности.

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

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

UFO just landed and posted this here
Ужас какой. Абсолютное непонимание предмета обсуждения.

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

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

Я скорее про реализацию, толку от языка, который если хочется чего то предсказуемого по скорости, приходится писать под каждую СУБД свой запросс?
Даже тут https://ru.wikipedia.org/wiki/%D0%A3%D1%80%D0%BE%D0%B2%D0%B5%D0%BD%D1%8C_%D0%B8%D0%B7%D0%BE%D0%BB%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%BD%D0%BE%D1%81%D1%82%D0%B8_%D1%82%D1%80%D0%B0%D0%BD%D0%B7%D0%B0%D0%BA%D1%86%D0%B8%D0%B9 немного написанно про то что в мало каких СУБД это уровни реализованны строго по стандарту…
Есть же вроде устойчивое мнение что Read committed в Postgres это Repeatable read в Oracle.


И вы зря про SQLite это очень мощная СУБД и наглядный пример как можно использовать язык SQL (особенно их "компидятор" запроссов). И по колличеству инсталяций + работающего софта это наверная самая популярная СУБД в мире.

Конечно, посчитать все андроид-девайсы — будет самой популярной :-)
Я скорее к тому, что в SQLite нет как таковой необходимости иметь уровни изоляции — это по дизайну встраиваемая БД для локального применения в рамках одного процесса.
Там нет и хранимых процедур, и многопользовательского доступа по примерно тем же причинам. Это просто библиотека (не СУБД) с SQL-like синтаксисом. Очень полезная в хозяйстве, надо сказать. Отдельно хочется похвалить автора за его любовь к автотестам.

Если я правильно помню, то хранимок нету и в MySQL/MariaDB и это никакого отношения к SQL не имеет. А так наверное да, но это всёравно применение SQL языка.

в MySQL и MariaDB есть хранимые процедуры.
Кривые, косые, но есть. Тоже не от хорошей жизни они там появились =)
Я имел ввиду, что SQLite нельзя назвать "взрослой" клиент-серверной СУБД, которая умеет работать с большим объёмом данных и большим числом одновременных клиентов.

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

Кстати, это не очень связано с невозможностью работать с большими данными. Размер данных зависит от возможностей файловой системы.

По первому абзацу целиком и полностью согласен.


Кстати, это не очень связано с невозможностью работать с большими данными. Размер данных зависит от возможностей файловой системы.

Что есть большие данные? Я раньше слышал определение — они не влазят в ни в один из доступных на массовом рынке серверов. И там далеко не только в файловой системе возникают проблемы.

UFO just landed and posted this here
По моему NoSQL просто занял ту нишу для которой он предназначен. Какое то время это был модный тренд, как часто бывает в ИТ. Просто потому что разрабы постоянно ищут какую то серебряную пулю, которая одним махом решит проблемы разработки.
Накинулись на NoSQL но чуда, как обычно, не произошло и все стало на свои места.

Собственно если так подумать, то главная претензия к самому языку это отсуствие вменяемого синтаксиса (точно не как в новом стандарте) для доступа к сложным иерархиям внутри одного поля (документа). Если бы это было, то и Эластиксёрч с Монгой можно было бы перевести на этот язык.
ЗЫ хотя если так подумать, к примеру вложенные группировки в Эластике явно выглядят приятнее чем нагромождение которое будет в SQL.

Это я поро применимость SQL в документо ориентированных БД.

Думаю дело не в языке а в реляционных отношениях между данными. Природа данным мало изменилась с 70х годов. изменилось только количество. Просто добавилась ниша для nosql в виде огромного количества мелких не связанных глубокими реляциями (и не требующих, соответственно, витиеватых выборок) данных.
Кеширование, сообщения в соцсетях и месенжерах и т.д. Собственно и есть ниша NoSQl.
SQL (и SPARQL) позволяют сформировать очень сложные запросы, которые долго выполняются и тормозят другие запросы. Если ограничиться простыми запросами, то SQL по производительности не особо уступает NoSQL решениям. Основная проблема — заставить себя (и коллег) ограничиться простыми запросами.
это типа заставить всех вместо компьютеров пользоваться калькуляторами. Если данные(бизнес-сущности) по своей природе сложные и находятся объективно в реляционных отношениях а заказчик требует мудрёный репорт, то то никуда не денешься. Разве что, в разумных пределах, денормализовать данные заплатив за это увеличением их объема.
Ну, а все-таки, что теперь будет? Обновленный и расширенный новый стандарт SQL, с поддержкой агрегатов (тип CUBE), и что-то для работы иерархиями, или шире … с графами? Может какое-то обобщение с MDX, или GraphQL?

SQL остаётся хорошим для статической модели данных. Там же где данные ненормализованные, либо очевидно, что модель будет и должна меняться, он излишне строгий.
Любой SQL всегда работает поверх набора внутренних методов доступа к данным — поверх не-SQL. При этом слой SQL потребляет огромное количество вычислительных ресурсов, как паямти, так и процессора. В документации самого оракла говорится, что использование SQL безусловно оправдано только в случае динамической базы данных — когда схема (структура кортежей и отношений) непостоянна и меняется в процессе работы приложения. В случае же статической схемы данных в каждом конкретном случае нужно рассматривать применение SQL только в том случае, если требуется быстро выпустить приложение, невзирая при этом на производительность. По их словам производительность не-SQL решений (NoSQL, BDB) обычно в десять и более раз выше, чем SQL, при этом затраты на разработку вырастают всего лишь в разы.
Так что не-SQL пока ничто не грозит, как никогда и не грозило.
однако тот же postgresql кое где даже немножко быстрее большинкства nosql решений.
например в класическом доступе по индексу.

Как минимум они делают разные вещи внутри этого доступа. Собственно prepare statement не от хорошей жизни появился так что SQL имеет существенный оверхед особенно если в нём перечисленно много "таблиц".

в nosql со «много таблиц» не очень гладко, да и с хитрыми индексами.

Но это не результат отказа от SQL, а скорее ориентированность на их ниши.
На самом деле встроить SQL парсер и написать к нему оптимизатор это не такое простое занятие, куда проще (не факт что лучше) использовать JSON который повторяет ваши внутрении абстракции.

если сравнивать такиеже элементарные запросы какие возможны в nosql — то парсер моментально отоабатывает.
а вот оптимизатор и планировщик могут подзадуматся.
поэтому подготовленые запросы есть и хранимые процедуры.
и опять же план запроса в большинстве sql систем кешируется
Ну да, всегда есть тормознутые тривиальные решения.
Тем неменее, большинство NoSQL на порядок (SiC!!!) быстрее, чем SQL при решении 90% наиболее распространенных задач. Если быть точнее, то если в приложении нет оператора altertable, имеет смысл подумать — а какого тут делает SQL? Реально вопрос только в затратах на разработку — на SQL дешевле и к программисту требования на уровне плинтуса.
UFO just landed and posted this here
Не только лишь все могут реляционную алгебру? Хе-хе…
Движок любой базы данных работает не с реляционной алгеброй, а с аддами-делитами, гетами-путами, установкой в позицию ключа и некстами-превисами (т.н. курсоры). Это элементарные операции над базами данных «ключ-значение». А как вы эти пары в своем кластере устроите, и какие модели хранения этих пар выберете, зависит либо напрямую от программиста, либо от того слоя, который лежит между уровнем SQL и движком. Пока этот самый уровень проигрывает по производительности результата живому программисту в конкретных приложениях не просто вчистую, а с кратным отрывом. И сближения не видно.
UFO just landed and posted this here
Реляционная модель — это всего лишь модель поверх кластера баз данных «ключ-значение».
Сравнение [SQL vs. non-SQL] это как бы аналог сравнения [C vs. assembler] с той разницей, что слой автоматической трансляции [C --> assembler] реализован, не побоюсь этого слова, почти совершенным образом, а слой автоматической трансляции [SQL --> non-SQL] — как иногда говорят, представляет собой «наивную реализацию».
При большом объеме данных трансформация запроса в план низкоуровневых операций занимает принебрежимо мало времени. Все равно все упрется в обработку данных или ввод/вывод.
Если объем небольшой, а запросов много, проблема появляется. Но это не самый типичный случай.

У меня к SQL есть пара претензий.


  1. Сложность отладки и тестирования. Каждое условие в запросе — это по сути if, который создает минимум две ветки, которые нужно протестировать.
    Т.е. даже на честную отладку самого обычного запроса нужно проверить минимум 2^(n+k) инвариантов, где n — это количество сравнений полей, а k — это количество входных параметров запроса.


  2. Поведение с NULL. Мне конечно все говорят, что это норма, такова жизнь и вотэтовсё, но чёрт подери, это ещё сильнее ухудшает (1), делая мне 3^(n+k), и при этом всё начинает очень весело стрелять в рантайме, вываливая этот NULL, то туда, то сюда, когда кто-то внезапно сменит inner join на left join, просто потому что так стало надо.


  3. Протекающие абстракции слоя хранения и оптимизатора запросов.
    Знание SQL не освобождает от ответственности написания эффективных запросов. В каждом движке есть свои заморочки, как данные эффективно запрашивать и для того, чтобы работать действительно грамотно, надо точить запрос под каждый движок отдельно.
    На рынке работодателю не слишком интересно знаешь ты SQL или нет, куда важнее, работал ли ты с конкретной СУБД. Неофиты в каком-то движке имеют привычку писать совершенно по-другому и поливать тоннами ругани СУБД, когда она ведёт себя неожиданным образом, и это будет продолжаться, пока человек не разберётся, как СУБД данные хранит и как работают планировщик/оптимизатор/исполнитель запроса. Увы, не существует единого стандарта SQL, который будет абсолютно одинаково эффективно работать на всех рантаймах. И никогда не будет существовать, потому что есть требования обратной совместимости. // никогда не прощу ораклу, что у них NULL и пустая строка — это одно и тоже.

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

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

в 80х годах прошлого века от этого подхода отказались в пользу cost based optimizator. это то же самое, что в сезон отпусков проложить маршрут через центр города, а потом весь год терять 3 часа в пробках, которые более сообразительная молодежь объезжает, потому что маршрут выбирает в зависимости от дорожных условий.
самое главное преимущество SQL — он не указывает как достать данные. это декларативный язык.
cost based optimizator

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

Потом пришли разработчики и потребовали хранимых процедур и писали по сути императивный код, чтобы БД периодически не выдавала "Ну у вас и запросы" и не зависала наглухо.
Потом пришёл веб, и юзеров стало так много, что один сервер БД стал загибаться и логика поехала в приложение, где разработчики по сути закатывали солнце вручную.
Потом пришли разработчики и потребовали ORM, потому что SQL — это слишком сложно и продолжили закатывать солнце вручную на толстых аппликейшн серверах, используя БД просто как тупую хранилку данных.
А потом дырявая абстракция cost based оптимизатора начала протекать и через ORM.
А потом...


SQL не очень хорош, и я бы его ставил в ряд с каким-нибудь JS по причинам появления багов, но лучше пока не сделали. Так и живём.

видимо вы в весьма глухом месте живете, у нас вот SQL абстракция никуда не потекла, а лишь захватила еще и наши хадупы, гнусно посмеявшись на бесплодными попытками чем либо заменить. spark на хадупах — все тот же sql, все тот же cost based оптимизатор. ничего лучше так никто и не предложил

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


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


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

побеждает потому, что практика показала то что все альтернативы в итоге сильно проигрывают. при разработке оптимальным ожидается одно, при запуске оказывается оптимально данные достать по другому, через какое-то время даные распухают не равномерно и оптимум уже третий. переписывая в третий раз, люди начинуют понимать силу деклативного языка и начинают от вендоров требовать прикрутить SQL. к хадупам уже прикрутили, in memory grids аля apache ignite тоже по сути SQL уже прикручен.
UFO just landed and posted this here

Не было бы нормальных людей, шарящих в СУБД, мы бы за хранимые процедуры даже не стали бы браться. Писали бы всё на аппсервере. Другое дело, что с большинство ораклом раньше не работали.
Есть у нас хороший ораклист. Целый один. Но скорость развития проекта просто не та, при которой он бы успевал что-то сделать.
И ещё живых ораклистов за вменяемые деньги найти — это огромная проблема.
И нет, нельзя написать запрос так, чтобы он был одновременно читабельным, поддерживаемым и при этом всегда делал что надо, в условиях, когда нужно регулярно менять что-то в схеме, добавлять/убирать возврат каких-то полей, когда поля скачут из not null в nullable итд.
Обычные запросы в таких условиях очень быстро превращается в убористую кашу с десятком джойнов и вложенных запросов, которая завешивает и оптимизатор, и ораклиста.
Тупые хранимые процедуры с последовательной логикой работают просто чудесно на этом фоне. И никаких вопросов с транзакционностью.

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

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

в ерп тоже у всех разные требования и бизнесы, но структура хранения то одна.

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


Увы, не всё можно загнать под общую готовую схему.
Иначе заказчик уже купил и внедрял бы готовое решение.
Иначе бы всё ПО уже давно бы написали.

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

я и не утверждаю, что схема ломается постоянно.
На одной итерации добавилось поле, на другой стало not null, на третьей потребовалось поменять логику взаимодействия этого поля с другими, на четвертой — материализовать значение/агрегат в другую таблицу.
Просто такие изменения потихоньку наслаиваются друг на друга и потом становится очевидно, что мы из существующего решения уже выросли и время немножко поменять нормализацию в отдельных кусочках итд.
Неприятность заключается в том, что при рефакторинге надо очень хорошо тестировать, а SQL штука сильно завязанная на данные и требует большое количество тестов, если хочется надёжности.

у вас хреновый архитек. в итерации не должны поля появляться, поля могут возникнуть в результате серьезной трудности засунуть сущность в существующие структуры. добавление колонки это форс мажер, а не планомерная работа. то же касается связей между таблицами, они должны настраиваться без DDL.
UFO just landed and posted this here
— оно стоит того

А теперь новая вводная — требуется импортозамещение на Postgresql. =)


Глупости, можно конечно.

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


Если слова «десяток джойнов» смущают ораклиста то его надо заменить, этот негодный

Десяток джойнов куда больше смущают оракловый оптимизатор, у которого случается горе от ума. И помимо ораклиста есть ещё другие члены команды, которые пишут и читают SQL, так что не поможет. Уж лучше аккуратненько писать ХП и потом их бить на кусочки, да оптимизировать помаленьку.

UFO just landed and posted this here
Оракл и постгрес прекрасно справляется с сотнями джойнов, он для этого и предназначен.

Кем и как это проверено? Это сильно зависит от структуры таблиц, данных, статистики, индексов, объёма данных.


Вы не справляетесь.

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


мы не умеем в скл

Мой пойнт в том, что не существует единого SQL, который всегда одинаково хорошо работает на любой СУБД. В каждом движке есть грабли и тонкости, из-за которых часто приходится делать иначе, чем в другой СУБД. Запрос, который идеально работает в pgsql, может быть неэффективным в oracle или в принципе не реализуемым (привет, пагинация в oracle 11, боже, как я ржал, когда увидел правильное решение). И это нормально.


выбрасываем деньги на оракл

Не мы выбрасываем, это было требование заказчика — использовать оракл, потому что у него уже готовая инфраструктура, админы, итд.


но пользуем иерархическую бд 30-летней давности

??? не понял, откуда такой вывод.


P.S. а можно без ad hominem и апломба? раздражает же и убивает адекватную дискуссию.

самое главное преимущество SQL — он не указывает как достать данные. это декларативный язык.

К сожалению, за это приходится платить производительностью приложения. Особенно это заметно, если на базе данных сидит много клиентов — универсальный сервер всегда проигрывает сугубо заточенному. Именно поэтому кобыла и сегодня живее всех живых.
UFO just landed and posted this here
Спасают инструменты разработчика в браузере – статью можно читать только после удаления всего мельтешащего ))))
UFO just landed and posted this here
UFO just landed and posted this here
Считаю, что главная проблема NoSQL, а лучше сказать НЕ реляционных документных БД, в том, что этот тип БД имеет узкую специализацию. Чтобы использовать различные типы БД по назначению достаточно внимательно вчитаться в их основную характеристику. Очевидно что реляционные БД лучше подходят для нормализованных данных со схемой и связями. Документные БД для документов, т.е. не нормализованных данных без связей и схемы. Графовые БД для графов и т.д.

Однако зачастую, в проект берут какую-нибудь MongoDB, потому что это стильно-модно-молодежно и начинают лабать коллекции со схемами и связами, с сложными выборками. Вот и получается что забивают гвозди микроскопом.
Sign up to leave a comment.