4674. Вы проектируете аналитическую систему для ритейла, где ключевые отчеты строятся по итогам дня, недели, месяца. Какой наиболее правильный и распространенный архитектурный подход?
Anonymous Quiz
16%
Реплицировать OLTP-базу на отдельный сервер и выполнять запросы там.
16%
Настроить индексы в операционной БД так, чтобы они покрывали все аналитические запросы.
56%
Реализовать механизм ETL, который будет переносить и преобразовывать данные в отдельное хранилище.
11%
Выполнять агрегации в реальном времени, используя кэширующий слой с предвычисленными значениями.
👩🏫Объяснение:
Это классический паттерн разделения на OLTP (операционная обработка транзакций) и OLAP (аналитическая обработка). Прямые аналитические запросы к OLTP-системе (A, B) блокируют операционные транзакции и убивают производительность. ETL-процесс (C) переносит данные в специально спроектированное хранилище (DWH), где данные денормализованы, структурированы по темам (схема «звезда»/«снежинка») и используют эффективные для чтения форматы хранения (колоночные СУБД). Кэш (D) хорош для простых метрик, но не для гибкой, многомерной аналитики.
4675. В таблице documents есть поле version (целое число). Как должен выглядеть SQL-запрос для обновления документа, который гарантированно предотвратит «потерянное обновление» (lost update), если два пользователя редактируют один документ?
Anonymous Quiz
21%
UPDATE documents SET content='новый текст', version = version + 1 WHERE id = 123;
48%
UPDATE documents SET content='новый текст', version = version + 1 WHERE id = 123 AND version
21%
SELECT ... FOR UPDATE; затем UPDATE documents ... WHERE id=123;
10%
UPDATE documents SET content='новый текст' WHERE id = 123;
👩🏫Объяснение:
Суть оптимистичной блокировки — позволить всем читать данные, но проверять, изменились ли они с момента чтения, в момент записи. Ключевой элемент — проверка версии в условии WHERE. Если другой процесс уже успел обновить документ, то его version изменился, и запрос текущего процесса (B) не затронет ни одной строки (affected rows = 0). Приложение, увидев 0 измененных строк, поймет, что произошел конфликт и должно предложить пользователю разрешить его. Вариант A увеличит версию всегда, потеряв первое обновление. Вариант C — это пессимистическая блокировка. Вариант D не использует версионирование вовсе.
4676. Требуется сложная морфология, ранжирование по релевантности, фасетный поиск и отказоустойчивость. Какое решение является индустриальным стандартом?
Anonymous Quiz
9%
Перейти на более мощный сервер БД с большим объемом RAM.
16%
Реализовать кастомную логику поиска на стороне приложения, используя кэш.
66%
Использовать выделенную поисковую систему, такую как Elasticsearch или Apache Solr.
9%
Переписать все запросы, максимально их оптимизировав и добавив больше составных индексов.
👩🏫Объяснение:
Когда требования к поиску выходят за рамки базовых возможностей реляционных СУБД, используется специализированный поисковый движок. Elasticsearch/Solr построены на инвертированных индексах, созданных именно для задач:
* Полнотекстового поиска со стеммингом, синонимами, обработкой омонимов.
* Нечеткого поиска (fuzzy).
* Сложного ранжирования (relevance scoring) на основе TF-IDF, BM25.
* Масштабирования и отказоустойчивости за счет распределенной кластеризации.
«Подкручивание» существующей БД (A, D) дает лишь временный и ограниченный эффект. Кастомная реализация (B) неоправданно сложна и не будет соответствовать по качеству и производительности готовым решениям.
* Полнотекстового поиска со стеммингом, синонимами, обработкой омонимов.
* Нечеткого поиска (fuzzy).
* Сложного ранжирования (relevance scoring) на основе TF-IDF, BM25.
* Масштабирования и отказоустойчивости за счет распределенной кластеризации.
«Подкручивание» существующей БД (A, D) дает лишь временный и ограниченный эффект. Кастомная реализация (B) неоправданно сложна и не будет соответствовать по качеству и производительности готовым решениям.
4677. Таблица votes потенциально может расти на миллиарды строк. Критически важна скорость проверки, голосовал ли пользователь. Какой первичный ключ для таблицы votes будет оптимальным?
Anonymous Quiz
15%
id BIGSERIAL PRIMARY KEY (автоинкремент).
42%
Составной первичный ключ (user_id, entity_type, entity_id).
20%
PRIMARY KEY (entity_type, entity_id, user_id).
23%
uuid PRIMARY KEY.
👩🏫Объяснение:
Здесь важны две вещи: гарантия уникальности комбинации «пользователь-сущность» и скорость проверки этой уникальности при вставке. Составной первичный ключ (user_id, entity_type, entity_id) (B) идеально решает обе задачи:
1. Он на уровне БД гарантирует, что дубликат невозможен.
2. Запрос SELECT 1 FROM votes WHERE user_id = ? AND entity_type = ? AND entity_id = ? для проверки будет выполняться очень быстро, используя поиск по первичному ключу (т.е. по кластеризованному индексу).
Порядок колонок важен: если чаще проверяют по user_id, он должен быть первым. Ключ из варианта C тоже рабочий, но оптимизирован для поиска всех голосов за сущность, что менее частый сценарий. Автоинкремент (A) и UUID (D) не предотвращают дублирование логических записей без отдельного UNIQUE-ограничения.
1. Он на уровне БД гарантирует, что дубликат невозможен.
2. Запрос SELECT 1 FROM votes WHERE user_id = ? AND entity_type = ? AND entity_id = ? для проверки будет выполняться очень быстро, используя поиск по первичному ключу (т.е. по кластеризованному индексу).
Порядок колонок важен: если чаще проверяют по user_id, он должен быть первым. Ключ из варианта C тоже рабочий, но оптимизирован для поиска всех голосов за сущность, что менее частый сценарий. Автоинкремент (A) и UUID (D) не предотвращают дублирование логических записей без отдельного UNIQUE-ограничения.
4678. Вы обнаружили, что в таблице events с временными рядами 99% запросов обращаются только к данным за последние 7 дней. Таблица содержит данные за 5 лет. Какое изменение структуры хранения даст максимальный эффект ?
Anonymous Quiz
62%
Создать партиционирование таблицы по диапазону дат (например, по дням или неделям).
14%
Добавить индекс на поле с датой, включив в него все часто запрашиваемые колонки.
3%
Запустить процедуру полной перестройки (REINDEX) всех индексов таблицы.
22%
Регулярно (раз в неделю) удалять старые данные, перемещая их в архивную таблицу.
👩🏫Объяснение:
Партиционирование — наиболее фундаментальное и эффективное решение для временных рядов с ярко выраженным паттерном доступа к «горячим» (свежим) данным. Оно позволяет:
* Резко уменьшить объем сканируемых данных: оптимизатор запросов будет обращаться только к партициям за последние 7 дней (партициональная прунинг).
* Упростить управление жизненным циклом: удаление старых данных (DROP PARTITION) — мгновенная и дешевая операция.
* Улучшить производительность обслуживания: операции VACUUM, REINDEX можно выполнять точечно на устаревших партициях.
Создание покрывающего индекса (B) или его перестройка (C) могут помочь, но не решат проблему работы с огромной неделимой таблицей. Ручное перемещение данных (D) — это, по сути, «ручное» партиционирование, но менее эффективное и встроенное в СУБД.
* Резко уменьшить объем сканируемых данных: оптимизатор запросов будет обращаться только к партициям за последние 7 дней (партициональная прунинг).
* Упростить управление жизненным циклом: удаление старых данных (DROP PARTITION) — мгновенная и дешевая операция.
* Улучшить производительность обслуживания: операции VACUUM, REINDEX можно выполнять точечно на устаревших партициях.
Создание покрывающего индекса (B) или его перестройка (C) могут помочь, но не решат проблему работы с огромной неделимой таблицей. Ручное перемещение данных (D) — это, по сути, «ручное» партиционирование, но менее эффективное и встроенное в СУБД.
4679. Какую репликацию нужно настроить для гарантии того, что реплика всегда имеет актуальные данные.
Anonymous Quiz
54%
Синхронную репликацию (Synchronous Replication).
31%
Асинхронную репликацию (Asynchronous Replication) с более быстрым сетевым оборудованием.
4%
Логическую репликацию (Logical Replication).
10%
Каскадную репликацию (Cascade Replication).
👩🏫Объяснение:
Синхронная репликация гарантирует, что транзакция на мастере будет считаться завершенной (получит COMMIT) только после того, как изменения будут записаны не только на мастер, но и на реплику (или реплики). Это обеспечивает нулевое отставание (RPO=0) для выбранных реплик и защиту от потери данных. Недостаток — повышенная задержка записи на мастер и его остановка, если реплика «упала». Асинхронная репликация (B) всегда имеет лаг. Логическая (C) и каскадная (D) репликации — это варианты реализации, которые сами по себе могут быть как синхронными, так и асинхронными.
4680. Вы проектируете схему для хранения древовидных комментариев (как в Reddit или Хабре) с неограниченным уровнем вложенности. Какой метод хранения иерархии позволит наиболее эффективно выбрать всю ветку обсуждения для одного корневого комментария?
Anonymous Quiz
42%
Структура «Вложенные множества» (Nested Sets).
25%
Поле parent_id со ссылкой на родительский комментарий.
25%
Хранение пути (path) в виде материализованного пути (например, 1.5.12.34).
7%
Таблица замыканий (Closure Table).
👩🏫Объяснение:
Для задачи выборки целого поддерева структура «Вложенные множества» является самой эффективной. Каждая вершина хранит два числа: left и right. Все потомки вершины X имеют left между X.left и X.right. Чтобы выбрать всё поддерево, нужен один простой запрос: SELECT * FROM comments WHERE left >= @root_left AND right <= @root_right ORDER BY left. Это выполняется за один проход по индексу. Поле parent_id (B) потребует рекурсивного запроса (CTE) или множества обращений к БД. Материализованный путь (C) потребует использования LIKE. Closure Table (D) также эффективен, но требует JOIN со служебной таблицей. Nested Sets идеальны для частого чтения поддеревьев, но очень неэффективны для вставки/перемещения узлов.
❤1👍1🔥1