Простой вопрос, который разделяет инженеров и «операторов фреймворков»

Я провёл больше ста технических собеседований. Разных: на джуна, мидла, сеньора, системных аналитиков, бэкендеров, фуллстеков.

И у меня есть один вопрос. Простой до неприличия. Без алгоритмов, без паттернов проектирования, без «реализуй красно-чёрное дерево на доске».

Один вопрос, который с точностью хирургического скальпеля отделяет людей, которые думают о данных, от тех, кто просто заполняет формочки.

Вот он:

Вы проектируете базу данных. В ней нужно хранить серию и номер российского паспорта. Какой тип данных выберете? База – SQL.

Всё. Больше никаких условий. Можно уточнять, можно думать вслух.

Прежде чем читать дальше – ответьте себе честно. Прямо сейчас. Какой тип?


Что отвечают 8 из 10

Большинство кандидатов с ожиданиями от 150к рублей отвечают примерно так:

«Ну... это же цифры. Значит, INTEGER. Или BIGINT, если много данных».

Иногда добавляют:

«Можно NUMBER(10), чтобы ограничить длину».

Редкий кандидат скажет NUMERIC. Это звучит умнее, но суть та же.

Один PHP-разработчик с опытом больше пяти лет тоже уверенно ответил NUMBER. А когда я намекнул, что есть подвох, начал выкручиваться: «Ну, можно при чтении проверять длину числа, и если она меньше четырёх – дописывать ноль спереди». Костыль в бизнес-логике вместо правильного типа данных – и он настаивал, что «зато так база работает быстрее». Человек готов жонглировать строками в коде, лишь бы не пересмотреть выбор типа.

И все они ошибаются. Причём ошибка не в синтаксисе и не в незнании конкретной СУБД. Ошибка – в способе мышления.

Давайте разберём, почему.


Проблема первая: ведущий ноль

Да, многие из вас уже догадались, в чём подвох. Задача элементарная – и тем обиднее, что на ней спотыкаются снова и снова. Не джуны на первом собеседовании, а опытные разработчики с годами коммерческой практики.

Серия российского паспорта – это четыре цифры. Например: 0306.

Что произойдёт, если вы сохраните 0306 в поле типа INTEGER?

INSERT INTO persons (passport_series) VALUES (0306);
SELECT passport_series FROM persons; -- вернёт 306

Ведущий ноль исчезнет. Молча и без ошибки. База данных просто сделает своё дело: сохранит число триста шесть.

Паспорт серии 0306 и паспорт серии 306 – это юридически разные документы. Но в вашей базе они станут неотличимы.

Вы только что сломали идентификацию человека. Тихо, незаметно, без единого исключения в логах.

Масштабируем: в России живёт 146 миллионов человек. У скольких серия паспорта начинается с нуля? У миллионов. Поздравляю, вы только что помножили миллионы людей на тот самый ноль – в буквальном смысле. Их паспорта перестали существовать в корректном виде.


Проблема вторая: семантика

Но даже если бы ведущих нулей не существовало – тип INTEGER всё равно был бы неправильным ответом.

Спросите себя: что вы делаете с числами?

Вы складываете их. Вычитаете. Находите среднее. Делите. Сортируете по возрастанию, чтобы найти «наибольший» или «наименьший».

Теперь вопрос: когда вы в последний раз складывали серию паспорта с номером дома? Вычисляли среднее арифметическое паспортов в базе? Искали паспорт с «наибольшим» значением серии?

Никогда. Потому что это бессмысленно.

Паспорт – это идентификатор. Это метка, уникально указывающая на документ. Над идентификаторами не производят математических операций. Их сравнивают на равенство, ищут по ним, передают – и всё.

Это принципиально другая семантика. И тип данных должен эту семантику отражать.

Правильный ответ: VARCHAR (или CHAR, если длина фиксирована, что здесь как раз так).

-- Серия: ровно 4 символа
passport_series CHAR(4) NOT NULL,

-- Номер: ровно 6 символов  
passport_number CHAR(6) NOT NULL

Иногда серию и номер хранят в одном поле – тогда CHAR(10) или VARCHAR(10):

-- Серия + номер: 10 символов без пробела
passport_full CHAR(10) NOT NULL  -- '0306123456'

Смысл не меняется: это строка. Не число. Точка.


«Но ведь строки занимают больше места!»

Это возражение я слышу часто. И оно технически верное, но практически бессмысленное.

CHAR(4) для цифр занимает те же 4 байта, что и INTEGER (для однобайтовых символов, а цифры в любой кодировке – один байт). В данном случае разницы нет вообще.

Но даже если бы VARCHAR занимал в два раза больше – это не имело бы значения. Вы храните паспорт человека, а не оптимизируете хранилище для задачи уровня FAANG. Экономия нескольких байт на строке не стоит сломанных данных.


«А что если мне нужно быстро искать по паспорту?»

Поставьте индекс. Индекс на VARCHAR работает отлично. Поиск по точному совпадению строки через B-tree индекс – это O(log n), ровно как и для числа. (Да, hash-индекс даёт O(1) – но B-tree в большинстве СУБД стоит по умолчанию, и для наших объёмов разница неощутима.)

Если кто-то говори��, что «числовые индексы быстрее строковых» – пусть покажет бенчмарк на реальных данных. Для CHAR фиксированной длины разница практически нулевая.


Почему это важно прямо сейчас

Вы можете подумать: «Ну, это академический вопрос. На практике такое не встречается».

Встречается и постоянно.

Пару лет назад моя команда разрабатывала сервис для оформления заявок на парковочные абонементы. Один начинающий специалист спроектировал таблицу, в которой поле паспорта имело тип NUMBER. Форма прошла код-ревью, прошла тестирование, прошла приёмку – и благополучно ушла в прод. Работала без нареканий. Ровно до того момента, пока заявку не подал я сам.

У меня серия паспорта – 0306. Система проглотила ведущий ноль, сохранила 306, и заявка тихо сломалась. Не с ошибкой, не с исключением – просто данные стали невалидными. Паспорт в базе и паспорт на бумаге перестали совпадать.

С тех пор этот вопрос – один из моих любимых на собеседованиях. Не потому что он сложный, а потому что он настоящий. За ним стоит конкретный баг, конкретная сломанная заявка и конкретный урок: типы данных – это не синтаксис, это проектное решение.

Эту ситуацию можно было исключить одним правильным решением в начале.


Бонус: а что со СНИЛС и ИНН?

Раз уж мы разобрались с паспортом, давайте добьём тему.

СНИЛС – 11 цифр, формат XXX-XXX-XXX XX. Тип? VARCHAR(14) или CHAR(11) после очистки от дефисов. Не BIGINT. Никогда.

ИНН физлица – 12 цифр. Может начинаться с нуля? Да: коды регионов 01–09 (Адыгея, Башкортостан, Бурятия и т.д.) дают ИНН, начинающийся с нуля. Так что аргумент «ведущий ноль» здесь работает в полную силу. Но даже без него хранить в VARCHAR(12) – это правильная привычка, потому что ИНН – идентификатор, а не число.

Номер телефона+7 (903) 123-45-67. Тип? Только VARCHAR. Да, + можно отрезать и хранить чистые цифры 79031234567 – но даже в этом случае вы не будете складывать телефоны между собой. Телефон – идентификатор: его ищут, сравнивают и передают. Арифметика над ним бессмысленна. А если завтра потребуется хранить международный формат с + – придётся менять схему. VARCHAR(20) и никаких компромиссов.

Почтовый индекс – 6 цифр. Российские индексы начинаются с цифр от 1 до 6 (минимальный – 101000, Москва), с нуля не начинается ни один. Но для международных индексов (Великобритания, Канада) формат буквенно-цифровой, и главное – индекс всё равно не число. CHAR(6).

Паттерн везде один: если вы никогда не будете делать арифметику с этим полем – это не число.


Что на самом деле проверяет этот вопрос

Этот вопрос – не ловушка. Это не попытка поймать вас на незнании какой-то синтаксической особенности.

Он проверяет одну вещь: думаете ли вы о природе данных, прежде чем выбрать инструмент для их хранения.

Плохой инженер смотрит на данные и думает: «Там цифры – значит число».

Хороший инженер задаёт три вопроса:

  1. Какова семантика этих данных? (Что они означают?)

  2. Какие операции над ними будут производиться?

  3. Какие ограничения накладывает предметная область?

Только ответив на них, он выбирает тип.

Это и есть разница между человеком, который пишет код, и человеком, который решает задачи.


Полная таблица: идентификаторы в российских системах

Данные

Формат

Правильный тип

Частая ошибка

Что случится, если ошибётесь

Серия паспорта

4 цифры

CHAR(4)

INTEGER

Серия 0306306, документ невалиден

Номер паспорта

6 цифр

CHAR(6)

INTEGER

Потеря ведущего нуля, сломанная идентификация

Паспорт (серия + номер)

10 цифр

CHAR(10)

BIGINT

Потеря до двух ведущих нулей

СНИЛС

11 цифр

CHAR(11) или VARCHAR(14)

BIGINT

ИНН/СНИЛС регионов 01–09 обрезаются

ИНН физлица

12 цифр

CHAR(12)

BIGINT

ИНН с кодом 01–09 теряет разряд

ИНН юрлица

10 цифр

CHAR(10)

BIGINT

Аналогично: ведущий ноль → невалидный ИНН

Телефон

+7...

VARCHAR(20)

BIGINT

Невозможно хранить +, ломается формат

Почтовый индекс

6 цифр

CHAR(6)

INTEGER

Международный индекс не влезет

Банковский счёт

20 цифр

CHAR(20)

Нет подходящего INT

Переполнение, потеря денег

БИК

9 цифр

CHAR(9)

INTEGER

Обрезка при нестандартном коде

Вместо вывода

Если вы начинающий специалист – запомните эту таблицу. Она сэкономит вам часы отладки и сохранит репутацию.

Если вы сеньор – задайте этот вопрос на следующем собеседовании. Ответ скажет вам о кандидате больше, чем час разговора про паттерны.

Если вы тимлид – проверьте свою текущую схему БД. Прямо сегодня. Найдите поле с серией паспорта или СНИЛС. Посмотрите на его тип.

Иногда самые дорогие баги прячутся в самых скучных местах.


Эта статья – адаптированный фрагмент из моей книги «Поколение JSON: хроники Client-Side Testing». Книга о том, как индустрия свернула не туда. Бесплатная глава – на json-book.ru

Комментарии (188)


  1. Pavel7
    21.03.2026 08:38

    Паспорт серии 0306 и паспорт серии 306 – это юридически разные документы.

    Разве количество цифр в серии не всегда равно 4? Потому что я не очень понимаю, какая проблема в том, чтобы хранить 0306 как 306, если серия 306 невозможна. Никто не мешает отображать 306 как 0306, при этом.


    1. fire64
      21.03.2026 08:38

      Тоже не понимаю.

      Если у нас реальная длина фиксированная, то пусть даже будет 0001 мы то все равно понимаем, что если длина числа равна 1, то нужно добавить лидирующие нули.


      1. Akina
        21.03.2026 08:38

        Всё так, можно и проверить, и добавить. Но в процессе работы с данными вы получаете дополнительный оверхед - нужно преобразовать в строку, проверить длину, при необходимости добавить ведущий ноль... Что самое забавное - вы будете делать это каждый раз, когда оно понадобится. Я не верю, что кому-то в голову придёт вычитать один раз и закэшить в памяти, чтобы потом всё время использовать это один раз полученное нормализованное значение.

        А со строковым типом данных этого оверхеда нет.


        1. Yankee2d
          21.03.2026 08:38

          Спорно, потому что вам нужно очищать тоггда данные от пробелов и спецсимволов. И также везде при вводе.

          Далее, в большинстве систем, особенно в банковских, паспорт может быть иностранным.

          Если вы говорите про семантику, то у паспорта НОМЕР, а не символьный или числовой идентификатор.

          Номер это numeric. То, что в отображении используется форма с заполнением нулями слева не играет роли. Это отображение. Иногда это передача во внешние системы.

          Не только лишь семантика рулит выбором, а вся совокупность сценариев использования. К примеру, телефонный номер это число, но есть код страны, а коды страны пересекаются. Есть +37, есть +373. Для логинов проще хранить единый номер. Но отобразить в форме код и номер ты не сможешь, выбрать по странам не сможешь.

          Нормальный сеньор на ваш вопрос бы задал другой «а что за система и что вы собираетесь делать с этими номерами? Какие ограничения? Это только российские паспорта?»

          Сеньор решает задачу системы, а не задачу хранения отдельно. В постгресе есть вычислимые на лету поля. Если номера паспортов и серий в числовом виде не пересекаются и в будущем не предполагается вводить иностранные паспорта и население рф не собирается выпрыгивать за диапазон в ближайшие сто лет, тогда, например, числовой тип на весь номер и две вычислимые колонки серии и номера с lpad абсолютно не являются криминалом.


          1. Akina
            21.03.2026 08:38

            Спорно, потому что вам нужно очищать тогда данные от пробелов и спецсимволов. И также везде при вводе.

            Ну да... а при вводе в числовой тип всё это чистить не надо, да?

            Если вы говорите про семантику, то у паспорта НОМЕР, а не символьный или числовой идентификатор.

            У паспорта - идентификатор. Но какой-то товарищ назвал его "номер". И началося...

            Так что дело да, в терминологии. В слове, применённом там, где его значение лишь частично соответствует смыслу. И бездумном ориентировании на слово, а не на суть.

            Если номера паспортов и серий в числовом виде не пересекаются и в будущем не предполагается вводить иностранные паспорта ...

            Ага... ещё добавьте "мамой клянусь".

            Гарантии есть? нет. И сеньор ОБЯЗАН это и учесть, и предусмотреть.


          1. WhoIsJohnGolt
            21.03.2026 08:38

            Далее, в большинстве систем, особенно в банковских, паспорт может быть иностранным.

            Именно. Вы можете гарантировать, что в этих случаях серия и/или "номер" не будут содержать буквы?

            И "номером" это называется не везде. Чаще - именно "ID"


            1. Yankee2d
              21.03.2026 08:38

              Только логика в вашей статье совершенно от другого.

              На вопрос «в каком виде хранить номер паспорта» ответ не text, а встречный вопрос «какие ограничения, требования, сценарии использования, регуляторка». Номер паспорта является персданными и должен шифроваться.

              Ваш ответ, данный в статье, не ответ сеньора.


        1. GerrAlt
          21.03.2026 08:38

          нужно преобразовать в строку, проверить длину

          а проверка "< 1000" для серии чем-то вас обидела? или "< 1000000000" для серии и номера сразу?

          для ситуаций значений строго фиксированной длины рассуждения выглядят как бла-бла-бла, с одной стороны рассказ про 146 миллионов (и это надо еще помножить на несколько паспортов на каждого), а с другой экономия в несколько байт на строку - копейки


        1. MikhailB7
          21.03.2026 08:38

          А со строковым типом данных этого оверхеда нет.

          Весьма спорное утверждение.

          Вы уверовали в то, что номер паспорта-это идентификатор. И забыли ответить на свои же вопросы.

          1. Какова семантика этих данных? (Что они означают?)

          2. Какие операции над ними будут производиться?

          Серия паспорта-это весьма информативная составляющая. Первые 2 цифры-это код ОКАТО региона, где паспорт выдан. Вторые-год выпуска бланка. А вот номер паспорта-это как раз уникальный идентификатор.

          Исходя из ответа на первый вопрос, я легко могу представить систему, в которой необходимо найти паспорта в определённом регионе, выданные в промежутке между скажем 2009 и 2010 годами.

          И в этом случае числовой формат хранения даст более быстрый поиск.

          Другое дело, что такого рода системы встречаются реже, чем те, где номер паспорта-просто идентификатор. Но вы же не конкретизировали, какие именно функции предоставляет система, а просто безапелляционно утверждаете, что мы имеем дело с обычным идентификатором.


          1. Wesha
            21.03.2026 08:38

            я легко могу представить систему, в которой необходимо найти паспорта в определённом регионе, выданные в промежутке между скажем 2009 и 2010 годами.

            ..а потом окажется, что в некотором регионе у них остались невыданные бланки паспортов с прошлого года, и они решили «а чего добру пропадать» и выдали их не в том году.

            «Всё не так плохо, как вам кажется. Всё гораздо, ГОРАЗДО хуже!» ©


            1. MikhailB7
              21.03.2026 08:38

              Более того-так происходит почти всегда. Это нормально, когда прошлогодние бланки выдают в следующем году.

              Но замените слово "выданные" на "напечатанные" и вот уже запрос имеет практический смысл.

              По хорошему идентификатор не должен содержать смысловую нагрузку. А номер паспорта её содержит. А раз так, то можно и задачи на эту нагрузку придумать.


            1. MikhailB7
              21.03.2026 08:38

              Всех желающих хранить номер серию и номер паспорта одной строкой не думая, как вы их будете использовать, предлагаю найти алгоритм поиска в такой строке паспортов, напечатанных в определённые, задаваемые пользователем, годы. Ну и естественно подумать над вопросом, а нет-ли в таком алгоритме оверхеда при работе со строками.


              1. Wesha
                21.03.2026 08:38

                Все, кто предлагает НЕ хранить номер серию и номер паспорта одной строкой, не думают, что они будут со всем этим барахлом делать, когда бешеный принтер решит в очередной раз изменить формат.


                1. MikhailB7
                  21.03.2026 08:38

                  Просто иногда люди, предлагающие не хранить одной строкой, сначала выясняют все обстоятельства работы системы, взвешивают за и против, а затем уже предлагают. А не просто предлагают сферического коня в вакууме.

                  С чего вы решили, что в системе номер паспорта будет служить именно идентификатором человека, а не источником данных по отпечатанным бланкам, например?


                  1. Wesha
                    21.03.2026 08:38

                    А люди, предлагающие хранить одной строкой, в курсе, что бюрократы завтра какую-то новую схему номеров изобретут, и все эти бескрайние поля пойдут в пеший тур с эротическим уклоном.


            1. LexiusGaiden
              21.03.2026 08:38

              А потом выяснится, что при поиске сделать +1 все равно меньше нагрузка, чем искать по всему полю идентификаторов. Тем более код региона то точно не меняется


          1. shurutov
            21.03.2026 08:38

            Первые 2 цифры-это код ОКАТО региона, где паспорт выдан. Вторые-год выпуска бланка.

            Таки опять идентификатор. Формат которого вполне себе может быть изменён.


            1. MikhailB7
              21.03.2026 08:38

              Формат ОКАТО -это 8-11 цифр. Согласен, что теоретически он может быть изменён. Но сравнивать-то придётся 2 цифры с 8ю. И как следствие придётся хранить сокращённый вариант.

              Ещё раз-если идентификатор составной и несёт смысловую нагрузку, то всегда можно придумать задачи по этим смысловым полям.

              Я ответил на ваш вопрос: какова семантика данных. А вот какие операции над ними будут проводиться-надо разбирать по конкретной системе и требованиям к ней.

              Вы же продолжаете жить в парадигме, что "это просто идентификатор" Ничего кроме поиска по нему целиком не предполагая.


              1. shurutov
                21.03.2026 08:38

                Вы же продолжаете жить в парадигме, что "это просто идентификатор" Ничего кроме поиска по нему целиком не предполагая.

                Совершенно верно. Ибо здоровая паранойя - это профдеформация. Когда в сущность закладывается дополнительная информация, это, по моему совсем не скромному мнению, категорически неправильно. И использовать подобную информацию - совсем не стоит. Потому что вероятность пересмотра правил формирования весьма далека от нулевой.
                И, кстати, именно в российском паспорте есть ещё целых два поля, которые более точно укажут, где и кем выдавался паспорт:

                1. собственно, поле так и называет - "Паспорт выдан";

                2. и ещё одно - "Код подразделения".

                PS. Чем отличается проектировщик с опытом от начинающего, стартовый вопрос о типе хранения серии и номера паспорта, показывает вполне себе наглядно. Потому что, опытный проектировщик сразу вспомнит про паспорта иных государств, например.
                Ну а чтобы жизнь мёдом не казалась, да и в порядке ненаучно-фантастического бреда, поднакину-ка я мал-мала на вентилятор. Как вам ситуация, когда наши безмерно уважаемые и горячо любимые законотворцы родят указивку о том, чтобы использовать 16-ричную систему счисления для серии и номера паспорта?
                PSS. Глупость человеческая, в отличие от Вселенной, границ не имеет. :(
                PSSS. Я подхожу к проектированию, следуя правилу: Проектируй систему из условия, что её будет эксплуатировать (пользоваться ей) достаточно квалифицированный моральный урод, который будет стремиться её (систему) сломать, а потом отыграться на проектировщике, до которого сможет добраться.


                1. MikhailB7
                  21.03.2026 08:38

                  Так вопрос-то изначально не про дополнительные поля паспорта. С чего вы решили, что ваша система будет их содержать? Или что она будет с загран паспортами вообще работать? Возможно ваша система-это учёт бланков на госзнаке, где паспорт-вообще один из многих документов.

                  Я говорю о том, что проектировать хранение данных без учёта их применения вообще не правильно. И да, глупость границ не имеет. В том числе и при проектировании. И да, при проектировании надо всегда закладывать возможность изменения/расширения функциональности.

                  Мой изначальный пост был о том, что хранение номера паспорта в числовых полях не всегда даст оверхед по сравнению с хранением в строке.


          1. Akina
            21.03.2026 08:38

            И в этом случае числовой формат хранения даст более быстрый поиск.

            С точки зрения SQL это тупое WHERE column BETWEEN. И я лично не верю в это ваше "более быстрый поиск". При наличии подходящего индекса скорость поиска должна быть достаточно близкой..

            Серия паспорта-это весьма информативная составляющая. Первые 2 цифры-это код ОКАТО региона, где паспорт выдан. Вторые-год выпуска бланка.

            А с этим утверждением возможны два варианта.

            Первый - вы ГАРАНТИРУЕТЕ, что если при вводе мы разделим значение серии на два числовых поля, сохраним в БД только код ОКАТО и год выпуска, но не введённую серию, и в дальнейшем при запросе будем реконструировать значение серии, то у нас НИКОГДА не возникнет проблем - парсинга/преобразования, несоответствия введённого реконструированному и т.п.

            Готовы гарантировать, что так и будет - сейчас, завтра, через десять лет? По-серьёзному, без всяких "ну а чё мне будет?". Если нет, то имеем второй вариант - нулевую ценность и практическую неприменимость сделанного утверждения.


            1. MikhailB7
              21.03.2026 08:38

              А вы готовы гарантировать, что ваш where between обеспечит сопоставимую скорость по сравнению с поиском по числам при вводе пользователем 5-8 значений года для поиска? Нигде не напрягает, что мы там подстроки выделять будем?

              Ещё раз, в статье правильно сказал автор, что надо думать не только о семантике, но и о возможных условиях использования. Естественно при проектировании надо закладывать возможные сценарии изменения функций.

              Мой изначальный пост был про то, что использование использование числовых полей не всегда даёт оверхед при работе. Всё зависит от функций системы, которые вы старательно выводите из обсуждения, заменяя на наиболее частые варианты использования.


            1. MikhailB7
              21.03.2026 08:38

              Ну и я не гарантирую, а говорю, что разделение серии на ОКАТО и год выпуска при вводе и хранении-это один из возможных вариантов использования. И в этом случае есть смысл думать о числовых полях. Разделять или нет-зависит от функций конкретной системы. Если у вас серия и номер паспорта-это просто идентификатор, то нафиг вам числовые поля не сдались. А вот если вы хотите на их основе какой-то анализ строить (без доп полей), то как хранить-зависит от того, что вы анализировать будете.


          1. aleksandy
            21.03.2026 08:38

            Первые 2 цифры-это код ОКАТО региона, где паспорт выдан.

            Два моих и один паспорт супруги прямо таки всухую опровергают этот тезис: ни разу код региона выдачи не совпал с первыми двумя цифрами серии.


            1. MikhailB7
              21.03.2026 08:38

              Точно ОКАТО смотрели? Это не тоже самое, что код региона на номерах машин. Всё паспорта, что я видел строго совпадают.

              45 - Москва

              40- СПБ


      1. AlexGorky
        21.03.2026 08:38

        А вы не сталкивались с изменениями законодательства?
        Завтра разрешат паспорта с 5 знаками и как вы поймёте, 1 - это 0001 или 00001?


        1. zamboga
          21.03.2026 08:38

          Самое шикарное объяснение, почему нельзя хранить число и только на фронте рисовать ведущие нули.


          1. Benchstyle
            21.03.2026 08:38

            Всегда интересно почему фронт должен что-то дорисовывать. В идеале он просто отрисовывает


            1. Kenya-West
              21.03.2026 08:38

              "Ну закостыль мне это по-бырому, потом нормально на бэке сделаем, ну позязя, ты ж мой любимый сеньор манки патчер..." ©


          1. GerrAlt
            21.03.2026 08:38

            честно говоря я его не понял, почему вы думаете что при этом изменении паспорт 0001 и 00001 это будут разные паспорта?

            в системах с фиксированным числом разрядов при увеличении числа разрядов всегда делается пересчет - т.е. тот что был 0001 теперь 00001, у вас же система от добавления разряда не становится имеющей различное число знаков


            1. qwe101
              21.03.2026 08:38

              В уважаемой фирме изменили заводские номера. Прибавили впереди два 0. Знаков стало больше, никто старые номера изменять не предлагал. 0012345678 и 12345678 - разные номера. В жизни так.


              1. GerrAlt
                21.03.2026 08:38

                Возможно в уважаемых фирмах так можно (мне всеже сомнительно, т.к. судя по явно проставляемым ведущим нулям формат предполагает фиксированное число знаков, а эти номера фигурируют как минимум в учетных документах, и при таком подходе все документы содержащие 12345678 после изменения числа знаков оказались неверно заполненными), но как минимум с основным документом удоставеряющим личность это не так - формат его номера закреплен законом также как и, например, данные присутствующие на первой странице. Новый формат номера возможен для нового документа - например "паспорт гражданина РФ 2.0", но если появляется именно новый документ кажется что хранить его номер вместе с номерами другого документа идея сомнительная.


            1. ssj100
              21.03.2026 08:38

              А если вставят буквы а не цифры


              1. GerrAlt
                21.03.2026 08:38

                Тут кажется все достаточно прозрачно - новый формат номера это новый документ, и работать с ним надо как с другим документом, вы же не будете в одно поле писать и номер паспорта, и, например, номер охотничего билета?


                1. geher
                  21.03.2026 08:38

                  Паспорт1, паспорт2...


        1. qwe101
          21.03.2026 08:38

          У моего знакомого была банковская карта. Пин - 5 цифр. На заправке автомат получает 4 цифры и бежит проверять. Не подходит. Несколько раз. Результат - блокировка карты. За границей, без денег...


          1. aleksandy
            21.03.2026 08:38

            В Китае ситуация обратная: пин должен быть не менее 5 символов, и соотечественники, не зная данной особенности и имея 4-х значный пин, блокировали себе карты, т.к. банкоматы тупо считают невалидным пин с количеством знаков менее 5.

            А вот для правильного ввода 0 нужно вводить последним, а не первым символом.


      1. March228
        21.03.2026 08:38

        Это излишне


    1. MrTheFirst Автор
      21.03.2026 08:38

      Вы предлагаете классический антипаттерн – размазать ответственность за целостность данных тонким слоем по фронтенду или бизнес-логике. База данных должна хранить сам факт (идентификатор), а не математическую абстракцию, которую нужно каждый раз "собирать" костылями.

      Представьте: завтра к этой базе подключается новый микросервис, BI-система для аналитики или понадобится сырая выгрузка в CSV. Каждому новому клиенту придется заново писать этот костыль с подстановкой нулей. А если кто-то забудет это сделать? Данные разъедутся. База должна гарантировать консистентность: положили строку – достали строку.


      1. Pavel7
        21.03.2026 08:38

        Представьте: завтра к этой базе подключается новый микросервис, BI-система для аналитики или понадобится сырая выгрузка в CSV. Каждому новому клиенту придется заново писать этот костыль с подстановкой нулей.

        Нет, не придётся, в базах существуют представления.

        Но, вообще говоря, мой комментарий был про то, что такой механизм хранения никак не ломает идентификацию человека.

        Да и следуя вашей же аргументации, я могу вам сказать - представьте, что завтра в вашей базе начинают хранить не только российские, но и паспорта других стран. Или представьте, что завтра в вашей базе начинают хранить не только внутренние, но и загранпаспорта. Ваша предлагаемая схема готова к этому?


        1. MrTheFirst Автор
          21.03.2026 08:38

          Представления отличный инструмент. Но зачем изначально создавать себе проблему на уровне хранения (терять данные), чтобы потом героически её решать через View? База должна хранить консистентные факты. 

          Что касается изменения форматов в будущем: если МВД добавит пятую цифру, букву или дефис, тип CHAR или VARCHAR мигрировать/расширить гораздо проще. А вот если вы заложились на INTEGER, то при появлении букв ваша схема просто ляжет с ошибкой типизации.


          1. GerrAlt
            21.03.2026 08:38

            а вы считаете что эти теоретические новые номера корректно хранить вместе со старыми? законом закреплён формат документа, если вводится новый формат - это будет новый закон и новый документ

            вы же, наверное, не будете в колонку "номер паспорта гражданина РФ" писать, например, номер удостоверения моряка (хотя это тоже документ удостоверяющий личность)?


          1. seryoga77
            21.03.2026 08:38

            Даже если добавят пятую цифру, то скорее всего старые серии будут продолжать действовать. Скорее всего будут одновременно действовать 4 и 5-значные серии. Представляю какой взрыв мозга и толстый слой костылей ожидает тех, у кого числовой тип хранения)


          1. Pavel7
            21.03.2026 08:38

            Но зачем изначально создавать себе проблему на уровне хранения (терять данные)

            В хранении bigint-ом нет никакой потери данных. Нет коллизий, из хранимого значения однозначно восстанавливается отображаемое значение и обратно. Так можно вообще заявить, что хранение дат timestamp-ом - это потеря данных.

            чтобы потом героически её решать через View?

            Хранение bigint-ом не требует никакого ощутимого оверхеда в части разработки и развития. Ну и суть подобного решения очевидна - это повышение производительности. Меня изначально смутило заявление, что по производительности индексов bigint и char(10) " разница практически нулевая ". Мой опыт, да и просто банальная логика говорит об обратном. Загрузить два значения в два регистра и сделать cmp гораздо быстрее, чем побайтово грузить строки и cmp их.

            Меня это заинтересовало и я набросал простейший тест - инсёртим N номеров, ребилдим индекс, проверяем M номеров (90% существующих, 10% несуществующих). У меня получилось, что CHAR(10) минимум в полтора раза медленнее BIGINT и чем больше N, тем больше разница, конечно же.

            TYPE        ROWS         SEARCHED     AVG_MS (10 tries)
            ----------- ------------ ------------ ----------------------
            BIGINT      500000       100000       825.813
            CHAR(10)    500000       100000       1257.351
            
            BIGINT      2000000      100000       1018.259
            CHAR(10)    2000000      100000       1559.763
            
            BIGINT      10000000     200000       2146.738
            CHAR(10)    10000000     200000       3605.246

            Естественно, далеко не всегда нужно гнаться за этой производительностью, но с учётом того, что это практически ничего не стоит в части оверхеда, то BIGINT вполне себе жизнеспособный вариант, наряду с CHAR(10). А CHAR(10), например, будет быстрее в извлечении кусков серии, чем BIGINT.

            если МВД добавит пятую цифру, букву или дефис, тип CHAR или VARCHAR мигрировать/расширить гораздо проще

            То ваша схема просто ляжет с ошибкой транкейта и потребуется доработка физического хранилища.

            А вот если вы заложились на INTEGER, то при появлении букв ваша схема просто ляжет с ошибкой типизации.

            То есть потребуется доработка физического хранилища.

            А вот если МВД добавит пятую цифру в серию (что гораздо вероятнее, чем букву), то в случае BIGINT потребуется только доработка представления, а в случае CHAR(10) - хранилища.


            1. randomsimplenumber
              21.03.2026 08:38

              хранение дат timestamp-ом - это потеря данных.

              С какого года начинается Unix time, с 1970? В астрономии или истории могут случиться и другие диапазоны дат.


      1. GerrAlt
        21.03.2026 08:38

        я правильно понимаю что "костылем" в данном случае вы называете, например, SQL-функцию LPAD ?


        1. Warperus
          21.03.2026 08:38

          Которую придётся ляпать во всех поисковых запросах? Да, костыль, причём неудобный.


          1. GerrAlt
            21.03.2026 08:38

            а зачем ее добавлять в поисковых запросах?


    1. megabozzx
      21.03.2026 08:38

      Если завтра поменяют формат в новых выдаваемых паспортах, например добавят ещё одну цифру спереди серии, то хранение данных с таким подходом очень сильно сядет в лужу.


      1. Pavel7
        21.03.2026 08:38

        Если завтра поменяют формат в новых выдаваемых паспортах

        То и вариант схемы, предложенный автором, перестанет удовлеторять требованиям.


        1. alex_tulski
          21.03.2026 08:38

          Ну там к варчару надо будет один символ добавить, не проблема, а вот отличить серию 0384 от 00384 в виде инта не получится.


          1. GerrAlt
            21.03.2026 08:38

            так и не придется - серия имеет фиксированное число знаков, если теперь это 5 знаков - ок, значит 0384 теперь 00384

            от того что к фиксированной длине добавили разряд формат не стал предполагать вариативность в длине


            1. fshp
              21.03.2026 08:38

              А в выданных паспортах нолик дорисуется сам или нужно будет в ФМС записываться?


              1. GerrAlt
                21.03.2026 08:38

                если конкретно про паспорта то ни то ни другое - другой формат номера это другой документ

                для ситуаций инвентарных номеров и т.п. при смене формата пишут что-то вроде "при указании номера меньшей длины считать номер дополненным нулями слева до <число> знаков"


                1. fshp
                  21.03.2026 08:38

                  Вы сами себе противоречите. Если другой формат это другой документ, то серия 0384 в базе не должна превратиться в 00384, т.к. это разные документы.


                  1. GerrAlt
                    21.03.2026 08:38

                    Если мы обсуждаем конкретно паспорта то да, новый формат номера это новый документ, и с моей точки зрения хранить его номер там же где хранятся номера "старых" документов неверно.

                    Вариант для менее бюрократизированных случае я привел как пример, как в некоторых случаях могут работать с номерами, для основного документа удостоверяющего личность это неприминимо.


              1. alex_tulski
                21.03.2026 08:38

                А в выданных паспортах количество символов останется тем же до замены документа. 0384 и 00384 это две разные серии


                1. fshp
                  21.03.2026 08:38

                  Именно поэтому их нельзя считать одинаковыми.


      1. ssj100
        21.03.2026 08:38

        А если букву?


    1. h4r7w3l1
      21.03.2026 08:38

      Паспортные данные (серия, номер, дата выдачи, орган выдачи) должны храниться точно в том формате, в котором они представлены в документе, без потери ведущих нулей или других преобразований. Регулируется ст.5 фз-152, в случая аудита ПДн обрезания не лучший вариант

      Вопрос больше в цели, если производительность критична и эффективность хранения, можно и в int на самом деле хранить, в тотже ch это будет эффективней, но с практичной точки зрения такой формат для расположения "рядом", т.е. фактически помимо pass_serial char(4), pass_number char(6) можно и в passport_data int(11)

      з.ы. по сабжу автору статьи, не знаю причем тут тест на синьора, будучи еще зеленым мидлои при первой практике с номерами телефонов мне стало очевидно что это совсем не про тип номерной в строчный. скорее тут тест больше на теоретиков и тех кто ручками пощупал что это такое