Как лучше хранить дополнительные параметры сущности в бд?

Рейтинг: 0Ответов: 1Опубликовано: 17.07.2025

В базе данных есть 2 таблицы: Акты и История

Схема

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

SELECT
    a.Number  
  , created.AuthorId
  , status.StatusId
  , status.Timestamp
  , verified.Timestamp AS Verified
  , implemented.Timestamp AS Implemented  
FROM Acts a
OUTER APPLY(SELECT TOP 1 * FROM ActHistories WHERE ActId = a.Id ORDER BY Id) created
OUTER APPLY(SELECT TOP 1 * FROM ActHistories WHERE ActId = a.Id ORDER BY Id Desc) status
OUTER APPLY(SELECT TOP 1 Timestamp FROM ActHistories WHERE ActId = a.Id AND StatusId = 947 ORDER BY Id Desc) verified
OUTER APPLY(SELECT TOP 1 Timestamp FROM ActHistories WHERE ActId = a.Id AND StatusId = 946 ORDER BY Id Desc) implemented

Подумываю насчет создания дополнительной таблицы в которой буду фиксировать данные для исключения запросов OUTER APPLY, схема бд изменится следующим образом

введите сюда описание изображения

соответственно запрос изменится следующим образом

SELECT
    a.Id
  , aa.OwnerId
  , aa.StatusId
  , aa.Timestamp
  , aa.Timestamp AS Verified
  , aa.Timestamp AS Implemented
FROM Acts a
JOIN ActAttributes aa ON a.Id = aa.ActId

Подскажите можно ли так сделать или может лучше поля из ActAttributes сделать в таблице Acts?

Ответы

▲ 0

Я бы структуру не менял, таблица с историей статусов вполне нормальная. Но можно попробовать оконные функции:

SELECT
    a.Number  
  , MAX(h.AuthorId) OVER (PARTITION BY h.ActId ORDER BY h.Id) AuthorId
  , MAX(h.StatusId) OVER (PARTITION BY h.ActId ORDER BY h.Id DESC) StatusId
  , MAX(h.Timestamp) OVER (PARTITION BY h.ActId ORDER BY h.Id DESC) Timestamp
  , MAX(CASE WHEN h.StatusId = 947 THEN h.Timestamp END) OVER (PARTITION BY h.ActId ORDER BY h.Id DESC) Verified
  , MAX(CASE WHEN h.StatusId = 946 THEN h.Timestamp END) OVER (PARTITION BY h.ActId ORDER BY h.Id DESC) Implemented  

FROM Acts a
LEFT JOIN ActHistories h ON h.ActId = a.Id
GROUP BY a.Id

Может ошибся с сортировкой окон, тогда поменять MAX/MIN (или ASC/DESC)