From 292e4da4bcc1cc5a7b0c503088cec1a2461f1119 Mon Sep 17 00:00:00 2001 From: Dmitry Medvedev Date: Thu, 23 Jul 2026 00:09:45 +0500 Subject: [PATCH] fixed mistakes --- dmedvedev/2.1.theory_bd_indexes.sql | 4 ++-- dmedvedev/2.2.theory_bd_partitions.sql | 10 +++++----- dmedvedev/2.3.theory_bd_shard.sql | 3 +++ dmedvedev/2.4.theory_bd_replications.sql | 8 ++++---- dmedvedev/2.5.theory_bd_b_tree_hash_index.sql | 2 +- dmedvedev/2.6.theory_bd_acid_base.sql | 2 +- dmedvedev/4.1.greenplum_zaplosi.sql | 2 +- 7 files changed, 17 insertions(+), 14 deletions(-) diff --git a/dmedvedev/2.1.theory_bd_indexes.sql b/dmedvedev/2.1.theory_bd_indexes.sql index f5c3991..809bc5e 100644 --- a/dmedvedev/2.1.theory_bd_indexes.sql +++ b/dmedvedev/2.1.theory_bd_indexes.sql @@ -110,7 +110,7 @@ **Вопросы:** 1. Какой **один** составной индекс по полям `user_id` и `order_date` ты бы сделал (в каком порядке)? - CREATE INDEX idx_user_od ON orders(order_date, user_id) + CREATE INDEX idx_user_od ON orders(user_id, order_date) 2. Для каких из трёх запросов этот индекс будет работать особенно хорошо, а для каких — хуже? Объясни. Для первого особенно хорошо, потому что будет по двух индексам. @@ -190,7 +190,7 @@ Для каждого запроса оцени: «индекс нужен / не нужен», и если нужен — по каким полям: 1. SELECT * FROM users WHERE id = 100; нужен по полю id - 2. SELECT * FROM users WHERE email = 'user@example.com'; не нужен + 2. SELECT * FROM users WHERE email = 'user@example.com'; нужен по полю email 3. SELECT * FROM products WHERE price BETWEEN 100 AND 500; нужен по price 4. SELECT * FROM products WHERE name LIKE '%phone%'; нужен по name 5. SELECT * FROM orders WHERE status = 'DELIVERED'; нужен по status diff --git a/dmedvedev/2.2.theory_bd_partitions.sql b/dmedvedev/2.2.theory_bd_partitions.sql index 8be0563..0de96c9 100644 --- a/dmedvedev/2.2.theory_bd_partitions.sql +++ b/dmedvedev/2.2.theory_bd_partitions.sql @@ -30,7 +30,7 @@ - по дням. 2. Для каждого варианта напиши: - примерно сколько будет партиций за 10 лет; - по годам - 10, по месяцам - 12, по дням 7. + по годам - 10 * 1 = 10, по месяцам - 10 * 12 = 120, по дням 366 * 2 + 365 * 4 = 2652. - плюсы и минусы (удаление старых данных, поддержка, скорость запросов). @@ -54,16 +54,16 @@ - создать несколько партиций (например, по годам или другим диапазонам дат), чтобы вставка строк с разными датами автоматически попадала в нужную партицию; CREATE TABLE orderz_2023 PARTITION OF orderz - FOR VALUES FROM ('2023-01-01') TO ('2023-12-31'); + FOR VALUES FROM ('2023-01-01') TO ('2024-01-01'); CREATE TABLE orderz_2024 PARTITION OF orderz - FOR VALUES FROM ('2024-01-01') TO ('2024-12-31'); + FOR VALUES FROM ('2024-01-01') TO ('2025-01-01'); CREATE TABLE orderz_2025 PARTITION OF orderz - FOR VALUES FROM ('2025-01-01') TO ('2025-12-31'); + 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 ('2022-12-31'); + FOR VALUES FROM ('2000-01-01') TO ('2023-01-01'); - вставить тестовые данные с разными датами; INSERT INTO orderz (user_id, order_date, status) VALUES diff --git a/dmedvedev/2.3.theory_bd_shard.sql b/dmedvedev/2.3.theory_bd_shard.sql index 321c436..40e4ea8 100644 --- a/dmedvedev/2.3.theory_bd_shard.sql +++ b/dmedvedev/2.3.theory_bd_shard.sql @@ -26,6 +26,9 @@ ПОЛУЧИТЬ ДАННЫЕ ИЗ СТАРЫХ ШАРДОВ, НЕ УДАЛЯЯ НИ ДАННЫЕ, НИ ШАРДЫ, РАСКИДАТЬ ДАННЫЕ ПО НОВЫМ ШАРДАМ (СЕРВЕРАМ) И УДАЛИТЬ СТАРЫЕ ШАРДЫ; ПО ИДЕЕ ЗАПРОСЫ ВО ВРЕМЯ МИГРАЦИИ ТАК И БУДУТ ОБРАЩАТЬСЯ К СТАРЫМ ШАРДАМ, ВПЛОТЬ ДО МОМЕНТА, ПОКА ОНИ НЕ БУДУТ УДАЛЕНЫ. +НОВЫЙ ОТВЕТ: РАЗВЕРНУТЬ НОВЫЕ ШАРДЫ ПАРАЛЛЕЛЬНО СТАРЫМ И НАСТРОИТЬ ПАРАЛЛЕЛЬНУЮ МИГРАЦИЮ ДАННЫЕ В СТАРЫЕ И НОВЫЕ ШАРДЫ. ДАЛЕЕ БЕРЕМ ДАННЫЕ ИЗ СТАРЫХ ШАРДОВ И ЗАПУСКАЕМ ПРОЦЕСС КОПИРОВАНИЯ В НОВЫЕ ШАРДЫ. ПОСЛЕ ПЕРЕНОСА НАМ НУЖНО УДОСТОВЕРИТЬСЯ ЧТО ДАННЫЕ АНАЛОГИЧНО И ТАМ И ТАМ. ЕСЛИ ЕСТЬ РАСХОЖДЕНИЯ, ТО НУЖНО ИХ ДОПЕРЕНЕСТИ. +ПОТОМ НУЖНО ВЫКЛЮЧИТЬ ЗАПИСЬ В СТАРЫЕ ШАРДЫ И ОСТАВИТЬ ЗАПИСЬ НА НОВЫХ. + - Задание 3. Шардинг против партиционирования Есть одна большая база PostgreSQL с таблицей `orders`, и она начала тормозить. Команда обсуждает два варианта: сделать партиционирование в рамках одной базы или шардирование по нескольким базам/серверям. diff --git a/dmedvedev/2.4.theory_bd_replications.sql b/dmedvedev/2.4.theory_bd_replications.sql index 1e02f3a..056e2d7 100644 --- a/dmedvedev/2.4.theory_bd_replications.sql +++ b/dmedvedev/2.4.theory_bd_replications.sql @@ -50,16 +50,16 @@ Объяснить, чем логическая репликация отличается от физической: - на каком уровне передаются изменения; - ЗАТРУДНЯЮСЬ ОТВЕТИТЬ НА ДАННЫЙ ВОПРОС. + В ФИЗИЧЕСКОЙ ВСЕ ПЕРЕДАЕТСЯ НА УРОВНЕ БАЙТОВ, А В ЛОГИЧЕСКОЙ НА УРОВНЕ СТРОК И ТАБЛИЦ. - насколько гибко можно выбирать, какие таблицы и данные реплицировать; - ЗАТРУДНЯЮСЬ ОТВЕТИТЬ НА ДАННЫЙ ВОПРОС. + ФИЗИЧЕСКАЯ РЕПЛИКАЦИЯ НЕ ПОДРАЗУМЕВАЕТ ВЫБОР ТАБЛИЦ (ГИБКОСТЬ ОТСУТСТВУЕТ), В ЛОГИЧЕСКОЙ МОЖНО ВЫБИРАТЬ (МАКСИМАЛЬНАЯ ГИБКОСТЬ). - как это влияет на возможность миграций между версиями/схемами. - ЗАТРУДНЯЮСЬ ОТВЕТИТЬ НА ДАННЫЙ ВОПРОС. + С ФИЗИЧЕСКОЙ ЭТО БУДЕТ ТРУДНО ДЕЛАТЬ МИГРАЦИЮ МЕЖДУ РАЗНЫМИ ВЕРСИЯМИ, А В ЛОГИЧЕСКОЙ ПРОСТО ПОТОМУ ЧТО ПЕРЕНОСИТЬ ТАБЛИЦЫ МОЖНО КОМАНДАМИ, ОДНАКО НУЖНО СЛЕДИТЬ ЗА СХЕМАМИ В МАСТЕРЕ И НА РЕПЛИКЕ, ЧТОБЫ ОНИ СОВПАДАЛИ, ИНАЧЕ ПРИ ПЕРЕНОСЕ МОЖЕТ ВОЗНИКНУТЬ ОШИБКА. Придумать по одному сценарию, где логическая репликация удобнее, и где физическая проще и надёжнее. - ЗАТРУДНЯЮСЬ ОТВЕТИТЬ НА ДАННЫЙ ВОПРОС. + ФИЗИЧЕСКАЯ КОГДА НУЖНО СОЗДАТЬ СЕРВЕР ДУБЛЕР, А ЛОГИЧЕСКАЯ КОГДА НУЖНЫ НЕ ВСЕ ДАННЫЕ , А ЛИШЬ ДАННЫЕ ДЛЯ ПОСТРОЕНИЯ ВИТРИН. - Задание 4. Схема один мастер — несколько реплик для чтения diff --git a/dmedvedev/2.5.theory_bd_b_tree_hash_index.sql b/dmedvedev/2.5.theory_bd_b_tree_hash_index.sql index aa261e5..7138732 100644 --- a/dmedvedev/2.5.theory_bd_b_tree_hash_index.sql +++ b/dmedvedev/2.5.theory_bd_b_tree_hash_index.sql @@ -22,7 +22,7 @@ 3. SELECT * FROM users WHERE email LIKE 'alex%'; // будет, все норм 4. SELECT * FROM users WHERE email LIKE '%@gmail.com'; // не будет, так как ищем оканчание строки. не знаю что тут можно поменять, как-будто ничего 5. SELECT * FROM users ORDER BY email LIMIT 10; // будет, все норм - 6. SELECT * FROM users WHERE age BETWEEN 20 AND 30; // будет, все норм, но только B-tree + 6. SELECT * FROM users WHERE age BETWEEN 20 AND 30; // не будет - Задание 2: **Дана таблица заказов:** diff --git a/dmedvedev/2.6.theory_bd_acid_base.sql b/dmedvedev/2.6.theory_bd_acid_base.sql index 8545c8c..287bd5d 100644 --- a/dmedvedev/2.6.theory_bd_acid_base.sql +++ b/dmedvedev/2.6.theory_bd_acid_base.sql @@ -7,7 +7,7 @@ **Нужно:** - указать, какие свойства ACID здесь особенно важны и почему; - АТОМАРНОСТЬ (СДЕЛАНО ОДНО ДЕЙСТВИЕ, ЗНАЧИТ ДОЛЖЕН БЫТЬ ОДИН ЗАПРОС НА ПЕРЕВОД, А НЕ ДВА), ДЮРАБИЛИТИ (ОТСУТСТВУЕТ НАДЕЖНОСТЬ У ДАННОЙ ТРАНЗАКЦИИ). + АТОМАРНОСТЬ, ДЮРАБИЛИТИ (ОТСУТСТВУЕТ НАДЕЖНОСТЬ У ДАННОЙ ТРАНЗАКЦИИ), СОГЛАСОВАННОСТЬ - НЕЛЬЗЯ ПРОВЕСТИ ОДНУ ОПЕРАЦИЮ И ЗАСЧИТАТЬ ЕЕ ДВАЖДЫ. - описать, какие проблемы могут возникнуть, если этих свойств не будет (например, нет атомарности или изолированности). ЕСЛИ ЭТИХ СВОЙСТВ НЕ БУДЕТ, ТО ПРОИЗОЙДУТ ОШИБКИ, ДВА ОДИНАКОВЫХ ЗАПРОСА ИЛИ НЕИСПОЛНЕНИЕ ЗАПРОСА ВООБЩЕ. diff --git a/dmedvedev/4.1.greenplum_zaplosi.sql b/dmedvedev/4.1.greenplum_zaplosi.sql index 0afab42..5b3b9ab 100644 --- a/dmedvedev/4.1.greenplum_zaplosi.sql +++ b/dmedvedev/4.1.greenplum_zaplosi.sql @@ -46,7 +46,7 @@ FROM orders; **Вопрос:** - Как лучше распределить таблицу, если часто используешь оконные по `region_id`? - ДУМАЮ В ЭТОМ СЛУЧАЕ МОЖНО ПОМЕНЯТЬ destributed by по region_id ИЛИ МОЖНО СОСТАВНОЙ КЛЮЧ ПО region_id, user_id + ДУМАЮ В ЭТОМ СЛУЧАЕ МОЖНО ПОМЕНЯТЬ destributed by по region_id . ### Задача 3: