Модуль 16

Views and Reusable Queries

Ось готовий урок, створений за твоїм майстер-промптом.


🎓 CS50: Views (Представлення) та Reusable Queries

Привіт, друзі! Радий вас бачити. 👋

Сьогодні ми не просто пишемо код. Сьогодні ми вчимося бути ледачими. Так-так, у хорошому сенсі цього слова. Найкращі розробники — це ледачі розробники, які не хочуть робити одну й ту саму нудну роботу двічі.

Тема нашого уроку: Views (Представлення).


1. 🔥 Вступ: Проблема «Дня бабака»

Уявіть, що ви працюєте аналітиком у великому онлайн-магазині. Щоранку о 9:00 до вас прибігає менеджер і просить звіт: "Слухай, дай мені список усіх VIP-клієнтів, які зробили замовлення на суму понад 5000 гривень за останні 24 години, і покажи їхні email-адреси та назви куплених товарів".

Ви відкриваєте SQL-редактор і починаєте писати монстра:

SELECT users.email, orders.total, items.name
FROM users
JOIN orders ON users.id = orders.user_id
JOIN order_items ON orders.id = order_items.order_id
JOIN items ON order_items.item_id = items.id
WHERE users.status = 'VIP'
  AND orders.total > 5000
  AND orders.created_at >= NOW() - INTERVAL '1 day';

Фух. Працює. Ви віддаєте звіт.

На наступний ранок... менеджер прибігає знову: "А давай те саме, тільки для тих, хто купив на 10 000 гривень!". Ви зітхаєте, шукаєте вчорашній код, копіюєте, змінюєте цифру... А якщо ви випадково помилилися в JOIN? А якщо схема бази даних змінилася?

Риторичне запитання: Чи не було б круто, якби ми могли взяти цей величезний, страшний SQL-запит, запакувати його в коробочку і підписати одним словом — наприклад, high_value_sales?

І щоб наступного разу ми просто писали: SELECT * FROM high_value_sales?

Спойлер: Ми можемо. Саме для цього існують Views.

Аналогія: Уявіть, що ваша база даних — це величезна бібліотека. Звичайний запит — це коли ви бігаєте по залах, збираєте 10 різних книг, відкриваєте їх на певних сторінках і складаєте на столі. View (Представлення) — це як закладка або каталожна картка, яка вже лежить на столі. Книги фізично стоять на полицях, але у вас є "віртуальний" набір, готовий до перегляду.


2. 🧠 Теоретична база: Що "під капотом"?

Давайте розберемося, що це таке, без зайвих складних термінів.

View (Представлення) — це віртуальна таблиця. Вона виглядає як таблиця, поводиться як таблиця (можна робити SELECT, WHERE, JOIN), але не зберігає даних.

Як це працює?

Коли ви створюєте View, база даних зберігає лише текст вашого запиту, а не результат.

  1. Ви кажете базі: "Зроби мені View під назвою active_users із цього складного запиту".
  2. База каже: "Ок, я запам'ятала формулу".
  3. Коли ви пізніше пишете SELECT * FROM active_users, база даних "під капотом" бере ваш маленький запит, підставляє туди збережену "формулу" і виконує повний код.

📌 Що треба запам'ятати залізобетонно:

  • View не займає місця на диску (майже). Це просто збережений код.
  • View завжди показує актуальні дані. Якщо дані в реальних таблицях змінилися секунду тому, View покаже ці зміни. Це не "знімок" (snapshot), це вікно в дані.

Інтуїтивне розуміння: View — це "лінза" або "фільтр" на камері. Світ (дані) змінюється, але ви дивитеся на нього через специфічне скельце (View), яке показує тільки те, що вам треба.


3. 🧪 Приклади: Від простого до реального

Давайте створимо базу даних онлайн-курсів. У нас є таблиці: students, courses, enrollments (хто на що записався).

Приклад 1: "Маска безпеки" (Найпростіший)

У таблиці students є поля: id, name, email, password_hash, credit_card. Ми хочемо дати доступ до списку студентів службі підтримки, але не можна показувати паролі та кредитки.

Створюємо View:

CREATE VIEW public_student_info AS
SELECT id, name, email
FROM students;

Тепер, коли ми робимо:

SELECT * FROM public_student_info;

Питання до вас: Що ми побачимо? Ми побачимо тільки id, name, email. Стовпців з паролями ніби не існує. Ми сховали зайве.


Приклад 2: "Рятувальне коло від JOIN" (Реальний)

Тепер складніше. Ми хочемо бачити, хто на який курс записався. Без View нам треба щоразу писати:

SELECT s.name AS student, c.title AS course, e.enrolled_at
FROM students s
JOIN enrollments e ON s.id = e.student_id
JOIN courses c ON c.id = e.course_id;

Зробимо з цього View:

CREATE VIEW student_roster AS
SELECT s.name AS student, c.title AS course, e.enrolled_at
FROM students s
JOIN enrollments e ON s.id = e.student_id
JOIN courses c ON c.id = e.course_id;

Тепер магія! ✨ Якщо нам треба знайти всіх студентів курсу "SQL Basics", ми пишемо:

SELECT student, enrolled_at
FROM student_roster
WHERE course = 'SQL Basics';

Бачите? Ми працюємо зі student_roster так, ніби це проста, пласка таблиця. Ми забули про страшні JOIN.


4. 🛠 Практична частина

Час "забруднити руки" кодом. Уявіть, що ви працюєте з базою даних HR-відділу. Є таблиця employees (id, name, department, salary, hire_date).

Завдання 1: Створення (Copy-Paste + Розуміння) Створіть View під назвою high_earners, яке показує лише тих працівників, у яких зарплата (salary) більша за 3000. Підказка: CREATE VIEW ... AS SELECT ... WHERE ...

Завдання 2: Використання Використайте ваше нове View, щоб відсортувати багатіїв за іменем. Підказка: SELECT * FROM high_earners ORDER BY ...

Завдання 3: Зміна умов (CREATE OR REPLACE) HR змінив політику. Тепер "high earner" — це той, хто отримує більше 4000. Змініть View, не видаляючи його. Підказка: Використовуйте CREATE OR REPLACE VIEW.

Завдання 4: Міні-кейс "Безпека" Створіть View employee_directory, яке показує всіх працівників, але приховує колонку salary. Це View буде доступне для всіх колег, щоб знайти email чи відділ, але не заглядати в чужий гаманець.

Завдання 5: "А що, якщо..." (Провокаційне) 1. Ви створили View на основі таблиці employees. 2. Видалили таблицю employees (DROP TABLE). 3. Спробували зробити SELECT зі свого View. Питання: Що станеться? Чому? (Спробуйте подумати перед запуском).


5. 💡 Мислення як у розробника

Ви тепер вмієте створювати View. Але як їх використовують профі?

❌ Типові помилки новачка:

  1. "View — це для швидкості!" — Ні. Це найпоширеніший міф. Звичайне View не пришвидшує запит. Воно просто спрощує написання коду. Для швидкості існують Індекси або Матеріалізовані Views (про них іншим разом).
  2. "View всередині View всередині View..." — Не робіть "матрьошку". Якщо ви створите View, яке посилається на інше View, яке посилається на третє... база даних може "зійти з розуму", намагаючись це розплутати. Це буде працювати, але дуже повільно.

✅ Як думає Senior Developer:

  • DRY (Don't Repeat Yourself): "Я використовую цей JOIN у п'яти різних звітах. Треба винести це у View. Якщо логіка зміниться, я зміню її в одному місці, а не в п'яти."
  • Абстракція: "Frontend-розробнику не треба знати, що у нас база нормалізована до 3-ї форми і дані розкидані по 10 таблицях. Я дам йому одне красиве View full_product_info, і нехай він радіє життю".

6. 🧩 Підсумок

Отже, друзі, що ми маємо в сухому залишку:

  1. View — це збережений SQL-запит, який прикидається таблицею.
  2. Ми використовуємо їх, щоб спростити складні запити (сховати JOIN).
  3. Ми використовуємо їх для безпеки (сховати секретні колонки).
  4. Вони динамічні — дані завжди свіжі.

Тепер ви можете перетворити 20 рядків страшного коду на один елегантний рядок.

🔍 Що далі? Ви запитаєте: "А якщо даних мільйони, і цей складний JOIN у View гальмує кожного разу, коли я його викликаю?" Чудове питання! Тут на сцену виходять Матеріалізовані Views (Materialized Views) та Індекси. Це тема нашого наступного занурення.

А поки що — практикуйтеся і будьте "ледачими" розумно! 🚀