Pull to refresh

Comments 21

Не до конца понял решаемую бизнес задачу, для какого проекта нужны таблицы историчности? Почему таблицы истории создаются руками через скрипт, а не через код системы или ещё как-то?

В ряде корпоративных проектов (например, в банковских), принято хранить историю изменений каждой записи. Это нужно для аудита, отката ошибок и в целом для отслеживания состояния объекта во времени.
Обычно такие history-таблицы создают вручную, что довольно рутинно: прописать колонки, проверять корректность и избегать опечаток.
Собственно, плагин и был сделан, чтобы этот процесс автоматизировать: выбираешь таблицу, нужные колонки и события - а скрипт генерится автоматически.

У потгреса, например, есть такая штука:

create table new (
    like old
    including defaults
    including constraints
    including indexes
);

Даже можно тут же колонки дополнительные добавить.

Да, like быстро копирует структуру, но моя цель - автоматизировать вес цикл (хист таблица + триггеры). А так вы получаете лишь копию но без триггеров

для аудита, отката ошибок и в целом для отслеживания состояния объекта во времени.

Не проще ли написать генерирующую скрипт процедурку в БД, если уж логика БД на этом построена?

Если вам даже нужен простой аудит через триггеры, то не проще все изменения в одну табличку в json пихать? Открыл и сразу видно, какие записи и в каких полях менялись, не надо сравнивать две таблицы и никакого зоопарка лишних таблиц в БД.

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

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

С чего оно удобнее? Если вываливать пользователю портянку, чтобы сам глазами искал, то действительно проще, а для анализа намного сложнее. Чтобы понять, когда поменялось какое-то значение в поле, нужно текущую запись сравнить с какой из всех записей history? Писать запрос для нахождения первой отличающейся записи? А если нужен не один случай, а все и с какой-то извращенной логикой? Запросец уже не кажется таким уж простым? Оказывается, что не понятно как выстроить индексы для всех ваших history таблиц?

ускорить рутинный процесс.

Обычно плагин расширяет функции IDE, но БД ведь к ней не привязана. А чего делать, если ваш плагин не встанет на новую версию DBeaver или потребуется какие-то доработки сделать? Искать специалиста по разработке плагинов? Зачем весь этот онанизм, если можно просто хранить скрипт или процедурку в БД, которая делает то же самое.

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

Когда хранишь как скрипт - легко ошибиться. Процедурка привязана к конкретной СУБД (скрипт в дальнейшем будет расширять поддержку.

*(плагин в дальнейшем будет расширять поддержку СУБД)

Пример. Фирма переименовалась в январе 2025-го. В феврале 2025-го мы начинаем составлять некий статистический отчёт за 2024 год. В этом отчёте наименование фирмы должно быть не тем, какое оно стало на момент начала (или окончания) работы над отчётом, а тем, какое оно было в отчётном периоде, т.е. до переименования. Его мы возьмём из исторической таблицы.

Вы бы хоть SQL показали...
Как решали проблему с bloat'ом? History-таблицы будут append-only?
Как решали проблему с wraparound и вакуумом для его предотвращения? Замораживаете строки сразу при вставке?
Есть ли поддержка для секционированных таблиц?

Спасибо за вопросы! Сейчас плагин в самом "сыром" виде. Поэтому он генерит append-only историю, это дает полный аудит, но, конечно, вызывает рост таблицы (благодарен за напоминание про bloat).
В будущем планирую подумать над оптимизациями (замораживание, секционирование, режим хранения)

Добавил спойлер с sql скриптом (Под скриншотом со скриптом)

History-таблицы априори должны быть append-only. Это строки в основной таблице могут быть вставлены(INSERT), обновлены(UPDATE), удалены(DELETE). В history таблицах разрешается только вставка (INSERT) с указанием операции. Но при этом есть особенности - как хранить изменения: полностью копировать измененную строку основной таблицы с указанием типа операции(I,U.D) и атрибутов того, кто это сделал и времени изменения. При этом history-таблица (или таблица аудита) будет в разы больше основной таблицы. Либо же есть вариант, когда в history-таблицы данные заносятся по технологии "разряженных массивов", то есть фиксируются только значения измененных столбцов (при INSERT - изначально вставляются все столбцы и их значения, а при UPDATE - только измененные столбцы, при DELETE - только факт операции). При этом уменьшается размер history-аудит таблицы, но увеличивается время анализа измененных данных, логика и тип хранения этих данных с указанием измененного столбца, процедура восстановления полного состояния полей строки таблицы на определенную дату. Также для history-аудит таблиц делают архивные(archive) таблицы, куда периодически переносят древние строки аудит-таблиц и где-нить хранят отдельно от базы.

Спасибо за комментарий, согласен.

Не всегда append-only. В таблицах аудита да. А если таблица хранит историю актуализации атрибутов, то иногда возникает необходимость исправить задним числом ошибку ввода или удалить запись, вставленную по ошибке.

Не придумывай. Ты попутал мягкое с теплым. То, для чего автор топика делает свое расширение - это Аудит или Лог-таблицы (в которых кроме ID объекта должно быть ВРЕМЯ_ОПЕРАЦИИ, ТИП_ОПЕРАЦИИ, ПОЛЬЗОВАТЕЛЬ_СОВЕРШИВШИЙ_ОПЕРАЦИЮ). То о чем говоришь ты - это Темпоральные таблицы, в которых кроме ID и атрибутов объекта должны быть 2 обязательных столбца ВРЕМЯ_С и ВРЕМЯ_ПО. И эти 3 столбца ID, ВРЕМЯ_С, ВРЕМЯ_ПО образуют уникальный ключ и позволяют отслеживать временное изменение данных, в том числе и обновлять данные "задним числом". И на эту таблицу для отслеживания всех действий пользователя тоже можно сделать свою аудит-таблицу, которую автор и обозначает как _hist

И в темпоральных таблицах более сложная логика поддержания целостности атрибутов время_с, время_по.

Чем вызван выбор "кастомной" лицензии в репозитории, да ещё с такими жестокими ограничениями по изменениям, которые по сути запрещают форк и изменение кода "без разрешения/уведомления" автора?

Я выбрал кастомную лицензию, чтобы сохранить проект в том виде, в котором я его задумывал. Если у вас есть идеи или предложения по улучшению, их всегда можно оставить в репо в виде issue/feature request, с радостью ознакомлюсь :)

Реквесты и без лицензии могут быть и авторство плагина навряд ли кем-нибудь оспаривалось бы.

Я эту лицензию прочитал так, что даже в форке не могу вносить несогласованные изменения, а значит и пул/мердж реквест невозможен.

Чем то навеяло старые ЧСВ замашки в виде комментов авторства в файле, и субъективно вызывает нежелание влезать в кодбазу

Запрещается:

-изменять, модифицировать и распространять изменённые версии плагина без предварительного согласия автора.

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

Условия:

-любые улучшения или предложения должны направляться автору для согласования;

Т.е. пул/мердж реквест рассматривается как "согласование".

Sign up to leave a comment.

Articles