学说2 - 从历史表中检索最新记录

时间:2017-01-12 20:52:51

标签: php mysql doctrine-orm doctrine

使用status_history表来保存entries中特定记录的状态被修改的日期和时间,我正在尝试找到获取当前状态的最简单方法,AKA ,最新日期的状态。

例如,请考虑以下事项: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 检索特定条目的最新状态(技术上是当前状态),而无需维护latest_status_id在我的Entry实体中?

考虑调用$entry->getCurrentStatus()将返回"Complete"。但是,如果我们有该条目的大量状态记录,则加载所有状态的第二个查询可能会变为性能下降。

注意:this article中,他们使用额外的列方法来描述它,使用锁定机制进行并发。我想避免这种方法,除非这是正确的方法,因为我们试图不为每个表(status_history.entry_identry.latest_history_id)建立双重关系。

2 个答案:

答案 0 :(得分:1)

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

$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。一旦我找到解决方案,我会立即更新我的答案。

答案 1 :(得分:0)

我认为在状态历史存储库中使用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列中添加索引以提高性能