Основы работы с базами данных через SQL

Основы работы с базами данных через SQL Полезное

SQL (Structured Query Language) — это язык запросов, которым описывают действия над данными в реляционной базе: создать, прочитать, изменить и удалить. Вы формулируете, ЧТО нужно получить, а как выполнить запрос, решает СУБД — система управления базами данных (PostgreSQL, MySQL, SQLite, Microsoft SQL Server и другие).

Ниже разберем реляционную модель (таблицы, строки, столбцы, ключи), четыре базовые команды и модель CRUD, а также фильтрацию WHERE, соединение таблиц JOIN и группировку GROUP BY. Все примеры — на одной сквозной схеме, их можно скопировать и выполнить. В конце — краткое отличие SQL от NoSQL.

Реляционная модель: таблицы, строки, столбцы, ключи

Реляционная база хранит данные в виде таблиц. Полезно сразу развести четыре понятия, их часто путают:

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

Ключи бывают двух основных видов. Первичный ключ (PRIMARY KEY) уникально идентифицирует строку внутри таблицы и не может быть пустым. Внешний ключ (FOREIGN KEY) ссылается на первичный ключ другой таблицы и связывает таблицы между собой.

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

CREATE TABLE departments (
    id   INTEGER PRIMARY KEY,
    name TEXT NOT NULL
);

CREATE TABLE employees (
    id            INTEGER PRIMARY KEY,
    name          TEXT NOT NULL,
    department_id INTEGER,
    salary        INTEGER,
    FOREIGN KEY (department_id) REFERENCES departments(id)
);

Здесь employees.department_id — внешний ключ: он указывает, к какому отделу относится сотрудник. Такая связь исключает «висячие» значения: сотрудника нельзя привязать к несуществующему отделу.

Оговорка про индексы зависит от СУБД: в PostgreSQL под PRIMARY KEY индекс создается автоматически, а под FOREIGN KEY — нет, его при необходимости добавляют вручную. В других системах поведение может отличаться, это стоит смотреть в документации конкретной СУБД.

Четыре базовые команды и CRUD

Большая часть повседневной работы с данными сводится к четырем операциям. Их обычно называют аббревиатурой CRUD: Create, Read, Update, Delete. Каждой соответствует своя SQL-команда.

Операция CRUD Команда SQL Что делает
Create INSERT добавляет строки
Read SELECT читает и отбирает данные
Update UPDATE меняет значения в строках
Delete DELETE удаляет строки

CRUD — это модель для запоминания, а не часть синтаксиса SQL: в самом языке команд больше (например, CREATE TABLE для структуры). Но четыре команды выше покрывают почти все операции именно с содержимым таблиц.

INSERT — добавляем данные

Заполним обе таблицы. INSERT добавляет одну или сразу несколько строк.

INSERT INTO departments (id, name) VALUES
    (1, 'Разработка'),
    (2, 'Аналитика'),
    (3, 'Поддержка');

INSERT INTO employees (id, name, department_id, salary) VALUES
    (1, 'Анна',  1, 180000),
    (2, 'Борис', 1, 150000),
    (3, 'Вера',  2, 160000),
    (4, 'Глеб',  3,  90000),
    (5, 'Дина',  2, 170000);

SELECT и WHERE — читаем и фильтруем

SELECT возвращает данные. После WHERE идет условие: в результат попадут только строки, для которых оно истинно. Запросим сотрудников с зарплатой от 160000.

SELECT name, salary
FROM employees
WHERE salary >= 160000;

Результат (порядок строк без ORDER BY не гарантирован):

name   salary
Анна   180000
Вера   160000
Дина   170000

Чтобы прочитать все столбцы, вместо перечисления пишут SELECT *. В рабочем коде лучше называть столбцы явно: так запрос не сломается при изменении структуры таблицы и читается понятнее.

UPDATE — меняем данные

UPDATE изменяет значения в уже существующих строках. Условие WHERE здесь критично: без него команда изменит ВСЕ строки таблицы. Поднимем зарплату сотруднику с id = 2.

UPDATE employees
SET salary = 175000
WHERE id = 2;

Затронута 1 строка: у Бориса теперь зарплата 175000. Перед UPDATE без ясного условия полезно тем же WHERE сделать SELECT и убедиться, что под правку попадают именно нужные строки.

DELETE — удаляем данные

DELETE удаляет строки по условию. Как и у UPDATE, пропуск WHERE означает удаление всех строк таблицы. Удалим сотрудника с id = 4.

DELETE FROM employees
WHERE id = 4;

Удалена 1 строка (Глеб). Дальше в таблице employees остаются четыре сотрудника: Анна, Борис (уже 175000), Вера, Дина.

JOIN — соединяем таблицы

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

SELECT e.name, d.name AS department
FROM employees AS e
JOIN departments AS d ON e.department_id = d.id;

Результат:

name    department
Анна    Разработка
Борис   Разработка
Вера    Аналитика
Дина    Аналитика

Псевдонимы e и d (заданы через AS) сокращают запись и снимают неоднозначность: в обеих таблицах есть столбец name, и e.name / d.name явно указывают, откуда брать значение. Условие после ON задает, какие строки считать совпадающими.

Показанный JOIN — это внутреннее соединение (INNER JOIN): в результат попадают только строки, у которых нашлась пара. Отдел «Поддержка» в выводе отсутствует — в нем не осталось сотрудников после DELETE. Внешние соединения (LEFT JOIN и другие) сохраняют строки без пары, но это уже за рамками основ.

GROUP BY — группируем и считаем

GROUP BY собирает строки в группы по значению столбца, а агрегатные функции (COUNT, SUM, AVG, MIN, MAX) считают итог по каждой группе. Посчитаем число сотрудников и среднюю зарплату по отделам.

SELECT d.name AS department,
       COUNT(*)    AS cnt,
       AVG(e.salary) AS avg_salary
FROM employees AS e
JOIN departments AS d ON e.department_id = d.id
GROUP BY d.name;

Результат (порядок групп без ORDER BY тоже не гарантирован):

department   cnt   avg_salary
Аналитика    2     165000
Разработка   2     177500

Здесь важен нюанс диалекта. Столбцы в SELECT при группировке должны быть либо в GROUP BY, либо под агрегатной функцией. PostgreSQL и MySQL в режиме ONLY_FULL_GROUP_BY вернут на нарушение ошибку. А вот SQLite молча вернет произвольное значение не сгруппированного столбца — правдоподобный, но неверный результат. Тихий неверный ответ опаснее явной ошибки, поэтому список столбцов при GROUP BY стоит проверять внимательно.

SQL и NoSQL: кратко об отличии

SQL описывает работу с реляционными базами: строгая схема таблиц и связи по ключам. NoSQL — это общее название для нереляционных хранилищ (документные, ключ-значение, графовые, колоночные) с гибкой или отсутствующей схемой.

Признак Реляционные (SQL) NoSQL
Модель данных таблицы, строки, связи по ключам документы, пары ключ-значение, графы
Схема задается заранее, строгая гибкая, может меняться на лету
Язык запросов SQL (близкий во всех СУБД) свой у каждой системы
Когда уместно связанные данные, отчеты, транзакции быстро меняющаяся структура, большие объемы простых записей

Это не «лучше или хуже», а выбор под задачу: для связанных данных и отчетности обычно берут реляционную СУБД, для гибкой структуры и горизонтального масштабирования — NoSQL. Многие проекты используют оба типа одновременно.

Выводы

  • SQL — декларативный язык: вы описываете нужный результат, а способ выполнения выбирает СУБД.
  • Реляционная модель держится на таблицах и ключах: PRIMARY KEY идентифицирует строку, FOREIGN KEY связывает таблицы.
  • Четыре базовые команды закрывают CRUD: INSERT (create), SELECT (read), UPDATE (update), DELETE (delete).
  • WHERE в UPDATE и DELETE обязателен по смыслу: без условия правка или удаление затронут всю таблицу.
  • JOIN соединяет таблицы по ключам, GROUP BY с агрегатами дает сводки; порядок строк без ORDER BY не гарантирован.

Где применяется / связь с практикой

Основы SQL нужны почти в любой работе с данными: аналитику — чтобы выгружать и сводить показатели, разработчику — чтобы читать и менять данные приложения, тестировщику — чтобы проверять состояние базы. Освоив CRUD, JOIN и GROUP BY на маленькой схеме, дальше вы наращиваете сложность запросов уже на реальных данных.

Освойте тему на практике

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

Смежные темы: Основы работы с базами данных, SQL: описание и особенности, Особенности работы с MS SQL.

FAQ

Нужно ли устанавливать сервер, чтобы попробовать SQL?
Нет. Для первых шагов подойдет SQLite — он не требует отдельного сервера, база хранится в одном файле. Синтаксис базовых команд из статьи в нем работает так же.

Чем отличается WHERE от HAVING?
WHERE фильтрует строки ДО группировки, а HAVING — уже готовые группы после GROUP BY (например, оставить отделы, где COUNT(*) > 1). Условия по агрегатам пишут именно в HAVING.

Различается ли SQL в разных СУБД?
Ядро языка (SELECT, INSERT, UPDATE, DELETE, JOIN, GROUP BY) близко везде благодаря стандарту SQL. Но типы данных, функции и отдельные расширения у PostgreSQL, MySQL, SQLite и SQL Server отличаются — детали смотрят в документации конкретной системы.

OTUS Журнал
Скидка 5% 14-20 сентября на курсы (popup)