2013-03-10 57 views
0

我注意到现在看起来非常明显的模式。 需要得到您对此的意见。关系模型中OneToMany关系性能的一般设计原则

假设在关系模型中具有表1到表2之间的一对多关系。 例如,表1可以是用户表,表2可以是登录所有用户登录的登录表。一个用户可以多次登录。 给定一个用户,我们可以找到该用户的所有登录。

想到的第一个想法是仅将登录名存储在登录表中。这是设计之一。

但是,如果由于某种usecases我们感兴趣的用户的特定登录(说上次登录的)是“通常是个好主意”缓存在用户表本身的最后登录时间。 是吗?

设计2显然是多余的,因为我们总能找到通过执行加入,然后丢弃所有,但先前登录上次登录的时间。

对于一个用户应该没问题。但是如果你想为所有的用户找到一个SQL查询的最后登录时间,那么设计1将涉及一个连接和一个子查询来过滤不需要的结果。

但考虑到我们的用例,是去年的登录时间存储在用户表本身,这将拯救我们从加入一个好主意。是对的吗?

这是您在设计模式时看到的通用模式吗?

+0

我认为当前会话ID通常用于跟踪这一点。 – Aiias 2013-03-10 05:21:21

+0

我刚刚用这个作为例子,我指的是通用许多设计原则。另外,我想制作这个问题社区维基。 – 2013-03-10 05:24:20

+0

您正在评估设计阶段的性能方面。请记住,[过早优化是所有邪恶的根源](http://en.wikipedia.org/wiki/Premature_optimization#When_to_optimize) – 2013-03-10 05:43:29

回答

0

您正在混淆TABLE和RELATION这两个常见错误的概念。您的概念模型中有两个关系(用户&登录),但实际上这将涉及物理模型中的两个以上表,因为非聚集索引不过是附加表来加速多个关系的加入。

一旦登录中存在INDEX(用户标识,登录时间)以支持与用户的FK关系,则非聚集索引将覆盖查找用户最近登录的查询。只有当这个默认模型已经确定了一个已知的,可测量的,严重的性能问题时,才会看到非规范化,因为这个(像所有的非规范化)在非规格化表上引入了对每一个其他读和写操作的性能命中。

+0

嗯...有趣...可能是我缺少重点......但是当我查询所有用户的最近登录时,我将生成一个如下所示的查询: 'SELECT user.id,login.login_time FROM USER用户,登录登录WHERE user.id = login.user_id AND login.login_time> =(从LOGIN where user_id = user.id)选择登录时间''。那是对的吗?非聚集索引如何加快此查询速度? 存在此索引时,以下查询会更快吗? 'SELECT U.id,L1.login_time FROM USER U1,LOGIN L1,LOGIN L2 WHERE U1.id = L1.user_id AND U1.id = L2.user_id AND L1.login_time> = L2.login_time'。 – 2013-03-10 19:45:11

+0

我猜这些查询存在一些问题。需要弄清楚如何解决它们。假设这种连接对'非聚集索引'是有效的,那么我将需要确保hibernate在使用hbm2ddl时为我生成这些索引,并确保我的JPQL转换为更高效的SQL查询。在某些情况下,我看到只是创建一个冗余列使得最终的数据分析速度更快。虽然我没有创建相关的非聚集索引。 – 2013-03-10 20:12:07

+0

查询“用户u上的UserName,u.UserID,LastLoginTime = Max(LoginTIme)”将u.UserId = l.UserID组中的Logins l留在了u.UserID组中,UserName“将被非聚集索引覆盖。 – 2013-03-11 01:54:31