我有一个2表:一个存储对象(对象),其他存储对象状态(对象状态更新)的状态更新(例如:NOT_DONE,BEING_MANUFACTURED,DONE):database diagram
每次对象状态改变时,都会在ObjectStateUpdate表中添加一行,其中包含新的状态和状态改变的日期。
在我的应用程序中,有一个用例,我想检索处于特定状态的所有对象(假设所有正在制造的对象)。
这是通过一个复杂的SQL请求完成的,该请求根据更新的日期获取每个对象的最新已知更新,如果同时发生了两个更新,则我使用更新ID来查找最后一个(每个对象具有至少一个状态更新):
SELECT *
FROM ObjectStateUpdate
WHERE id =
(
SELECT MAX(id)
FROM ObjectStateUpdate
INNER JOIN (
SELECT objectId, MAX(date) AS max_date
FROM trade_manager_app_orderupdate GROUP BY objectId
) as Latest
ON ObjectStateUpdate.objectId = Latest.objectId
AND ObjectStateUpdate.date = Latest.max_date
GROUP BY ObjectStateUpdate.objectId
)
[我曾考虑在对象表中添加一个外键列"lastUpdateId"
来存储对象的最新更新的ID(每次我有一个新更新时,我都会将其ID存储到该对象)。
这可以通过用效率更高的请求代替它来避免执行大型SQL请求,但是,如果出于某种原因,“ lastUpdateId”不能与数据库更新保持一致,恐怕它将在数据库模型中添加不一致的地方。 ObjectStateUpdate表的数据。
所以我应该将此列添加到对象表中以提高性能,还是应该像这样保持它以避免不一致?
row_number()
大大简化现有查询(如果您的SQLite版本支持它们);select *
from (
select u.*, row_number() over(partition by objectId order by date desc, id desc) rn
from ObjectStateUpdate u
) t
where rn = 1 and state = 'BEING_MANUFACTURED'
您可以通过相关的子查询获得相同的结果:您可以通过相关的子查询获得相同的结果:
select u.* from ObjectStateUpdate u where id = ( select u1.id from ObjectStateUpdate u1 where u1.objectId = u.objectId order by date desc, id desc limit 1 ) and state = 'BEING_MANUFACTURED'
为了提高性能,您需要在(objectId, date, id)
上建立索引。