原则2-从历史表中检索最新记录



使用一个status_history表,它将保存entries中特定记录的状态修改日期和时间,我试图找到最简单的方法来获取当前状态,也就是最近日期的状态。

例如,考虑以下内容:status_history

+----+----------+------------+-----------+
| id | entry_id |   status   | timestamp |
+----+----------+------------+-----------+
|  1 |        1 | Processing | 15:05:09  |
|  2 |        1 | In Review  | 15:05:18  |
|  3 |        1 | Complete   | 15:05:26  |
+----+----------+------------+-----------+

当然,我们的条目:entries

+----+--------+
| id | title  |
+----+--------+
|  1 | Foobar |
+----+--------+

如何使用DQL检索特定条目的最新状态(技术上为当前状态),而不必在Entry实体中维护latest_status_id列?

考虑调用$entry->getCurrentStatus()将返回"Complete"。然而,如果该条目有大量的状态记录,那么第二个加载所有状态的查询可能会导致性能下降。

注意:在本文中,他们用额外的列方法描述了它,使用了用于并发的锁定机制。我希望避免这种方法,除非这是正确的方法,因为我们试图不对每个表(status_history.entry_identry.latest_history_id)都有双重关系。

对于单个条目,查询可能如下所示:

$query = $em->createQuery('SELECT e, s 
FROM entries e 
JOIN e.status_history s 
WHERE e.entry_id = :entry_id
ORDER BY s.timestamp DESC');
$query->setParameter('entry_id', $entry_id);
$entries = $query->getSingleResult();

getCurrentStatus()方法中,您可以返回指定的唯一status_history对象。

对于所有条目,它都比较复杂,并且必须使用具有GROUP BYMAX()的子查询。它在本机SQL中是可行的,但我还没有弄清楚如何使用DQL。一旦我有了解决方案,我就会更新我的答案。

我认为在状态历史存储库中使用QueryBuilder就足够了:

$entry_id = 1;
$queryBuilder = $this->createQueryBuilder()
->select('s')
->where('s.entry = :entry_id')
->orderBy('o.id', 'DESC')
->setParameter('entry_id', $entry_id)
$query = $queryBuilder->getQuery();
return $query->getSingleResult();

您可以使用id,假设id是"自动递增",并且timestamp是创建记录的自动时间戳。在这种情况下,最高id总是最新的插入,所以您甚至不需要使用timestamp列来查找该记录。

否则,您必须在timestamp列中添加一个索引,然后按该列排序:

$entry_id = 1;
$queryBuilder = $this->createQueryBuilder()
->select('s')
->where('s.entry = :entry_id')
->orderBy('o.timestamp', 'DESC')
->setParameter('entry_id', $entry_id)
$query = $queryBuilder->getQuery();
return $query->getSingleResult();

您需要在timestamp列中添加一个索引以提高的性能

相关内容

  • 没有找到相关文章

最新更新