> Что такое кардинальность колонок и зачем это знать (Go)
Уровень: junior · Роль: backend · Язык: Go · Категория: Технические вопросы
Компании: Employcity
Стек: Go
> Пример ответа
Короткий ответ
Кардинальность колонки - это количество уникальных значений в ней относительно общего числа строк. Например, колонка id имеет высокую кардинальность (почти все значения уникальны), а колонка status - низкую (несколько повторяющихся значений). Знать это важно, потому что кардинальность напрямую влияет на выбор индексов, производительность запросов и проектирование схемы БД. Для backend-разработчика на Go это критично при работе с PostgreSQL или MySQL через драйверы вроде pgx или database/sql.
Подробное объяснение
Кардинальность бывает трёх типов:
- Высокая - почти все значения уникальны (например, UUID, email, timestamp). Индекс по такой колонке эффективен для поиска конкретного значения, но бесполезен для фильтрации по диапазону с большим количеством строк.
- Низкая - мало уникальных значений (например,
gender,status,is_active). Индекс по такой колонке почти не ускоряет запросы, потому что селективность низкая - запрос всё равно вернёт большой процент строк. - Средняя - промежуточный случай (например,
city,category_id). Здесь индекс может быть полезен, но нужно смотреть на распределение значений.
Зачем это знать:
- Выбор индексов - для колонок с высокой кардинальностью индекс даёт большой выигрыш, для низкой - почти никакого.
- Планировщик запросов - PostgreSQL и MySQL используют статистику по кардинальности для оценки стоимости плана. Если статистика устарела, запросы могут деградировать.
- Проектирование схемы - если колонка имеет низкую кардинальность, возможно, стоит использовать enum или отдельную таблицу-справочник.
- Оптимизация JOIN - кардинальность влияет на выбор порядка соединения таблиц и типа join (hash join vs nested loop).
На практике
В Go при работе с БД кардинальность учитывается на этапе написания SQL-запросов и создания миграций. Например, если у вас таблица orders с колонкой status, и вы часто фильтруете по ней, индекс не поможет, если значений всего 3-5. Вместо этого стоит подумать о партиционировании или изменении структуры запроса.
Также важно помнить, что кардинальность может меняться со временем. Например, колонка created_at сначала имеет низкую кардинальность (мало данных), но со временем становится высокой. Поэтому нужно периодически обновлять статистику (ANALYZE в PostgreSQL) и пересматривать индексы.
Пример кода
Пример миграции для PostgreSQL, где учитывается кардинальность:
SQL-- Высокая кардинальность - индекс полезенCREATE INDEX idx_orders_user_id ON orders (user_id);-- Низкая кардинальность - индекс бесполезен, лучше не создавать-- CREATE INDEX idx_orders_status ON orders (status); -- плохо
Пример запроса в Go с учётом кардинальности:
GO// Плохо: фильтр по низкокардинальной колонкеrows, err := db.Query("SELECT * FROM orders WHERE status = 'pending'")// Хорошо: фильтр по высококардинальной колонке + дополнительное условиеrows, err := db.Query("SELECT * FROM orders WHERE user_id = $1 AND status = 'pending'", userID)
Как отвечать на собеседовании
Начните с определения, затем приведите примеры высокой и низкой кардинальности. Обязательно свяжите это с индексами и производительностью. Если спросят про Go, упомяните, что кардинальность влияет на выбор стратегии кеширования и на то, как вы пишете SQL-запросы в коде. Хорошо показать понимание trade-off: индекс ускоряет чтение, но замедляет запись и занимает место.
Что проверяет интервьюер
- Понимаете ли вы разницу между высокой и низкой кардинальностью.
- Умеете ли вы применять это знание на практике - при проектировании схемы и написании запросов.
- Знаете ли вы, как кардинальность влияет на планировщик запросов и выбор индексов.
- Понимаете ли вы, что кардинальность - не статическая характеристика, она меняется со временем.
Типичные ошибки
- Создание индексов на низкокардинальных колонках без необходимости.
- Игнорирование кардинальности при написании JOIN - выбор неправильного типа join.
- Утверждение, что кардинальность важна только для DBA, а не для backend-разработчика.
- Путаница между кардинальностью и селективностью - это разные понятия, хотя и связанные.
- Забывают про обновление статистики после массовых изменений данных.
> Похожие задачи по Go
Для чего нужен sync.RWMutex и когда его использовать в Go
Можно ли отключить или ограничить запуск сборщика мусора в Go
Как избежать race condition при одновременном чтении и записи в таблицу транзакций в Go
Для чего нужно логирование
> Похожие задачи по backend
Для чего нужен sync.RWMutex и когда его использовать в Go
Можно ли отключить или ограничить запуск сборщика мусора в Go
Как избежать race condition при одновременном чтении и записи в таблицу транзакций в Go
Для чего нужно логирование
> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?
Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью