Ненависть к SQL
Нынче такая мода — ненавидеть SQL. Проходя мимо, нужно обязательно поддать его ногой: и синтаксис уродлив, и плохо ложится на объекты, и джоины всякие… Под каждой статьей народ стоит в очереди, чтобы накласть комментарий: да, плохой. Да, фу-фу.
Я считаю, что SQL замечателен, но сначала расскажу анекдот.
Приезжает Тарантино на фестиваль. Журналист берет у него интервью и троллит: Квентин, вы замечательный режиссер, но вы так и не сняли фильма лучше “Криминального чтива”. Тарантино думает и отвечает: а кто снял?
Вот так и с SQL — кто снял? У нас есть что-то лучше? Я лично не уверен.
Напротив, я все больше убеждаюсь, что SQL удобен и гибок. Этим объясняется то, что он дожил до наших дней. Помните, в начале десятых годов каждый клоун кричал в Твиттере, что пришло время noSQL? Каждый день была статья “как я переехал на Монгу”. Кончилось тем, что Postgres сделал jsonb и съел Монгу с потрохами. А у тех, кто на нее переехал, начались другие проблемы, потому что чудес не бывает.
Когда говорят про SQL, забывают, что он не зависит от языка, на котором пишут код. Ему не важно, что у вас — Питон, Джава или пы-хы-пе. Это по-настоящему классно. SQL дает универсальный доступ к данным из любой технологии. Им можно пользоваться без программного окружения, например в psql или PgAdmin.
Помните аббревиатуру LAMP: Linux, Apache, Mysql, PHP? Вот что по-настоящему важно: SQL — это часть стека. Сегодня буквы поменялись, но принцип остался: это операционка, сервер, данные и язык, который ими управляет.
Каждый элемент стека — как слой жидкости в лава-лампе. Можно перемешать слои, то есть внести хаос: взять базу, которая встраивается в язык; сделать проект на no-code-решениях, тем самым выкинув условный PHP. Такие случаи есть, и каждый из них обсуждают на айтишных сайтах. Но в долгосрочной перспективе слои лава-лампы приходят в норму. Потому что вещи должны быть простыми, но не проще определенного порога.
Мало кто думает о том, что noSQL-решения дороги и трудны в развертке. Я уже писал, что Postgres и Mariadb работают на каждом утюге. Первый уже гоняют в браузере. А базы вроде Datomic или XTDB напоминают черепах на трех китах. Их работа сводится к оркестрации других хранилищ. Например, Datomic использует Посгрес или Марию для хранения индексов, плюс ему нужен мемкеш-кластер, плюс в облаке он ходит в S3. Базе XDTB нужен кластер Кафки. Вы точно готовы в этом разбираться? Осилите развернуть продакшен-версию локально?
Разумеется, у этих баз есть dev-режим для локального запуска. Но в случае с Postgres я знаю, что локальная база идентична той, что в проде. В обоих случаях крутится один и тот же код. Я могу воспроизвести любую ситуацию локально. В случае с Датомиком это лишь имитация.
Сюда же относится OpenSearch. Формально он open source, бери и пользуйся. На практике его развертка настолько сложна — нужно минимум три узла в кубере, — что все пользуются облачной версией поставщиков. А это дорого.
Апишку OpenSearch вы видели? Казалось бы, HTTP и REST, шли джейсоны и живи
спокойно. Я с ней работал и скажу — неудобно. Синтаксис жуткий, нужно учить с
нуля. Тройная вложенность: мапа внутри мапы внутри мапы. Нельзя выбрать больше
10 тысяч записей за раз (Посгрес выплюнет миллион за долю секунды). Пагинация
ужасная и состоит их двух апишек, а не одной. Наконец, я лично спровоцировал
исключение, когда переполняется ByteArrayOutputStream
, и запрос падает с
ошибкой 500. Когда в последний раз вы видели переполнение буфера в Посгресе?
Когда я стал работать в крупной фирме, поразился тому, что почти каждый знает SQL. Менеджеров и аналитиков этому учат на курсах. Человек, который путает Java и JavaScript, может написать сложный запрос на два экрана. Ощущение, что даже уборщица напишет выборку часов с нарастающим итогом. Было такое, что человек приносил запрос и просил поставить на ежедневную выгрузку. А это значит, он снимал с меня тяжкий груз — сопоставлять бизнес-требования с данными. Без него я писал бы запрос неделю, потому что не понимаю бизнес-жаргон. А он сделал это за меня, и осталось только завернуть запрос в техническую шкурку.
В крупных фирмах SQL становится языком коммуникации, посредником между бизнесом и технарями. А что с условным Датомиком и Даталогом? Все это прибито гвоздями к Кложе; с ним у людей нет доступа к данным. К вам без конца будут приходить и просить: выгрузи то, выгрузи это, напиши такой запрос, сякой запрос. Вам это нужно?
Некоторые сотрудники знают Питон и решают задачи скриптами с запросами к базе. Нейросеть пишет болванку, а они ее адаптируют. Что с Датомиком или XTDB? У них до сих пор нет клиента для Питона. Когда-то давно у Датомика был REST-интерфейс, но его упразднили. А XTDB вообще предоставляет Wire Protocol, притворяясь, что на том конце Postgres. Играет по правилам конкурента, лишь бы отхватить пользователей.
Все говорит об одном: дай людям SQL, и они сами все сделают.
Базы, которые встраиваются в язык, предлагают удобный доступ к данным. Он красивее и изящней, чем голый SQL — с этим я не спорю. Но повторю: данные нужны всем, а не только кложуристам. Мне приходилось писать запросы в веб-консоли Датомика, и уверяю вас: магия пропадает. Одно дело писать их в редакторе с балансировкой скобок, подсветкой синтаксиса и хоткеями. А когда перед тобой унылый text area — все, завяли помидоры. Написание запроса становится рутиной: не закрыл скобку, опечатался в ключевом слове. Набранные запросы копируешь в файлик, чтобы сохранились.
Когда пишешь SQL днями напролет, воспринимаешь его как язык. На нем удобно
выражать мысли. Например, я не вижу причины писать {select [foo bar baz]}
вместо select foo bar baz
— то есть ставить скобочки и структурировать
данные. Пусть этим занимаются построители SQL. Недавно сотрудники Гугла выкатили
пейпер, где на 20 страницах объясняли необходимость писать from users select
id
вместо select id from users
. Ну ок, напишите препроцессор для клиента к
БД. А разговоров-то было…
Наша работа всегда будет сложной — иначе бы айтишники не получали как депутаты. Сложность следует из разнообразия случаев, с которыми сталкиваешься. Решения вроде Датомика и прочих noSQL-баз хороши в моменте. Они подкупают красотой в тех местах, где SQL не вышел лицом. Если хотите, это показ мод или акаунты моделей в Инстаграме. Но когда ты женился на модели, выясняется, что из-за длинных ногтей она не может почистить картошку или пришить пуговицу.
SQL — это не про красоту, а про getting shit done. Понимание этого приходит на долгой дистанции.
Нашли ошибку? Выделите мышкой и нажмите Ctrl/⌘+Enter
Роман, 7th Jul 2025, link
Ненависть к SQL вполне объяснима. Требования растут и ограничения становятся проблемой.
В начале нулевых работал в одном региональном телекоме. Там была ситуация - чтоб запустить один отчет из программы человек бегал и всех в здании предупреждал. Иначе на 15-20 минут работа вставала.
Я потом этот ужос оптимизировал. SQL запрос на 4 страницы мелким шрифтом. Любви это вовсе не прибавило. А это было время как раз безраздельного доминирования SQL-а. Это не проблема SQL как такового, но он таки ограничен и выстрелить в ногу - элементарно.
Насколько я помню он изначально и создавался именно для них. Простое средство выборки данных для аналитиков и способ сэкономить на программистах.
Но вот только это уже не SQL - то есть просто прогнулись под общий тренд. И обращаю внимание - фича-то востребованная. То есть не хватает уже SQL-а.
Работаю с эластиком - это вроде как тоже самое. Никакие три узла в кубере не нужны (не обязательны). Запускается не сложнее любой СУБД.
Да - неудобно. Ублюдочный вложенный JSON. Напрямую его никогда не генерю - есть обертки, которые позволяют делать это композицией. Но спасает несильно. Кроме вложенности нестабильный и неконсистентный синтаксис просто раздражает.
Можно. Это всего лишь умолчание.
Никогда этого аргумента не понимал. Зачем вам выплевывать миллионы? Куда? Вы на экран пользователю эти миллионы вывалите? Ну нет же - один хрен вы все будете пагинировать. Или аггрегировать.
И на клиента вы потащите ограниченный набор, а не “эти ваши миллионы”
И именно отсюда это умолчание в OpenSearch/Elastic
Не совсем понял в чем ужос-ужос. Пагинация там как раз правильная, а не offset/limit который используется повсеместно. В PG кстати offset/limit был традиционной болью ибо работал медленно (может уже починили - давно это не тестил)
Ну и вот сейчас графану глянул на живом проекте. Elastic + MariaDB. Среднее время выборки
Максимальное
И это при том, что в эластике очень много выборок с аггрегированнием и в целом данных сильно больше.
Это конечно пальцем в небо - грубо без учета специфики использования. Но тут разница в скорости колоссальная - она слишком велика, чтоб ее игнорировать. Поэтому оно и живо и популярно.
Итого - пусть растут все цветы. SQL никуда не денется - для своих целей он близок к идеалу - взрослая стабильная технология. Весь этот noSQL просто занимает ниши где SQL не очень хорош. Проблемы они в крайностях и фанатиках с “эффектом утенка”.
Ivan Grishaev, 7th Jul 2025, link
Querying for pages deep in your results can have a significant performance impact, so OpenSearch limits this approach to 10,000 results.
Это с сайта OpenSearch. Подскажите тогда, как задать лимит в 500.000 документов, пожалуйста.
А на какой технологии это была бы одна страница?
Роман, 7th Jul 2025, link
“can have a significant performance impact” и “нельзя выбрать” вообще не одно и тоже. Can have, а может и не can have - это просто предупреждение. Postgres он тоже не резиновый и имеет свои лимиты. То, что их явно не оговаривают это не значит, что их нет. В частности широко известную проблему с медленным OFFSET я уже упоминал.
Ну и вы так и не ответили - для каких задач нужна выборка в миллион записей одним запросом?
It depends …4 страницы кода на любом ЯП например читать совсем несложно …а вот сложный SQL с кучей подзапросов и джойнов читается ничуть не лучше безумных json-ов эластика. При этом с определенного количества джойнов понять, что вернется становится очень сложно. Так же как и понять как физически свяжутся данные и как это повлияет на производительность.
В том случае, что я описывал вся проблема решилась довольно тупо - разбиением этого монстра на 2 отдельных запроса - дальше рыть не стали, ибо проблема ушла. Причем разбивалось именно, чтобы хоть как-то понять, что тут происходит, а не потому, что скилл.
Даже просто тупо отформатировать достаточно длинный и сильно вложенный SQL до читабельного состояния та еще задача.
Ну и к слову несмотря на некоторый хейт эластиковые json-ы вполне читаемы. Json сам по себе структурирован, в отличие от SQL-а c местами неочевидными связями. Ну и до кучи - когда-то на волне хайпа трогал монгу. Деталей не помню, но именно язык запросов показался тогда удобным, хотя по памяти там что-то jsono-подобное было.
Ivan Grishaev, 7th Jul 2025, link
У меня это не работало, надо проверить. Зато я точно помню, как на больших выборках словил исключение, когда переполнялся ByteArrayOutputStream. Это крайне досадная штука.
для отчетности, для забора данных, миграций, например.
Мне сложно, потому что данных много, строятся мапы-индексы, которые нужно обходить и проверять. Плюс понятие рантайма: что было на момент исполнения кода, вы уже не догоните. Разве что дампить в файлы и потом скачивать их. А SQL вставил в PGAdmin и сразу видно, что пошло не так.
Роман, 7th Jul 2025, link
Я даже могу предположить с чем это ограничение связано. У нас возвращаются JSON-ы. Это же пипец какой избыточный формат. Если документики простые и маленькие вы вполне себе вернете ваш миллион результатов, а если там развесистые данные то такое количество данных проблемно прокачать за разумное время даже при меньшем лимите.
Так оно на ручной ввод и не рассчитано - там богомерзкий json везде. SQL изначально строился для ручного ввода - он человекопонятный by design. Он как раз не был предназначен для использования в коде - это же явный изврат использовать в любом ЯП еще один промежуточный язык. Это как регулярки - убогий костыль, который удобен в простых случаях но боле менее длинные регулярки практически нечитаемы.
Ну типа давайте разовьем тему - файловый АPI тоже через свой QL сделаем - а чем файлы хуже? Сокеты почему не через отдельный язык сделать? “READ FROM 192.168.1.1” и поехали. Красиво, удобно, портабельно. Ну и на каждый пук свой язычок. Но почему-то файлами оперировать написанием кода на родном ЯП нет проблем, а для БД у нас прослойка в виде подьязыка.
SQL это же фактически UI. Родной и понятный для консолей 70-x 80-x. Мне довелось потрогать систему тех времен - еще как ни странно живы такие динозавры. Рабочее место оператора текстовый терминал с набором полей. Никаких вам выпадающих списков, чекбоксов и прочих излишеств. Есть мануал оператора (PDF) в какие поля какие буковки циферки указывать и что они значат. Сформировал запрос, очень крепко подумал и сто раз проверил ибо один запрос $5 и жмешь отправить. И в ответ оно начинает как в старых фильмах про хакеров буквально выдавливать из себя результаты. Ну так вот SQL это такой универсальный UI для подобного рода систем.
То что его программисты используют вместо внятного API к БД это скорее такая загогулина развития ИТ. Нужный унифицированный API для БД вовремя не был предложен и внедрен - вот и жрем до сих пор эту прослойку.
Ivan Grishaev, 7th Jul 2025, link
не-не, операция limit так не работает. Она не учитывыет размер документов. У меня подозрение, что я все-таки прав и передать лимит больше 10к нельзя. Как будет время, проверю.
не UI, а декларативный язык описания данных.
Роман, 7th Jul 2025, link
Так а язык (любой - хоть китайский) это разве не UI?
Роман, 7th Jul 2025, link
Это опция сервера. По крайней мере на эластике