Типы данных и качество данных
«Расскажите, как вы проверяете качество данных перед анализом» — вопрос, на котором отсеивают половину кандидатов.
Качество данных — это не «нет ошибок», а измеримый набор свойств: полнота, уникальность, валидность, согласованность, актуальность и точность.
Вопрос 1. Какие бывают типы данных и почему это важно аналитику?
Что проверяет интервьюер. Не помните ли вы список типов из документации, а понимаете ли, что тип определяет, какие операции над данными вообще имеют смысл. Считать среднее по почтовым индексам можно технически и нельзя содержательно.
Аналитику удобнее держать в голове не типы СУБД, а шкалы измерения:
| Шкала | Пример | Что можно считать |
| Номинальная | город, канал привлечения | частоты, мода |
| Порядковая | оценка 1–5, грейд | + медиана, квантили |
| Интервальная | дата, температура в °C | + разности, среднее |
| Абсолютная | выручка, число заказов | + отношения, суммы, проценты |
Отсюда честный ответ на классическую подколку «посчитайте среднее по полю region_id»: среднее по идентификатору бессмысленно, region_id — номинальная шкала, записанная числом. Такие поля в хранилище лучше держать текстом или явно помечать как категориальные.
Вторая половина вопроса — про типы в базе. Три вещи, которые спрашивают чаще всего:
- Деньги нельзя хранить во
FLOAT:0.1 + 0.2в двоичной плавающей точке не равно0.3, и на миллионе строк это превращается в расхождение с бухгалтерией. НуженDECIMAL/NUMERICили целые копейки. - Дата ≠ строка. Строка
'2026-13-01'спокойно ляжет вTEXT, а сортировка'10.03.2026'будет лексикографической и уедет. - Часовые пояса. Если события пишутся в UTC, а отчёт строится по московскому дню, суточные метрики сдвинутся на три часа — и «падение трафика ночью» окажется артефактом.
Вопрос 2. Как вы проверяете качество данных?
Сильный ответ — назвать измерения качества и показать, что для каждого есть конкретная проверка. Слабый — сказать «смотрю глазами в Excel».
| Измерение | Проверка |
| Полнота | доля NULL и пустых строк по каждой колонке |
| Уникальность | дубли по бизнес-ключу, а не только по id |
| Валидность | диапазоны (возраст 0–120), формат email, домен значений статуса |
| Согласованность | сумма заказов сходится с суммой строк заказа; нет заказов у несуществующих клиентов |
| Актуальность | максимальная дата в таблице — сегодняшняя, а не позавчерашняя |
| Точность | сверка с внешним источником: биллинг, 1С, рекламный кабинет |
На практике это один SQL-запрос, который прогоняют по каждой новой выгрузке:
CREATE TABLE raw_users (id INTEGER, email TEXT, age INTEGER, revenue REAL);
INSERT INTO raw_users VALUES
(1,'anna@mail.ru',29,1200.0),
(2,'boris@mail.ru',NULL,0.0),
(2,'boris@mail.ru',NULL,0.0),
(3,'vera@mail.ru',34,NULL),
(4,'',-5,450.5),
(5,'gleb@mail.ru',201,300.0);
SELECT
COUNT(*) AS rows_total,
COUNT(DISTINCT id) AS ids_unique,
SUM(CASE WHEN age IS NULL THEN 1 ELSE 0 END) AS age_nulls,
SUM(CASE WHEN revenue IS NULL THEN 1 ELSE 0 END) AS revenue_nulls,
SUM(CASE WHEN email IS NULL OR email = '' THEN 1 ELSE 0 END) AS email_bad,
SUM(CASE WHEN age < 0 OR age > 120 THEN 1 ELSE 0 END) AS age_impossible
FROM raw_users;
Вывод:
rows_total ids_unique age_nulls revenue_nulls email_bad age_impossible
6 5 2 1 1 2
Шесть строк, пять уникальных id — значит есть дубль. Два невозможных возраста (-5 и 201), один пустой email, пропуски в двух колонках. Такой профиль занимает минуту, а спасает от отчёта, который придётся отзывать.
Вопрос 3. Что делать с найденными проблемами?
Тот же профиль на Python — код, который можно запустить прямо здесь:
from collections import Counter
rows = [
{"id": 1, "email": "anna@mail.ru", "age": "29"},
{"id": 2, "email": "boris@mail.ru", "age": ""},
{"id": 2, "email": "boris@mail.ru", "age": ""},
{"id": 3, "email": "vera(at)mail.ru", "age": "34"},
{"id": 4, "email": "gleb@mail.ru", "age": "201"},
]
ids = Counter(r["id"] for r in rows)
print("Дубликаты id:", [i for i, c in ids.items() if c > 1])
print("Пустой age:", sum(1 for r in rows if r["age"] == ""))
print("Битый email:", [r["id"] for r in rows if "@" not in r["email"]])
print("Возраст вне диапазона:",
[r["id"] for r in rows if r["age"].isdigit() and not 0 < int(r["age"]) < 120])
Вывод:
Дубликаты id: [2]
Пустой age: 2
Битый email: [3]
Возраст вне диапазона: [4]
Главная мысль, которую ждут от кандидата: данные не «чистят молча». Правильный порядок — зафиксировать проблему, оценить её масштаб в процентах, найти причину на стороне источника и только потом решать, чинить в ETL или возвращать поставщику данных. Молчаливое удаление 3% строк однажды окажется удалением всей мобильной аудитории.
Типичные ошибки кандидатов
- Отвечают «проверяю на NULL» и на этом заканчивают — про дубли, диапазоны и согласованность не вспоминают.
- Ищут дубли только по техническому
id, хотя бизнес-дубль — это одна и та же покупка с разными id. - Не спрашивают, что означает NULL в конкретной колонке: «неизвестно» и «ноль» требуют разной обработки.
- Не проверяют актуальность: отчёт строится, но данные приехали неделю назад.
- Считают среднее по полям-идентификаторам и категориям, закодированным числами.
Как ответить кратко
«Перед анализом я прогоняю профиль качества по шести измерениям: полнота (доля NULL), уникальность (дубли по бизнес-ключу, не только по id), валидность (диапазоны и форматы), согласованность (сходятся ли связанные таблицы), актуальность (свежая ли максимальная дата) и точность (сверка с источником вроде биллинга). Это один SQL-запрос с
COUNTиCASE WHEN. Найденное я не чиню молча: фиксирую долю проблемных строк, ищу причину на стороне источника и согласую правило обработки — иначе можно тихо выкинуть целый сегмент аудитории».