Database 数据库设计:这是位置日志记录的良好实践吗?
在下面的图表中,你可以看到我试图做的一个简化版本。我必须跟踪某些项目的位置,但我还必须高效地检索任何给定项目的最新位置。最简单的方法是查询ItemLocationLog并搜索该项的最新日期,但由于该表一定非常大,我想知道这是否有效(我想索引dateTime字段会有所帮助,但我没有经验确定到底有多少) 我考虑的另一种方法是为项上的日志表添加一个外键(如图中带有字段“lastLocation”的图所示),它将始终指向最新的日志条目,从而省去我的搜索。另一种选择是向项上的位置添加外键,并在每次为任何给定项添加日志条目时更新它 我确信这是一个简单解决方案的常见问题,但由于我没有这方面的经验,我对自己的方法持怀疑态度。这类场景的最佳实践是什么?为了避免代价高昂的查询,可以添加对Item表的引用吗?或者该查询足够简单,我只需要从日志表本身获取该信息Database 数据库设计:这是位置日志记录的良好实践吗?,database,database-design,entity-relationship,Database,Database Design,Entity Relationship,在下面的图表中,你可以看到我试图做的一个简化版本。我必须跟踪某些项目的位置,但我还必须高效地检索任何给定项目的最新位置。最简单的方法是查询ItemLocationLog并搜索该项的最新日期,但由于该表一定非常大,我想知道这是否有效(我想索引dateTime字段会有所帮助,但我没有经验确定到底有多少) 我考虑的另一种方法是为项上的日志表添加一个外键(如图中带有字段“lastLocation”的图所示),它将始终指向最新的日志条目,从而省去我的搜索。另一种选择是向项上的位置添加外键,并在每次为任何给
不要针对您不知道的问题进行预优化。 从涵盖
idItem
的ItemLocationLog
表上的索引开始。然后通过idItemLocationLog DESC从ItemLocationLog order中选择前1个idItemLocationLog——假设您的PK是一个自动递增列如果这不够快,请尝试在idItem
上加上dateTime
索引。如果这仍然不够快,那么您可以开始考虑剧烈的非规范化,比如将最后一个已知的位置引用保留在项上
有些人真的很惊讶RDBMS在检索数据方面有多么出色。你不应该这样 不要针对您不知道的问题进行预优化。
从涵盖idItem
的ItemLocationLog
表上的索引开始。然后通过idItemLocationLog DESC从ItemLocationLog order中选择前1个idItemLocationLog
——假设您的PK是一个自动递增列如果这不够快,请尝试在idItem
上加上dateTime
索引。如果这仍然不够快,那么您可以开始考虑剧烈的非规范化,比如将最后一个已知的位置引用保留在项上
有些人真的很惊讶RDBMS在检索数据方面有多么出色。你不应该这样 原则上,只有在测量了性能、确定了实际瓶颈并得出非规范化确实有帮助(足以抵消数据损坏风险)的结论后,才在模型中包含冗余
奇怪的是,在你的情况下,它不会。B-树索引工作方式的一个特点是,搜索MAX基本上与搜索精确值一样快。如果数据库管理系统上的INT小于DATETIME,那么更好的缓存可能会给您带来一点帮助,但不会太多
如果操作正确,索引功能将非常强大。而ItemLocationLog{idItem,dateTime}
上的索引应该有助于闪电般的从ItemLocationLog中选择MAX(dateTime),其中idItem=?
请看一看关于该主题的精彩介绍。原则上,只有在您测量了性能、确定了实际瓶颈并得出非规范化确实会有所帮助(足以抵消数据损坏的风险)的情况下,才在模型中包含冗余
奇怪的是,在你的情况下,它不会。B-树索引工作方式的一个特点是,搜索MAX基本上与搜索精确值一样快。如果数据库管理系统上的INT小于DATETIME,那么更好的缓存可能会给您带来一点帮助,但不会太多
如果操作正确,索引功能将非常强大。而ItemLocationLog{idItem,dateTime}
上的索引应该有助于闪电般的从ItemLocationLog中选择MAX(dateTime),其中idItem=?
请看一看关于该主题的精彩介绍。首先尝试一下(示例适用于PostgeSQL)
这可能看起来很吓人,但速度相当快,ItemID
是主键的一部分
如果您需要在任何时间点列出所有项目
-- Location of all items for point in time ('2012-05-01 11:00:00')
select
a.ItemID
, b.LocationID
, ValidFrom
from Item as a
join ItemLocation as b on b.ItemID = a.ItemID
and b.ValidFrom = (select max(x.ValidFrom)
from ItemLocation as x
where x.ItemID = a.ItemID
and x.ValidFrom <= '2012-05-01 11:00:00')
join Location as c on c.LocationID = b.LocationID
;
——时间点所有项目的位置('2012-05-01 11:00:00')
选择
a、 项目ID
,b.LocationID
,有效期自
从项作为
在b.ItemID=a.ItemID上将ItemLocation作为b连接
和b.ValidFrom=(选择max(x.ValidFrom)
从ItemLocation作为x
其中x.ItemID=a.ItemID
和x.ValidFrom先试试这个(例如PostgeSQL)
这可能看起来很吓人,但速度相当快,ItemID
是主键的一部分
如果您需要在任何时间点列出所有项目
-- Location of all items for point in time ('2012-05-01 11:00:00')
select
a.ItemID
, b.LocationID
, ValidFrom
from Item as a
join ItemLocation as b on b.ItemID = a.ItemID
and b.ValidFrom = (select max(x.ValidFrom)
from ItemLocation as x
where x.ItemID = a.ItemID
and x.ValidFrom <= '2012-05-01 11:00:00')
join Location as c on c.LocationID = b.LocationID
;
——时间点所有项目的位置('2012-05-01 11:00:00')
选择
a、 项目ID
,b.LocationID
,有效期自
从项作为
在b.ItemID=a.ItemID上将ItemLocation作为b连接
和b.ValidFrom=(选择max(x.ValidFrom)
从ItemLocation作为x
其中x.ItemID=a.ItemID
和x.ValidFrom我不确定你到底想做什么,你的图表被我的网络警察阻止了。我通常有两张表