> Что такое кардинальность колонок и зачем это знать (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). Здесь индекс может быть полезен, но нужно смотреть на распределение значений.

Зачем это знать:

  1. Выбор индексов - для колонок с высокой кардинальностью индекс даёт большой выигрыш, для низкой - почти никакого.
  2. Планировщик запросов - PostgreSQL и MySQL используют статистику по кардинальности для оценки стоимости плана. Если статистика устарела, запросы могут деградировать.
  3. Проектирование схемы - если колонка имеет низкую кардинальность, возможно, стоит использовать enum или отдельную таблицу-справочник.
  4. Оптимизация 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-разработчика.
  • Путаница между кардинальностью и селективностью - это разные понятия, хотя и связанные.
  • Забывают про обновление статистики после массовых изменений данных.

> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?

Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью