- Задание 1. Какой вид партиционирования выбрать **Ответ текстом.** 1. Таблица `orders(id, user_id, order_date, status)` — очень большая (10 лет истории). - Какой вид партиционирования (RANGE / LIST / HASH) ты выберешь и по какому полю? ДУМАЮ МОЖНО СДЕЛАТЬ 2 ПАРТИЦИИ, ПЕРВАЯ RANGE ПО ПОЛЯМ USER_ID И ORDER_DATE - RANGE. И ВТОРАЯ ПАРТИЦИЯ ПО USER_ID И STATUS - LIST - Какие типы запросов выиграют от этого выбора? Приведи 3 примера запросов. 2. Таблица `users(id, name, age, email, country, is_active, created_at)` — много пользователей по разным странам. - Выбери вид партиционирования (можно «не партиционировать») и обоснуй. МОЖНО ПО АЙДИ И СТРАНЕ - LIST. ПО АЙДИ И CREATE_AT - RANGE. COUNTRY И IS_ACTIVE - ЧТОБЫ ПОНИМАТЬ В КАКОЙ СТРАНЕ БОЛЬШЕ АКТИВНЫХ ПОЛЬЗОВАТЕЛЕЙ - МОЖЕТ HASH? - Если ты выбрал LIST по `country`, какие плюсы и минусы у такого решения? Огромное количество стран - минус. 3. Таблица логов `user_logs(id, user_id, created_at, event_type, payload)` — миллионы записей в день. - Какой вид партиционирования по какому полю логичен (RANGE / HASH) и почему? USER_ID и EVENT_TYPE по LIST или по HASH. - Задание 2. Размер партиций **Ответ текстом.** 1. Для `orders` с партиционированием по `order_date` придумай три варианта: - партиции по годам; - по месяцам; - по дням. 2. Для каждого варианта напиши: - примерно сколько будет партиций за 10 лет; по годам - 10 * 1 = 10, по месяцам - 10 * 12 = 120, по дням 366 * 2 + 365 * 4 = 2652. - плюсы и минусы (удаление старых данных, поддержка, скорость запросов). 3. Выбери один вариант и обоснуй: почему он оптимален для большого онлайн‑магазина. Для онлайн магазина лучше подойдет по месяцам, чтобы понимать сезонность товаров. - Задание 3. RANGE‑партиции по дате заказов **Уточнение**: партиционировать уже существующую таблицу муторно, проще создать новую **Сделать в PostgreSQL:** - создать партиционированную таблицу `orders`, разбитую методом RANGE по полю `order_date`; CREATE TABLE orderz ( id INT GENERATED ALWAYS AS IDENTITY, user_id INT NOT NULL, order_date DATE NOT NULL, status TEXT NOT NULL, PRIMARY KEY (id, order_date) ) PARTITION BY RANGE(order_date); - создать несколько партиций (например, по годам или другим диапазонам дат), чтобы вставка строк с разными датами автоматически попадала в нужную партицию; CREATE TABLE orderz_2023 PARTITION OF orderz FOR VALUES FROM ('2023-01-01') TO ('2024-01-01'); CREATE TABLE orderz_2024 PARTITION OF orderz FOR VALUES FROM ('2024-01-01') TO ('2025-01-01'); CREATE TABLE orderz_2025 PARTITION OF orderz FOR VALUES FROM ('2025-01-01') TO ('2026-01-01'); CREATE TABLE orderz_before_2023 PARTITION OF orderz FOR VALUES FROM ('2000-01-01') TO ('2023-01-01'); - вставить тестовые данные с разными датами; INSERT INTO orderz (user_id, order_date, status) VALUES (1, '2023-04-06', 'paid'), (2, '2024-07-17', 'decline'), (3, '2007-11-27', 'error'); - Написать несколько запросов выборки (за один год, за несколько лет, за весь период) SELECT * FROM orderz o WHERE order_date BETWEEN ('2023-01-01') AND ('2023-12-31'); SELECT * FROM orderz o WHERE order_date BETWEEN ('2022-01-01') AND ('2024-12-31'); SELECT * FROM orderz o; - Объяснить, в каких случаях БД будет читать только часть партиций, а в каких — все. Если мы выставляем определенное условие соответствующее одной партиции, то чтение будет по этой же партиции, если выставляем по нескольким, то чтение по нескольким. - Задание 4. LIST‑партиции по стране пользователей **Сделать в PostgreSQL:** - создать партиционированную таблицу `users`, разделённую методом LIST по полю `country`; CREATE TABLE userz ( id INT PRIMARY KEY, name TEXT NOT NULL, age INT, email TEXT NOT NULL, country TEXT NOT NULL, is_active BOOLEAN NOT NULL, created_at TIMESTAMP NOT NULL ) PARTITION BY LIST (country); - определить несколько партиций для разных стран или групп стран и вставить тестовые данные так, чтобы строки автоматически распределялись по этим партициям; CREATE TABLE userz_ru PARTITION OF userz FOR VALUES IN ('RU'); CREATE TABLE userz_us PARTITION OF userz FOR VALUES IN ('US'); CREATE TABLE userz_other PARTITION OF userz FOR VALUES IN (DEFAULT); - написать запросы выборки: - по конкретной стране (например, только пользователи из одной страны); SELECT * FROM userz u WHERE country = 'RU'; - по условию, не связанному с `country` (например, все активные пользователи); SELECT * FROM userz u WHERE status = 'is_active'; - Объясни, для какого запроса PostgreSQL может обращаться только к одной/нескольким партициям, а для какого придётся просматривать все партиции. Первый запрос обращается именно к одной партиции, а второй уже ко всем, потому что вто второй нет условия по партиции 'RU'. - Задание 5. HASH‑партиции по user_id в логах **Сделать в PostgreSQL:** - создать таблицу `user_logs`, партиционированную методом HASH по полю `user_id`, с несколькими партициями; CREATE TABLE user_logz ( id BIGSERIAL PRIMARY KEY, user_id BIGINT NOT NULL, created_at TIMESTAMP NOT NULL, event_type TEXT NOT NULL, payload JSONB ) PARTITION BY HASH (user_id); CREATE TABLE user_logz_p0 PARTITION OF user_logz FOR VALUES WITH (MODULUS 4, REMAINDER 0); CREATE TABLE user_logz_p1 PARTITION OF user_logz FOR VALUES WITH (MODULUS 4, REMAINDER 1); CREATE TABLE user_logz_p2 PARTITION OF user_logz FOR VALUES WITH (MODULUS 4, REMAINDER 2); CREATE TABLE user_logz_p3 PARTITION OF user_logz FOR VALUES WITH (MODULUS 4, REMAINDER 3); - заполнить таблицу тестовыми строками с разными значениями `user_id`; INSERT INTO user_logz (user_id, created_at, event_type, payload) VALUES (10, now(), 'login', '{"ip": "127.0.0.1"}'); SELECT * FROM user_logz WHERE created_at >= now() - interval '1 day'; - написать запрос: - выборки всех логов по конкретному `user_id`; SELECT * FROM user_logz WHERE user_id = 10; - выборки всех логов за период по полю `created_at` (без фильтра по `user_id`); SELECT * FROM user_logz WHERE created_at >= now() - interval '1 day'; - Объясни какой запрос позволит серверу обратиться только к одной партиции, а какой заставит сканировать все партиции и почему. Первый запрос обращается к одной партиции потому что есть условие по партиционному полю, второй именно ко всем таблицам, потому что нет условия по партиции.