SQL
SQL
SQL (Structured Query Language, «язык структурированных запросов») — декларативный язык для работы с реляционными базами данных: описания структуры таблиц, выборки, изменения и удаления данных.
История
SQL родился из одной академической статьи. В 1970 году Эдгар Кодд (Edgar F. Codd), математик и исследователь в IBM, опубликовал работу «A Relational Model of Data for Large Shared Data Banks» — предложил хранить данные не в виде иерархических или сетевых структур (как тогда было принято), а в виде плоских таблиц, связанных по значениям, а не по указателям. Идея была настолько простой и настолько математически строгой (в основе — теория множеств и предикатная логика), что произвела эффект разорвавшейся бомбы в мире баз данных.
IBM не сразу поверила в идею собственного сотрудника — реляционная модель конкурировала с существующим у IBM продуктом IMS (Information Management System, иерархическая БД, до сих пор используется в банках). Но в начале 1970-х внутри IBM запустили исследовательский проект System R, чтобы проверить, можно ли реляционную модель реализовать на практике и заставить работать быстро. Для System R два инженера, Дональд Чемберлин (Donald Chamberlin) и Рэймонд Бойс (Raymond Boyce), в 1974 году разработали язык запросов SEQUEL (Structured English Query Language) — с целью сделать язык похожим на английские предложения, понятным не только программистам, но и аналитикам.
Название SEQUEL пришлось сократить до SQL: у британской авиастроительной компании Hawker Siddeley уже была зарегистрирована торговая марка «Sequel» для своей продукции, и IBM во избежание юридических споров переименовала язык. Произношение «сиквел» осталось в разговорном употреблении до сих пор — часть инженеров произносит SQL как «эс-кью-эл» по буквам, часть — как «сиквел»; оба варианта общеприняты, стандарт не фиксирует ни один как единственно верный.
Первой компанией, которая вывела реляционную СУБД (систему управления базами данных) с SQL на коммерческий рынок, была не IBM, а стартап Relational Software Inc., основанный в 1977 году Ларри Эллисоном (Larry Ellison), Бобом Майнером и Эдом Оутсом. В 1979 году они выпустили Oracle V2 — первую коммерчески доступную СУБД с SQL, обогнав саму IBM (у которой первый коммерческий продукт, SQL/DS, вышел только в 1981-м). Позже эта компания сменила название на Oracle Corporation и по сей день остаётся одним из крупнейших игроков рынка баз данных.
Дальше язык стандартизировали: в 1986 году появился первый стандарт ANSI SQL (в разговоре — SQL-86), в 1987-м его приняла ISO. С тех пор вышло несколько крупных редакций стандарта — SQL-92 (расширенная поддержка типов и соединений таблиц), SQL:1999 (рекурсивные запросы, триггеры, объектные расширения), SQL:2003 (оконные функции, работа с XML), SQL:2016 (нативная поддержка JSON) и SQL:2023 (расширения для графовых запросов). Ни одна реальная СУБД не реализует стандарт целиком и без отклонений — у PostgreSQL, MySQL, Oracle, SQL Server и SQLite есть собственные диалекты, из-за чего один и тот же запрос иногда приходится переписывать при переезде с одной СУБД на другую.
Что это такое
SQL — это не язык программирования в привычном смысле (как Python или C), а декларативный язык запросов. Разница принципиальная: в императивном языке программист описывает последовательность шагов («открой файл, пройди по строкам, сравни, выведи»), а в декларативном — описывает результат, который хочет получить, а как именно его достать — решает движок СУБД (оптимизатор запросов). Ты пишешь SELECT имя FROM клиенты WHERE город = 'Казань', а внутри база сама решает: пройтись по всей таблице, воспользоваться индексом (структурой для быстрого поиска, похожей на алфавитный указатель в конце книги) или разбить работу на несколько потоков.
SQL состоит из нескольких подъязыков, которые исторически объединили под одним именем:
- DDL (Data Definition Language) — описание структуры:
CREATE TABLE,ALTER TABLE,DROP TABLE. - DML (Data Manipulation Language) — работа с данными:
SELECT,INSERT,UPDATE,DELETE. - DCL (Data Control Language) — права доступа:
GRANT,REVOKE. - TCL (Transaction Control Language) — управление транзакциями:
COMMIT,ROLLBACK.
Часто путают SQL и СУБД (систему управления базами данных): SQL — это язык, а PostgreSQL, MySQL, SQLite, Microsoft SQL Server, Oracle Database — это конкретные программы (движки), которые этот язык понимают и исполняют, каждая по-своему. Ты уже разбирал [[sqlite]] раньше — это как раз одна из таких СУБД, только встроенная (без отдельного сервера, вся база — один файл).
Ещё одна принципиальная пара — SQL vs NoSQL. NoSQL — не один язык, а зонтичный термин для баз данных, которые отказались от реляционной модели и жёсткой схемы таблиц ради гибкости или скорости на определённых нагрузках: документные (MongoDB), ключ-значение (Redis), графовые (Neo4j), колоночные (Cassandra). У них нет единого стандартного языка запросов — у каждой своё API или собственный диалект. SQL остаётся стандартом там, где данные структурированы, связи между сущностями важны, а согласованность (consistency) данных критична — например, в финансовых операциях.
Аналогии из жизни
Библиотечный каталог. SQL-запрос — это как заполнить требование в старом библиотечном каталоге: «дай мне все книги автора X, изданные после 1990 года, на полке по искусству». Библиотекарь (движок СУБД) сам решает, как быстрее найти нужные книги — по алфавитному каталогу, по тематическому, или обойти все стеллажи. Тебе не нужно знать план здания библиотеки. Где ломается: в реальной библиотеке один библиотекарь обслуживает запросы по очереди, а СУБД может обрабатывать тысячи запросов параллельно — аналогия не передаёт конкурентность (одновременный доступ разных читателей к одной и той же книге и связанные с этим блокировки).
Рецепт против пошаговой инструкции. Императивный код — это подробная инструкция «нарежь лук кубиками 5мм, разогрей сковороду до 180 градусов, обжаривай 3 минуты». SQL-запрос — это скорее заказ в ресторане: «хочу борщ без сметаны». Ты не указываешь повару последовательность действий — просто описываешь желаемый результат. Где ломается: заказ в ресторане нельзя оптимизировать так же, как запрос — повар не может параллельно приготовить часть борща десятью разными способами и выбрать самый быстрый, а оптимизатор СУБД именно так и поступает, перебирая планы выполнения запроса.
Excel-таблица с фильтрами. SQL WHERE — это как фильтр в Excel: ты указываешь условие («город = Казань»), и видишь только подходящие строки. JOIN (соединение таблиц) — как ВПР (VLOOKUP) между двумя листами: связываешь данные по общему столбцу (например, ID клиента). Где ломается: Excel-фильтр работает над данными, которые физически лежат перед тобой на листе и умещаются в оперативной памяти одного компьютера; SQL-запрос может выбирать данные из таблиц на десятки терабайт, распределённых по нескольким серверам — аналогия рвётся на масштабе.
Как это работает
Возьмём типичный запрос и разберём по шагам, что происходит внутри СУБД:
SELECT имя, город
FROM клиенты
WHERE город = 'Казань'
ORDER BY имя;
- Парсинг. СУБД разбирает текст запроса по правилам грамматики SQL и строит внутреннее дерево разбора — проверяет, что синтаксис верный, что таблица
клиентыи столбцыимя,городсуществуют. - Логическая оптимизация. Планировщик запросов (query planner) смотрит, что можно упростить или переставить местами без изменения результата — например, применить фильтр
WHEREкак можно раньше, чтобы не тащить лишние строки дальше по цепочке. - Физическая оптимизация. СУБД выбирает конкретный алгоритм выполнения: читать таблицу целиком (full scan) или воспользоваться индексом по столбцу
город, если он есть. Индекс — это отдельная структура данных (чаще всего B-дерево), которая хранит отсортированные значения столбца со ссылками на строки, — благодаря ей не нужно перебирать всю таблицу, как не нужно листать всю телефонную книгу, если она отсортирована по алфавиту. - Выполнение (execution). Движок исполняет получившийся план: читает нужные страницы данных с диска или из кэша в оперативной памяти, применяет фильтры, сортирует результат.
- Возврат результата. Клиенту (приложению, скрипту, консоли) отправляется набор строк — result set.
Отдельно стоит сказать про транзакции — механизм, который гарантирует, что группа операций либо выполнится целиком, либо не выполнится вообще (например, при переводе денег: списание с одного счёта и зачисление на другой должны произойти вместе или не произойти вовсе). Свойства правильной транзакции описывает акроним ACID: атомарность (Atomicity, всё или ничего), согласованность (Consistency, база не переходит в противоречивое состояние), изолированность (Isolation, параллельные транзакции не мешают друг другу) и устойчивость (Durability, после подтверждения данные не потеряются даже при отключении питания).
Почему SQL пережил уже пять десятилетий
Большинство языков программирования 1970-х давно забыты, а SQL за полвека почти не изменился в основах. Причина — декларативность: запрос описывает что нужно получить, а не как. Это значит, что движки СУБД могли десятилетиями становиться умнее (новые алгоритмы оптимизации, индексы, параллельное выполнение), а миллионы уже написанных запросов при этом продолжали работать без переписывания.
Где встречается в обычной жизни
- Когда в интернет-банке фильтруешь операции «только пополнения за последний месяц» — под капотом это
SELECT ... WHERE ...к таблице транзакций. - Когда ищешь товар на маркетплейсе по фильтрам (цена, бренд, рейтинг) — фильтры превращаются в условия SQL-запроса к каталогу товаров.
- Когда бухгалтерская программа строит отчёт «прибыль по месяцам» — это агрегирующий запрос с
GROUP BY(группировкой) по датам. - Когда авиакомпания показывает «осталось 3 места» на рейс — это результат запроса, который в реальном времени считает разницу между общим числом мест и числом уже проданных билетов.
- Когда служба поддержки находит твою историю обращений по номеру телефона — это
JOINмежду таблицей клиентов и таблицей обращений.
Где встречается в IT и бизнесе
- Аналитика и отчётность. Практически любой BI-дашборд (business intelligence, инструмент визуализации показателей) на бэкенде дёргает SQL-запросы к хранилищу данных.
- Бэкенд любого сервиса с состоянием. Каждый раз, когда приложение сохраняет заказ, обновляет статус доставки, проверяет баланс пользователя — это операции DML.
- CRM и лидогенерация — то, с чем ты сам вчера работал: связка автовалидатора, БрендБота и звонков через сопоставление номеров телефонов и таймстампов — это классическая задача JOIN-а нескольких таблиц по ключу и агрегации результата.
- Миграции данных. Когда переносят клиентов со старой платформы на новую, почти всегда пишут SQL-скрипты выгрузки и загрузки.
- A/B-тестирование и продуктовая аналитика. Расчёт конверсии, retention (удержания пользователей), LTV (пожизненной ценности клиента) почти всегда — SQL-запросы к событийным логам.
Кто пользуется
SQL в том или ином диалекте используют практически все крупные технологические компании. PostgreSQL — выбор Instagram, Reddit, Spotify для основной части данных. MySQL исторически стоял в основе Facebook (там его форк, MyRocks, до сих пор обслуживает часть нагрузки при миллиардах пользователей) и до сих пор остаётся одной из самых популярных СУБД для веб-приложений (WordPress, например, работает поверх MySQL/MariaDB). Oracle Database — стандарт в банках, страховых компаниях и госсекторе, где критична многолетняя поддержка и формальные гарантии. Microsoft SQL Server — основа корпоративного мира на Windows-инфраструктуре. Google BigQuery и Amazon Redshift — облачные SQL-хранилища для аналитики над петабайтами данных, где запрос может сканировать миллиарды строк за секунды благодаря массовому параллелизму.
По данным опроса разработчиков Stack Overflow, SQL стабильно входит в тройку-пятёрку самых используемых языков среди профессиональных разработчиков — обычно его отмечают порядка 40–50% опрошенных, наравне с JavaScript и Python, хотя точные цифры год от года слегка отличаются.
Альтернативы и конкуренты
- NoSQL (документные, ключ-значение, графовые БД) — плюс: гибкая схема, часто выше скорость записи на определённых нагрузках; минус: обычно слабее гарантии согласованности данных, нет единого стандартного языка запросов.
- ORM (Object-Relational Mapping, например Django ORM, SQLAlchemy, Hibernate) — плюс: не нужно писать сырой SQL, работаешь с объектами на привычном языке программирования; минус: генерируемые запросы иногда неэффективны, а для сложной аналитики всё равно приходится спускаться до SQL.
- GraphQL — плюс: клиент сам описывает, какие поля ему нужны, экономит трафик API; минус: это язык запросов к API, а не к базе напрямую — где-то за GraphQL всё равно чаще всего стоит SQL.
- Языки для больших данных (Spark SQL, Hive) — плюс: SQL-подобный синтаксис поверх распределённых кластеров с петабайтами данных; минус: избыточны и медленны для простых задач, где хватило бы обычной реляционной СУБД.
Когда НЕ стоит использовать
- Когда данные принципиально не табличные и сильно вложенные (например, документы с непредсказуемой структурой) — жёсткая схема SQL-таблиц заставит либо постоянно менять структуру, либо хранить всё в одном текстовом поле, теряя смысл реляционной модели.
- Когда нужна экстремальная скорость записи при простом доступе по ключу (счётчики просмотров, кэш сессий) — здесь ключ-значение хранилища вроде Redis быстрее и проще, чем полноценная реляционная СУБД с транзакциями.
- Когда данные — просто плоский поток событий без связей и без необходимости частых запросов (сырые логи, метрики) — специализированные time-series базы или файлы часто эффективнее, чем SQL-таблица с миллиардами строк.
Связанные понятия
- [[sqlite]] — встроенная файловая СУБД с диалектом SQL, без отдельного сервера.
- Индекс — структура данных для быстрого поиска по столбцу без полного перебора таблицы.
- Транзакция — группа операций, которая выполняется целиком или не выполняется вовсе.
- ORM — библиотека, которая переводит объекты языка программирования в SQL-запросы автоматически.
- NoSQL — класс баз данных без жёсткой реляционной схемы и без единого стандартного языка запросов.
- [[api]] — часто именно через API-слой приложения обращаются к базе, а не напрямую по SQL.
Литература и источники
- Edgar F. Codd, «A Relational Model of Data for Large Shared Data Banks», 1970 — оригинальная статья, с которой всё началось; искать в Google по названию, свободно доступна как классическая работа по теории баз данных.
- C.J. Date, «An Introduction to Database Systems» (несколько переизданий, en) — считается одним из главных учебников по теории реляционных баз.
- Markus Winand, «SQL Performance Explained» (en) — компактная и практическая книга про то, как СУБД реально выполняет запросы и как писать быстрый SQL; есть открытая версия на use-the-index-luke.com.
- Официальная документация PostgreSQL (postgresql.org/docs) — один из самых подробных и точных референсов по SQL на практике, с объяснением отличий от стандарта.
- Статья «SQL» в Wikipedia (ru.wikipedia.org/wiki/SQL, en.wikipedia.org/wiki/SQL) — для быстрой сверки исторических дат и версий стандарта.
Где встретилось у меня
Вчера SQL несколько раз всплывал в разборах инфраструктуры БрендБота и автовалидатора — например, при прямом сравнении доходимости кликов до и после внедрения прослойки /go, где агент делал read-only SQL-запросы на проде, переиспользуя уже готовые функции фильтрации, а не писал свою логику с нуля. Похожая история — при сверке расхода баланса ГБ, когда точное сопоставление звонков между автовалидатором и БрендБотом потребовало починки порядка приоритета в запросах.
Краткое резюме
- SQL — декларативный язык запросов к реляционным базам данных, придуман в IBM в начале 1970-х на основе теории Эдгара Кодда, первая коммерческая реализация — Oracle в 1979 году.
- Ты описываешь что хочешь получить, а не как это сделать — план выполнения строит сам движок СУБД.
- SQL — это язык, а PostgreSQL, MySQL, SQLite, Oracle — конкретные программы, которые его исполняют, каждая со своим диалектом.
- ACID-транзакции — ключевая гарантия SQL-баз: операции выполняются либо целиком, либо не выполняются вовсе.
- SQL не универсален: для гибких схем, экстремальной скорости по ключу или потоков сырых событий часто лучше подходят NoSQL или специализированные хранилища.