Sql 关系模型中一对多关系性能的一般设计原则

Sql 关系模型中一对多关系性能的一般设计原则,sql,relational,schema-design,Sql,Relational,Schema Design,我注意到一种模式,现在似乎很明显。 我需要听听你的意见 假设在关系模型中,表1和表2之间存在一对多关系。 例如,表1可以是用户表,表2可以是记录所有用户登录的登录表。一个用户可以多次登录。 给定一个用户,我们可以找到该用户的所有登录 首先想到的是只在登录表中存储登录名。这是设计一 但是,如果对于某些用例,我们对用户的某个特定登录感兴趣,比如最后一次登录,那么通常最好将最后一次登录时间缓存在用户表本身中。 是这样吗 设计2显然是多余的,因为我们总是可以通过执行连接,然后丢弃除以前登录以外的所有登录

我注意到一种模式,现在似乎很明显。 我需要听听你的意见

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

首先想到的是只在登录表中存储登录名。这是设计一

但是,如果对于某些用例,我们对用户的某个特定登录感兴趣,比如最后一次登录,那么通常最好将最后一次登录时间缓存在用户表本身中。 是这样吗

设计2显然是多余的,因为我们总是可以通过执行连接,然后丢弃除以前登录以外的所有登录来找到最后一次登录时间

对于一个用户来说,两者都可以。但是,如果您想为所有用户查找最后一次登录时间,那么设计1将涉及一个联接和一个子查询,以过滤掉不需要的结果

但是考虑到我们的用例,最好将上次登录时间存储在用户表中,这样可以避免加入。是这样吗


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

您混淆了表和关系的概念,这是一个常见的错误。概念模型用户和登录名中有两个关系,但实际上,这将涉及物理模型中的两个以上的表,因为非聚集索引只不过是加速多个关系联接的附加表


一旦索引UserID、LoginTime在登录上存在以支持与用户的FK关系,则非聚集索引将涵盖查找用户最近登录的查询。只有当已知的、可测量的、严重的性能问题通过该默认模型被识别时,我们才会去规范化,与所有非规范化操作一样,非规范化表上的每一个其他读写操作都会带来性能影响。

我认为当前会话id通常用于跟踪这一点。我只是以此为例,我指的是通用的一对多设计原则。另外,我想让这个问题成为一个社区wiki。您正在设计阶段评估性能方面。请记住,你不能在设计的这么早就回答这个问题,听A.Rodas的。完成您的设计,然后使用相关工具进行性能评估。如果你发现了一个问题,然后重新评估,如果你需要的话做出改变。。。有趣的也许我没有抓住重点。。。但当我查询所有用户最近的登录时,我将生成一个如下查询:选择user.id、login.login\u time FROM user user、login login WHERE user.id=login.user\u id和login.login\u time>=选择login\u time FROM login WHERE user\u id=user.id。对吗?非聚集索引将如何加速此查询?有了这个索引,下面的查询会更快吗?从用户U1中选择U.id、L1.login\U time、login L1、login L2,其中U1.id=L1.USER\U id和U1.id=L2.USER\U id和L1.login\U time>=L2.login\U time。我猜这些查询存在一些问题。需要弄清楚如何修复它们。假设这个连接对于“非聚集索引”是有效的,我需要确保hibernate在使用hbm2ddl时为我生成这些索引,并且确保我的JPQL转换为更有效的SQL查询。在某些情况下,我已经看到,仅仅创建一个冗余列就可以使最终的数据分析更快。虽然我没有创建相关的非聚集索引。查询从用户中选择UserName、u.UserID、LastLoginTime=MaxLoginTIme u left join Logins l on u.UserID=l.UserID group by u.UserID,UserName将由非聚集索引覆盖。谢谢。首先,我的特定用例有不同的表名,但这不重要。等效地,我在登录表中有不同的设备类型桌面、移动设备和其他设备,我想获得每个设备类型的所有用户的上次登录时间,我只是按u.UserID、u.DeviceType分组。我创建了一个BTREE索引UserID、LoginTime、DeviceType。出于某种原因,使用哈希也会创建一个BTREE索引。它给了我正确的结果。但似乎没有任何绩效改进。MySQL命令行报告约0.31秒,有或没有该索引。查询返回43000行。