сеньорчикОткрыть в Telegram
← вся теориятеория к собесу · Модель данных

Типы данных и справочники

Типы данных и справочники

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

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

// Формулировки: «в каком типе хранить сумму?», «зачем справочник вместо текста?», «чем пустое значение отличается от пустой строки?»

Деньги, время, перечисления

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

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

Статус свободным текстом гарантированно даёт «Новый», «новый», «НОВЫЙ» и «Новая» в одной колонке - причём все четыре введут разные люди с полной уверенностью в своей правоте. Любая группировка после этого врёт, и отчёт показывает четыре статуса вместо одного.

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

Обязательность и пустое значение

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

Разница между пустым значением и пустой строкой не педантизм: пустое значение означает «неизвестно», пустая строка - «известно, и оно пустое». Это разные факты о мире.

И у пустого значения есть свойство, которое ломает отчёты. Оно не проходит ни условие равенства, ни его отрицание. Запрос «клиенты, у которых менеджер номер пять» его не вернёт, что логично. Но и запрос «клиенты, у которых менеджер не пятый» его тоже не вернёт - хотя человек, который писал этот запрос, наверняка имел в виду и клиентов вовсе без менеджера. Строки просто исчезают из обоих отчётов, и никто не замечает.

// Поэтому в требованиях полезно явно написать, что означает незаполненное поле и должно ли оно попадать в такие выборки. Одна строка текста экономит расследование расхождений в отчётах.

Когда уместно полуструктурированное хранение

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

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

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

Как отвечать: «Как хранить время в системе с пользователями из разных часовых поясов?»

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

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

На чём валятся

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

Проверьте себя

Пять вопросов из банка по этой подтеме. Всего их 13, остальные разбираются в тренажёре.

  1. #ana_dm_types1 / 5
    Зачем справочник вместо текстового поля со статусом?
    A)Чтобы поле занимало меньше места
    B)Чтобы разрешить пустые значения статуса
    C)Чтобы ускорить вставку новых записей
    D)Чтобы значения не расползались по написанию
    показать ответ и разбор
    +D)Чтобы значения не расползались по написанию

    // разбор: Свободный текст неизбежно даёт «Новый», «новый», «НОВЫЙ» и «Новая» — группировка ломается, отчёты врут. Справочник фиксирует перечень допустимых значений, даёт им коды и позволяет переименовать отображаемое название, не трогая данные и логику.

  2. #ana_dm_types2 / 5
    В каком виде хранить момент времени в системе с пользователями из разных часовых поясов?
    A)В локальном времени сервера
    B)В локальном времени пользователя
    C)В UTC с отдельным полем зоны
    D)Строкой в формате, привычном пользователю
    показать ответ и разбор
    +C)В UTC с отдельным полем зоны

    // разбор: Хранят абсолютный момент в UTC, а часовой пояс события держат отдельно, если он нужен для отображения или отчётности. Тогда сравнение и сортировка работают всегда, а перевод в местное время делается на выводе. Хранение в локальном времени рвётся на переходах и при переезде сервера.

  3. #ana_dm_types3 / 5
    Аналитик задал полю «Комментарий» ограничение в 50 символов. Что стоит проверить?
    A)Поддерживает ли СУБД такую длину
    B)Хватит ли этого в реальных сценариях
    C)Кратна ли длина степени двойки
    D)Не занято ли это имя другим полем
    показать ответ и разбор
    +B)Хватит ли этого в реальных сценариях

    // разбор: Ограничения длины приходят не из головы, а из практики: посмотреть, что пишут в аналогичное поле сейчас, и заложить запас. Слишком тесное поле пользователи обходят сокращениями и переносом смысла в соседние поля. Слишком широкое, впрочем, тоже вредно — оно приглашает складывать туда всё подряд.

  4. #ana_dm_types4 / 5
    Что не так с обязательным полем «Отчество»?
    A)Оно избыточно при наличии полного имени
    B)Оно замедляет поиск по таблице клиентов
    C)Отчество есть не у всех людей
    D)Оно дублирует данные из паспорта
    показать ответ и разбор
    +C)Отчество есть не у всех людей

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

  5. #ana_dm_types5 / 5
    Когда для гибких атрибутов оправдано хранение в JSON-поле?
    A)Когда нужна строгая проверка значений
    B)Когда по этим атрибутам строят отчёты
    C)Когда атрибутов больше двадцати
    D)Когда набор атрибутов заранее неизвестен
    показать ответ и разбор
    +D)Когда набор атрибутов заранее неизвестен

    // разбор: Полуструктурированное хранение спасает, когда состав полей задаёт клиент или он различается от объекта к объекту: характеристики товаров в разных категориях, настройки. Плата — слабая проверка типов и неудобные запросы. Как только по атрибуту начинают отчитываться регулярно, его выносят в обычную колонку.

дальше

Теорию прочитали. Навык ставится повторением

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