Запрос, чтобы получить все версии графа объекта

StackOverflow https://stackoverflow.com/questions/221002

  •  03-07-2019
  •  | 
  •  

Вопрос

Я внедряю журнал аудита в базе данных, поэтому у всех есть столбцы CreatedAt и RemovedAt. Теперь я хочу иметь возможность перечислить все ревизии графа объектов, но лучший способ, которым я могу придумать для этого, состоит в том, чтобы использовать объединения. Мне нужно получить каждый уникальный идентификатор CreatedAt и RemovedAt.

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

SELECT c.CreatedAt AS RevisionId from Countries as c where localId=@Country
UNION
SELECT p.CreatedAt AS RevisionId from Provinces as p 
INNER JOIN Countries as c ON p.CountryId=c.LocalId AND c.LocalId = @Country
UNION
SELECT c.RemovedAt AS RevisionId from Countries as c where localId=@Country
UNION
SELECT p.RemovedAt AS RevisionId from Provinces as p 
INNER JOIN Countries as c ON p.CountryId=c.LocalId AND c.LocalId = @Country

Для более сложных запросов это может быть довольно сложно и, возможно, работать очень плохо, поэтому я хотел посмотреть, сможет ли кто-нибудь придумать лучший подход. Это на сервере MSSQL.

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

Это было полезно?

Решение

Скорее всего, вы уже реализовали свое решение, но решили несколько вопросов; Я бы предложил рассмотреть решение Aleris или его производную.

  • В ваших таблицах " удалено в " поле - хорошо, если это поле было активным (заполненным), технически данные не должны быть там - или, возможно, ваша реализация помечает их как удаленные, что приведет к прерыванию ведения журнала после удаления .
  • Что происходит, когда у вас есть несколько обновлений в течение отчетного периода - предыдущие записи журнала будут перезаписаны.
  • Наличие отдельного журнала позволяет архивировать информацию журнала и позволяет установить другой цикл анализа журнала из циклов обновления / редактирования.
  • Добавьте ссылку " ссылку " поля, необходимые для возврата к исходным данным ИЛИ , делают описания достаточно подробными.

    Поля, содержащиеся в вашем журнале, оставлены на ваше усмотрение, но решение Aleris является прямым. Я могу создать таблицу действий и изменить тип поля с varchar на int, как ссылку на таблицу действий, что вынуждает разработчиков выполнять некоторые стандартизированные действия.

    Надеюсь, это поможет.

        
  • Другие советы

    Альтернативой может быть создание журнала аудита, который может выглядеть следующим образом:

    AuditLog table
        EntityName varchar(2000),
        Action varchar(255),
        EntityId int,
        OccuranceDate datetime
    

    где EntityName - это имя таблицы (например, Contries, Provinces), Action - это действие аудита (например, Created, Removed и т. д.), а EntityId - первичный ключ измененной строки в исходной таблице.

    Таблица должна быть синхронизирована при каждом действии над таблицами. Есть несколько способов сделать это:

    1) Создайте триггеры для каждой таблицы, которые добавят строки в AuditTable
    2) Из вашего приложения добавляйте строки в AuditTable каждый раз, когда вносятся изменения в reversetables

    С помощью этого решения очень просто получить список журналов аудита.

    Если вам нужно получить столбцы из исходной таблицы, можно также использовать такие объединения:

    select *
    from 
        Contries C 
        join AuditLog L on C.Id = L.EntityId and EntityName = 'Contries'
    

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

    SELECT
         COALESCE(C.CreatedAt, P.CreatedAt)
    FROM
         dbo.Countries C
    FULL OUTER JOIN dbo.Provinces P ON
         1 = 0
    WHERE
         C.LocalID = @Country OR
         P.LocalID = @Country
    
    Лицензировано под: CC-BY-SA с атрибуция
    Не связан с StackOverflow
    scroll top