Ответ
Отслеживание изменений в БД — критически важная задача для аудита, синхронизации или реализации событийной архитектуры. Выбор подхода зависит от СУБД, фреймворка и требований.
1. Триггеры в БД
Создание триггеров AFTER INSERT/UPDATE/DELETE для записи изменений в таблицу-лог. Это надежный, но создающий нагрузку на БД метод.
CREATE TRIGGER TrackUserChanges
ON dbo.Users
AFTER INSERT, UPDATE, DELETE
AS
BEGIN
INSERT INTO ChangeLog (TableName, ChangeType, ChangedData, ChangedAt)
SELECT 'Users',
CASE WHEN EXISTS(SELECT * FROM inserted) AND EXISTS(SELECT * FROM deleted) THEN 'UPDATE'
WHEN EXISTS(SELECT * FROM inserted) THEN 'INSERT'
ELSE 'DELETE' END,
(SELECT * FROM inserted FOR JSON PATH),
GETDATE();
END;
2. Change Data Capture (CDC) или Temporal Tables
CDC (в SQL Server, PostgreSQL) отслеживает изменения на уровне транзакционного лога с минимальным влиянием на производительность.
-- SQL Server CDC
EXEC sys.sp_cdc_enable_db;
EXEC sys.sp_cdc_enable_table
@source_schema = 'dbo',
@source_name = 'Users',
@role_name = NULL,
@capture_instance = 'dbo_Users';
-- Запрос изменений
SELECT * FROM cdc.dbo_Users_CT;
Temporal Tables автоматически сохраняют историю версий строк.
3. Механизмы ORM (например, Entity Framework Core)
Change Tracker отслеживает изменения в контексте перед сохранением.
// Отслеживание измененных сущностей
var changedEntries = context.ChangeTracker.Entries()
.Where(e => e.State == EntityState.Modified)
.ToList();
foreach (var entry in changedEntries)
{
var originalValues = entry.OriginalValues;
var currentValues = entry.CurrentValues;
// Логирование изменений
}
Перехватчики (Interceptors) позволяют глобально обрабатывать команды перед выполнением.
4. Паттерн «Наблюдатель» (Observer) или Domain Events
В рамках приложения можно реализовать систему событий, которые генерируются при изменении сущностей.
public class EntityChangedEvent : INotification
{
public string EntityType { get; set; }
public string ChangeType { get; set; }
public object EntityId { get; set; }
}
// В обработчике репозитория или сервиса
await _mediator.Publish(new EntityChangedEvent
{
EntityType = nameof(User),
ChangeType = "Updated",
EntityId = user.Id
});
5. Внешние инструменты (Debezium)
Для сложных микросервисных архитектур используют Debezium — платформу для потоковой передачи изменений из БД (CDC) в Kafka, что позволяет другим сервисам реагировать на изменения.
Рекомендация: Для простых задач подойдут триггеры или Temporal Tables. Для .NET-приложений средней сложности — EF Core Change Tracker + Domain Events. Для распределенных систем — CDC через Debezium.