webroad.online
  1. 1Веб
  2. 2HTML
  3. 3CSS
  4. 4JavaScript
  5. 5TypeScript
  6. 6Git
  7. 7Инструменты
  8. 8React
  9. 9Стейт-менеджмент
  10. 10Next.js
  11. 11Формы
  12. 12Данные и бэкенд
  13. 13SEO
  14. 14Tailwind CSS
  15. 15Анимации
  16. 16Тестирование
  17. 17Архитектура
Данные и бэкенд · Урок 2 из 4

SQL и реляционные базы данных

Таблицы, ключи, CRUD, JOIN, связи и параметризованные запросы.

Обновлено

Что такое реляционная база данных

Реляционная база данных (PostgreSQL, MySQL, SQLite) хранит данные в таблицах: у каждой таблицы есть колонки с фиксированными типами, а каждая строка — это один элемент. Таблицы связаны между собой ключами — отсюда «реляционная».

users                         posts
id | name  | email            id | user_id | title
---+-------+------------      ---+---------+---------
 1 | Ana   | ana@x.com         1 |       1 | Privet
 2 | Ivan  | ivan@x.com        2 |       1 | Next 16

SQL — язык, на котором запрашивают и меняют эти данные. Даже если вы используете ORM, выполняется именно SQL — его стоит свободно читать. Это приложение использует PostgreSQL на Neon.

Ключи

Ключ Роль
primary key однозначно определяет строку (id)
foreign key колонка, указывающая на ключ другой таблицы (posts.user_id → users.id)
unique значение, которое не может повторяться (email)
индекс структура, ускоряющая поиск по колонке

Четыре операции (CRUD)

SELECT id, title FROM posts WHERE user_id = 1 ORDER BY created_at DESC LIMIT 10;

INSERT INTO posts (user_id, title) VALUES (1, 'Privet') RETURNING id;

UPDATE posts SET title = 'Privet!' WHERE id = 1;

DELETE FROM posts WHERE id = 1;

UPDATE и DELETE без WHERE затрагивают все строки. Это первое, что вы проверяете.

SELECT по частям

Часть Роль Аналог в JS
SELECT col1, col2 какие колонки map
FROM таблица из какой таблицы массив
WHERE условие какие строки filter
ORDER BY col DESC порядок toSorted
LIMIT n OFFSET m сколько и откуда slice
GROUP BY col + COUNT(*) группировка и агрегация Object.groupBy + length

JOIN — объединение таблиц

SELECT posts.title, users.name
FROM posts
JOIN users ON users.id = posts.user_id;
Вид Сохраняет
JOIN (inner) только строки, у которых есть пара в обеих таблицах
LEFT JOIN все строки слева; справа = NULL, если пары нет

Связи — виды

Связь Пример Как моделируется
один-ко-многим один пользователь → много постов posts.user_id
многие-ко-многим посты ↔ теги связующая таблица post_tags (post_id, tag_id)
один-к-одному пользователь → профиль profiles.user_id unique

SQL-инъекции — золотое правило

Никогда не вставляйте ввод пользователя прямо в текст SQL:

sql(`SELECT * FROM users WHERE email = '${email}'`)       // ✗ email = "' OR '1'='1" → все пользователи
sql`SELECT * FROM users WHERE email = ${email}`            // ✓ параметр — отправляется отдельно от запроса

Шаблон sql`...` из @neondatabase/serverless (используется в этом приложении), ORM и конструкторы запросов отправляют значения как параметры ($1, $2), а не как текст.

Коротко

  • Таблицы с типизированными колонками, связанные первичными / внешними ключами.
  • SELECT … WHERE … ORDER BY … LIMIT, INSERT, UPDATE … WHERE, DELETE … WHERE; JOIN для связей.
  • Всегда параметризованные запросы — никогда не вставляйте ввод в текст.

Официальные источники

Упражнения

Была ли страница полезной?

Один клик — без регистрации.