Загрузка данных


Государственное профессиональное образовательное учреждение
«Сибирский политехнический техникум»






ОТЧЁТ ПО БАЗЕ ДАННЫХ

«Кофейня (CoffeeShopDB)»





Работу выполнил(а): 
Прокошин Андрей Вячеславович,
Группа ПР-24
Руководитель:
ФИО,
Редько Алексей Дмитриевич






Кемерово, 2026
 





























 
ВВЕДЕНИЕ
Цель работы: закрепление навыков проектирования реляционных баз данных и написания SQL-запросов.
Выбранный вариант: Вариант 11 – Кофейня (CoffeeShopDB).
Используемые инструменты: PostreSQL 18, pgAdmin.
Краткое описание предметной области:
База данных автоматизирует работу кофейни. В системе хранятся сведения о сотрудниках (бариста), меню заведения (напитки, десерты, выпечка, еда), заказах клиентов и детальном составе каждого заказа. Система позволяет отслеживать выручку по сотрудникам, анализировать популярность позиций меню и управлять их доступностью.
 
ПРОЕКТИРОВАНИЕ БАЗ ДАННЫХ
ER-Диаграмма: 

Связи:
Таблица 1	Таблица 2	Тип связи	Реализация
baristas	orders	1 : N	Внешний ключ barista_id в таблице orders
orders	order_details	1 : N	Внешний ключ order_id в таблице order_details
menu_items	order_details	1 : N	Внешний ключ menu_item_id в таблице order_details

Описание таблиц:
Таблица baristas – сотрудники кофейни
Поле	Тип	Ограничение	Описание
id	SERIAL	PRIMARY KEY	Уникальный идентификатор
full_name	VARCHAR (150)	NOT NULL	ФИО бариста
hire_date	DATE	NOT NULL	Дата приёма на работу
is_active	BOOALEN	NOT NULL	Работает ли в данный момент

Таблица menu_items – позиции меню
Поле	Тип	Ограничение	Описание
id	SERIAL	PRIMARY KEY	Уникальный идентификатор
name	VARCHAR (150)	NOT NULL	Название
позиции
category	VARCHAR (300)	NOT NULL	Категория (Кофе, Чай, Десерты и т.д.)
price	DECIMAL (10,2)	NOT NULL	Цена в рублях
is_available	BOOALEN	NOT NULL	Доступна ли к заказу


Таблица orders – заказы
Поле	Тип	Ограничение	Описание
id	SERIAL	PRIMARY KEY	Уникальный идентификатор
barista_id	INT	FOREIGN KEY	Ссылка на бариста, принявшего заказ
order_time	TIMESTAMP	DEFAULT CURRENT_TIMESTAMP	Время оформления заказа
total_amount	DECIMAL (10,2)	NOT NULL	Общая сумма заказа
payment_method	VARCHAR (50)	NOT NULL	Способ оплаты

Нормализация:
1NF – в каждой ячейке одно значение, нет списков
2NF – всё зависит от полного ключа 
3NF – нет зависимостей между полями
 
РЕАЛИЗАЦИЯ
Создание структуры (DDL):
CREATE TABLE baristas (
    id SERIAL PRIMARY KEY,
    full_name VARCHAR(150) NOT NULL,
    hire_date DATE NOT NULL,
    is_active BOOLEAN NOT NULL
);

CREATE TABLE menu_items (
    id SERIAL PRIMARY KEY,
    name VARCHAR(150) NOT NULL,
    category VARCHAR(300) NOT NULL,
    price DECIMAL(10,2) NOT NULL,
    is_available BOOLEAN NOT NULL
);

CREATE TABLE orders (
    id SERIAL PRIMARY KEY,
    barista_id INT NOT NULL,
    FOREIGN KEY (barista_id) REFERENCES baristas(id),
    order_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    total_amount DECIMAL(10,2) NOT NULL,
    payment_method VARCHAR(50) NOT NULL
);

CREATE TABLE order_details (
    id SERIAL PRIMARY KEY,
    order_id INT NOT NULL,
    FOREIGN KEY (order_id) REFERENCES orders(id),
    menu_item_id INT NOT NULL,
    FOREIGN KEY (menu_item_id) REFERENCES menu_items(id),
    quantity INT NOT NULL,
    note TEXT
);

CREATE INDEX idx_orders_barista_id ON orders(barista_id);
CREATE INDEX idx_order_details_order_id ON order_details(order_id);
CREATE INDEX idx_order_details_menu_item_id ON order_details(menu_item_id);

Наполнение тестовыми данными:

Объём данных:
· baristas – 15 записей
· menu_items – 31 запись 
· orders – 61 запись 
· order_details – 87 записей

Источники данных: все данные сгенерированы вручную, приближены к реальным позициям кофейни и типичным заказам.

Пример вставки данных:
Добавление бариста:
INSERT INTO baristas (full_name, hire_date, is_active)
VALUES ('Иванов Александр', '2023-01-15', TRUE);

Добавление позиции меню:
INSERT INTO menu_items (name, category, price, is_available)
VALUES ('Эспрессо', 'Кофе', 150.00, TRUE);

Создание заказа:
INSERT INTO orders (barista_id, order_time, total_amount, payment_method)
VALUES (1, '2024-03-01 08:15:00', 480.00, 'Наличные');

Добавление состава заказа:
INSERT INTO order_details (order_id, menu_item_id, quantity, note)
VALUES (1, 1, 2, 'Без сахара');
 
ВЫПОЛНЕНИЕ ЗАДАНИЙ
Задание 1: добавить новый напиток в меню и создать заказ с этим напитком
Цель: добавить в меню позицию «Фраппучино» и оформить заказ с этим напитком.
SQL-запрос:
INSERT INTO menu_items (name, category, price, is_available) VALUES 
('Фраппучино', 'Кофе', 320.00, TRUE);

INSERT INTO orders (barista_id, order_time, total_amount, payment_method) VALUES
(3, NOW(), 320.00, 'Карта');

INSERT INTO order_details(order_id, menu_item_id, quantity, note) VALUES 
(62, 31, 1, 'Со льдом');
Пояснение логики: использован оператор INSERT INTO…VALUES для добавления строк. Функция NOW() автоматически подставляет текущие дату и время.
 
Проверка: добавлено по 1 строке в каждую таблицу.


Задание 2: вывести все заказы за сегодня с именами бариста, которые их приняли
Цель: получить список всех заказов за сегодня с именами бариста.
SQL-запрос:
SELECT
    o.id AS order_id,
    o.order_time,
    o.total_amount,
    o.payment_method,
    b.full_name
FROM orders o
JOIN baristas b ON o.barista_id = b.id
WHERE DATE(o.order_time) = CURRENT_DATE;
Пояснение логики: 
INNER JOIN соединяет таблицы по внешнему ключу. Функция DATE() выделяет дату из TIMESTAMP, CURRENT_DATE возвращает сегодняшнюю дату.
 
Проверка: выводятся только заказы за текущий день.

Задание 3: посчитать выручку по каждому бариста за неделю
Цель: подсчитать суммарную выручку по каждому бариста за последние 7 дней.
SQL-запрос:
SELECT
    b.id,
    b.full_name,
    SUM(o.total_amount) AS weekly_revenue
FROM orders o
JOIN baristas b ON o.barista_id = b.id
WHERE o.order_time >= NOW() - INTERVAL '7 days'
GROUP BY b.id, b.full_name
ORDER BY weekly_revenue DESC;
Пояснение логики: JOIN соединяет заказы с бариста. WHERE фильтрует заказы за 7 дней. GROUP BY группирует по бариста. Агрегатная функция SUM() считает общую выручку. ORDER BY DESC сортирует по убыванию.
 
Проверка: выводится список бариста с суммой их заказов за неделю.
Задание 4: найти самые популярные напитки (по количеству заказов), топ-5
Цель: определить 5 самых заказываемых позиций меню.
SQL-запрос:
SELECT
mi.id,
mi.name,
SUM(od.quantity) AS total_ordered
FROM order_details od
JOIN menu_items mi ON od.menu_item_id = mi.id
GROUP BY mi.id, mi.name
ORDER BY total_ordered DESC
LIMIT 5;
Пояснение логики: JOIN соединяет состав заказов с меню. GROUP BY группирует по позициям. SUM() суммирует проданное количество. ORDER BY DESC и LIMIT 5 оставляют только топ-5.
 
Проверка: выводится ровно 5 строк, отсортированных по убыванию.


Задание 5: cкрыть из меню (is_available = false) напиток, который закончился
Цель: пометить «Чизкейк» как недоступный для заказа.
SQL-запрос:
UPDATE menu_items SET is_available = FALSE
WHERE name = 'Чизкейк';
Пояснение логики: оператор UPDATE изменяет поле is_available. WHERE ограничивает изменение только позицией с указанным названием.
 
Проверка: поле is_available для «Чизкейк» изменилось с true на false.
 
ЗАКЛЮЧЕНИЕ
В ходе выполнения лабораторной работы была спроектирована и реализована реляционная база данных для кофейни CoffeeShopDB. Схема базы данных приведена к третьей нормальной форме (3NF), что исключает избыточность данных и аномалии при их обновлении.

В процессе работы освоены следующие навыки:
· проектирование ER-диаграмм и определение связей между таблицами (1:N, связующая таблица для M:N);
· написание DDL-скриптов для создания таблиц, внешних ключей и индексов;
· наполнение таблиц тестовыми данными с помощью оператора INSERT;
· составление запросов с использованием JOIN, WHERE, GROUP BY, ORDER BY и агрегатных функций (SUM, COUNT);
· фильтрация данных по дате с помощью DATE(), NOW(), INTERVAL;
· обновление данных с помощью оператора UPDATE.

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