Какой тип данных лучше присвоить полю ИНН в базе данных
Что проверяют
Отличаете ли вы число от идентификатора, записанного цифрами. Аналитику важно не только назвать тип, но и описать ограничения поля в требованиях. Следом обычно спрашивают про валидацию и уникальность.
Как отвечать
ИНН хранят строкой, а не числом:
- ведущий ноль: ИНН начинается с кода налогового органа, и у ряда регионов этот код начинается с нуля. В числовом поле ноль пропадёт, и значение перестанет совпадать с документами;
- разная длина: у организации 10 цифр, у физлица и ИП 12. Двенадцатизначное значение не помещается в
integer, а арифметика над ИНН смысла не имеет; - это код, а не количество: у него есть контрольные цифры и структура.
Практичный вариант для PostgreSQL: varchar(12) с ограничением CHECK (inn ~ '^([0-9]{10}|[0-9]{12})$'). Контрольные цифры (одна у десятизначного ИНН, две у двенадцатизначного) проверяют в приложении по алгоритму ФНС. В требованиях это оформляют отдельным правилом валидации с текстом ошибки для пользователя.
Дальше покажите, что думаете о предметной области:
- КПП: у организации рядом с ИНН обычно нужен КПП, 9 символов, тоже строкой;
- уникальность: у обособленных подразделений ИНН совпадает с головной организацией, а КПП разный. Уникальный индекс только по ИНН в справочнике контрагентов сломает заведение филиалов;
- пустые значения: у иностранного контрагента ИНН может не быть, поле должно допускать
NULL, а не пустую строку или нули; - персональные данные: ИНН физлица относится к персональным данным, это влияет на доступы и маскирование в интерфейсе.
Где спотыкаются
Выбирают bigint, потому что «там только цифры». Ведущие нули теряются, и поиск по ИНН, скопированному из выписки, перестаёт находить запись.
Берут char(12). Десятизначный ИНН дополняется пробелами, приложение получает значение с хвостом, на котором ломаются сравнения и выгрузки. Выигрыша в скорости char в PostgreSQL не даёт, документация прямо советует varchar или text.
Путают длины и говорят, что 10 цифр у физлица. На собеседовании аналитика это сразу читается как незнание предметной области.