бесплатно без регистрации урок 1 из 18

Что такое база и зачем SQL

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

17 мин чтения · 4 главы ·4 задания ·домашняя работа

Таблицы, строки, ключи

База данных — это склад, где информация лежит в таблицах. Таблица похожа на лист в электронной таблице: сверху названия столбцов, ниже строки с данными. Разница в трёх вещах, и каждая из них важна.

id · name · city · age · signup_date1 · Анна Смирнова · Москва · 28 · 2023-01-152 · Борис Кузнецов · Санкт-Петербург · 35 · 2023-02-033 · Вера Ильина · Казань · 22 · 2023-02-20строка — один покупатель целиком, со всеми его даннымистолбец — одна характеристика у всех покупателей сразуid — номер строки: по нему на неё ссылаются другие таблицы
Столбец — это характеристика, строка — один объект целиком, ключ — его номер.

Столбец — одна характеристика: имя, город, возраст. У столбца есть название и тип: name хранит текст, age — целые числа, price — числа с копейками. Тип не украшение: он решает, что с колонкой можно делать. Сложить два текста нельзя, а вычесть одну дату из другой — можно.

Строка (её называют ещё записью) — один объект целиком: конкретный покупатель со всеми его данными. Строк в таблице бывает и десять, и десять миллионов, и это почти не меняет скорость поиска — если база устроена правильно.

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

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

customers1 · Аннаorders7 · customer_id 1order_items12 · order_id 7одно и то же имя хранится один раз — и правится тоже один разэто и есть главная мысль: данные не дублируются, а связываютсясобрать их обратно в одну таблицу — работа запроса
Заказ не хранит имя покупателя — он хранит его номер, и по номеру имя находится.

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

Столбец, который хранит номер строки из другой таблицы, называют внешним ключом. В нашей базе это orders.customer_id, order_items.order_id, order_items.product_id. Собрать данные обратно в одну таблицу — работа запроса, и этому посвящён целый урок про соединения.

И последнее про таблицу: клетка может быть пустой. Не ноль и не пустая строка, а именно ничего — это состояние называется NULL. В нашей базе у одной покупательницы не указан возраст, а у одного отзыва нет текста: так бывает, когда данные не собрали, не успели или они вообще не нужны.

Пустота ведёт себя не как значение, и это источник самых тихих ошибок в отчётах: строка с незаполненным возрастом не попадёт ни в «моложе тридцати», ни в «старше тридцати», и человек просто исчезнет из обоих списков. Разбору этого посвящён отдельный урок; пока достаточно запомнить, что пустая клетка — третье состояние, а не ноль.

Зачем SQL, если есть выгрузка

Теперь про сам SQL. Это язык, на котором базе задают вопросы, и устроен он не так, как языки программирования.

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

SELECT name
FROM customers
WHERE city = 'Москва'

Три строки, и они читаются почти как английская фраза: выбери имя из покупателей, где город — Москва. На нашей базе этот запрос вернёт четыре строки: столько покупателей из Москвы.

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

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

Выгрузили продажи за месяц, посчитали сумму. Спросили «а по городам?» — выгружаете заново. «А только по тем, кто зарегистрировался в этом году?» — заново. «А за прошлый месяц для сравнения?» — снова. Каждый раз это пять минут и возможность ошибиться в формуле.

Запрос вместо этого правится в одну строку. И у него есть три свойства, которых у выгрузки нет.

Он повторяем. Один и тот же запрос завтра даст то же самое на тех же данных. Таблица, которую правили руками, — нет.

Он проверяем. Запрос видно целиком: понятно, что он считает и чего не считает. В таблице с формулами в трёхстах ячейках это понятно только автору, и то неделю.

Он не ограничен объёмом. Миллион строк выгружать некуда, а считать по ним — обычная работа.

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

Тут же снимается и следующий вопрос: баз много, а язык один? Почти. PostgreSQL, MySQL, SQLite, Oracle, MS SQL — у каждой свои добавки и мелкие расхождения в том, как пишутся даты и функции над текстом. Но основа — SELECT, WHERE, GROUP BY, соединения — везде одна, и человек, умеющий писать запросы в одной базе, пишет их в любой другой в тот же день.

Курс работает на SQLite: эта база помещается в одну вкладку браузера и не требует установки. Всё, что здесь написано, работает и в остальных базах без правок, а где мелочь отличается — курс скажет об этом прямо в том месте, где отличие важно.

Части запроса и порядок

Запрос состоит из частей, и каждая отвечает на свой вопрос.

частьна какой вопрос отвечает
SELECTКакие колонки показать
FROMИз какой таблицы брать строки
WHEREКакие строки оставить
GROUP BYКак свернуть их в итоги
HAVINGКакие итоги оставить
ORDER BYВ каком порядке показать
LIMITСколько строк вернуть

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

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

как пишутSELECT · FROM · WHEREGROUP BY · HAVINGORDER BY · LIMITкак выполняетсяFROM → WHERE → GROUP BY→ HAVING → SELECT→ ORDER BY → LIMITSELECT пишется первым, а выполняется почти последнимпоэтому на псевдоним из SELECT нельзя сослаться в WHEREи поэтому же отбор всегда дешевле сортировки: он идёт раньше
Пишут в одном порядке, а выполняется в другом — и из этого следует почти всё остальное.

Сначала база берёт строки из таблицы (FROM), потом отсеивает лишние (WHERE), потом сворачивает в группы (GROUP BY), отбирает группы (HAVING), и только потом вычисляет то, что вы написали в SELECT. В самом конце сортирует и отрезает нужное число строк.

Отсюда следует правило, о которое спотыкаются все новички: на псевдоним из SELECT нельзя сослаться в WHERE. Когда WHERE выполняется, псевдонима ещё не существует.

-- так нельзя: имени «полный_возраст» ещё нет
SELECT age + 1 AS полный_возраст
FROM customers
WHERE полный_возраст > 30

-- так можно: выражение повторяется целиком
SELECT age + 1 AS полный_возраст
FROM customers
WHERE age + 1 > 30

Ещё две мелочи, которые стоит принять сразу.

Регистр не важен. SELECT, select и Select — одно и то же. Ключевые слова принято писать заглавными: так в длинном запросе сразу видно скелет. Названия таблиц и колонок пишут как есть.

Комментарии начинаются с двух дефисов и идут до конца строки: -- это пояснение. Многострочный комментарий заключают в /* … */. В рабочих запросах комментарий обычно объясняет не что делает строка, а почему она такая: «берём только оплаченные — неоплаченные отменяются через сутки».

И про то, как запрос выглядит на экране. Базе всё равно, написан он в одну строку или в семь: переносы и отступы она не различает. Человеку — не всё равно. Принято начинать каждую часть с новой строки, как во всех примерах курса: тогда запрос читается сверху вниз, а лишнее или недостающее видно, не вчитываясь.

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

Учебная база и как проверяются задания

Курс работает на настоящей базе — маленьком интернет-магазине «Полка». Шесть таблиц, все запросы из теории на ней выполняются, и любой из них можно скопировать и проверить.

таблицачто в нейстрок
customersпокупатели: имя, город, возраст, дата регистрации12
productsтовары: название, категория, цена, остаток15
ordersзаказы: покупатель, дата, статус20
order_itemsстроки заказов: товар, количество, цена29
reviewsотзывы: товар, покупатель, оценка, текст13
employeesсотрудники: должность, зарплата, город, руководитель8

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

Вот как выглядят первые строки таблицы покупателей:

idnamecityagesignup_date
1Анна СмирноваМосква282023-01-15
2Борис КузнецовСанкт-Петербург352023-02-03
3Вера ИльинаКазань222023-02-20
4Глеб ОрловМосква412023-03-11
Те же данные, что в базе: запрос из теории вернёт ровно это.

Теперь про задания. Часть из них обычные — выбрать ответ, соотнести, посчитать. Но главные — те, где вы пишете запрос, и его по-настоящему выполняют.

Устроено это так: вы пишете запрос, сервер создаёт чистую копию учебной базы, выполняет на ней ваш запрос и эталонный и сравнивает результаты. Совпали — задание зачтено, каким бы способом вы этого ни добились.

Из этого следуют две приятные вещи. Первая: верных решений много, и своё не обязано совпадать с задуманным автором. Вторая: испортить базу нельзя — она создаётся заново перед каждой проверкой, и даже DELETE без условия никому не навредит.

Иногда в задании важен не только результат, но и способ: «сделайте это одним соединением, а не подзапросом». Тогда об этом сказано прямо в условии, и проверка смотрит ещё и на то, чем вы воспользовались. Таких заданий немного, и все они там, где способ и есть предмет урока.

Что делать, когда запрос не засчитан. Первым делом посмотреть на результат, а не на текст: сервер показывает строки, которые вернул ваш запрос. Обычно уже по ним видно, что не так, — строк слишком много (забыт отбор), слишком мало (условие отсекло лишнее) или не те колонки.

Пустой ответ — тоже ответ, и он не означает ошибку. Запрос, который ничего не нашёл, выполнился правильно; просто подходящих строк нет. Различать «запрос сломан» и «строк не нашлось» придётся всё время, и начинать эту привычку лучше здесь, на двенадцати покупателях.

Задания урока

Каждое проверяется сразу: ответ сверяется с эталоном, и на неверный вариант приходит разбор.

  1. Соотнесите понятие и то, чем оно является.легко
  2. В SQL вы описываете, как именно база должна найти нужные строки.средне
  3. На псевдоним из SELECT можно сослаться в WHERE.сложно
  4. Выведите имена и города всех покупателей. Колонки: name, city.средне
Пройти урок с проверкой заданий Курс «SQL» открыт и бесплатен, прогресс сохраняется.
Открыть курс