Коррекционный Update (Учётный SCD2)

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

Амбула

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

Явление бухгалтера первое

К вам приходит бухгалтер и говорит, что сотрудница Иванова поменяла фамилию на Петрова. Вы заходите в справочник и меняете фамилию сотрудницы.

Явление бухгалтера второе

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

Осознание

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

Явление бухгалтера третье

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

Явление бухгалтера четвертое

Бухгалтер звонит и жалуется, что в отчетах за предыдущие кварталы отчество сотрудницы выводится неправильно.

Просветление

Тут приходит понимание, что в справочнике нужно сделать кнопку "Сохранить" для update`а немного сложнее. При нажатии кнопки необходимо спросить у пользователя, что, собственно, он хочет сделать, исправить ошибку или актуализировать значение?

  • Исправить ошибку
    » Коррекционное изменение.
    » В этом случае версия записи порождаться не будет, но исправление должно быть сделано в актуальной и исторических версиях.
  • Актуализировать значение
    » Эволюционное изменение.
    » В этом случае нужно потребовать дату ввода в учёт нового значения. Будет порождена новая версия записи.

Для удаления ситуация аналогичная: удалить ошибочно созданную запись или финализировать учёт. При создании может потребоваться указать дату ввода в учёт задним числом (иногда сущность может вернуться в учёт).

Подсказки

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

Артефактным сущностям учётный SCD2 не требуется, поскольку у них не может быть разных учётных состояний, но технический аудит может иметь место (в т.ч. CDC). Учётный SCD2 рекомендуется разделить на уровне партиций, а технический аудит вынести в отдельную таблицу (SCD4).

Техническая реализация

  • idидентификатор записи.
  • entity_idидентификатор сущности.
    Обязательное. Для актуальной версии id = actual_id.
  • actual_fromдата начала учётного состояния.
    Обязательное. Default = 2001.01.01.
  • actual_toдата конца учётного состояния (партиционный признак).
    Обязательное. Default = 3001.01.01.

Кортежи entity_id + actual_from должны быть уникальными.

Если в отчетах нужно вывести актуальные значения, то JOIN делается к id (к актуальной партиции), если нужно вывести исторические значения, то JOIN делается к entity_id с добавлением условия на срок актуальности. Примерно так …

fact JOIN staff ON fact.staff_id = staff.entity_id and fact.datetime >= staff.actual_from and fact.datetime < staff.actual_to
Начать дискуссию