首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >可扩展的跟踪用户活动的方法

可扩展的跟踪用户活动的方法
EN

Stack Overflow用户
提问于 2013-01-15 22:15:17
回答 2查看 234关注 0票数 3

我正在开发一个人力资源系统,我需要对用户配置文件的所有视图进行跟踪记录,因为每个招聘人员对候选人配置文件的看法都是有限的。我主要关注的是我的方法的可伸缩性,它是这样的:我目前创建了一个包含2列的表,被查看的候选人的id和查看该候选人的招聘人员的id,每个视图只计算一次,所以如果您再次看到相同的候选人,将不会插入任何记录。

根据数据库中招聘人员和应聘者的数量,我可以有把握地说,我的表会增长得很快,为了使事情变得更糟,我必须在每个请求中查询我的表,因为我必须在UI中显示招聘人员查看过的候选人数量。考虑可伸缩性的最佳方法是哪一种?

我将进一步解释这个案例:我们有公司,每家公司都有很多招聘人员。

ViewsAssigner_Identifier表

  • Id: int PK
  • Company_Id: int非集群
  • Views_Assigned: int -非集群
  • 日期:非群集日期

CandidateViewCounts表

  • Id: int PK
  • Recruiter_id: int FK非集群?
  • Candidate_id: int FK非集群?
  • ViewsAssigner_Identifier_Id: int FK非集群?
  • DateViewed:非群集日期

I将查询ViewsAssigner_Identifier_id对所有Candidate_id的选择

我们希望按公司搜索,而不是按招聘人员搜索,因为同一公司的所有招聘人员都对公司使用了相同的Views_Assigned。换句话说,查看候选人的第一个恢复器将存储在"CandidateViewCounts“表中,而查看同一候选人的后续Recruitres将不会被存储。

结果:,我需要通过ViewsAssigner_Identifier_id检索所有Candidate_Id的列表,然后我可以对所有这些候选Ids进行求和。

查询示例:

从Candidate_Id =1的dbo.CandidateViewCounts中选择ViewsAssigner_Identifier_id

有什么建议吗?

EN

回答 2

Stack Overflow用户

发布于 2013-01-15 22:40:38

如果您认为每个招聘人员可能会查看每个应聘者一次,那么您所指的是最多6万*200万行。这是一个很大的数字,但它们不是很宽的行;正如ErikE解释的那样,每个页面上都可以得到许多行,所以即使是表扫描,总的I/O也不会像听起来那么糟糕。

尽管如此,出于维护的原因,只要您不使用CandidateID进行搜索,您可能希望在RecruiterID上对此表进行分区。例如,您的分区方案可以在1到2000之间为RecruiterID有一个分区,为2001年-> 4000提供一个分区,这样可以使每个分区的行数最大化,并相应地规划文件空间(您可以将每个分区放在自己的文件组中,分离I/O)。

另一点是:如果你想要运行诸如“对这个候选人有多少看法(我们不关心哪个招聘人员)”之类的查询?或者“这个招聘人员看了多少个应聘者(我们不在乎哪个应聘者)?”然后,您可以考虑索引视图。例如。

代码语言:javascript
运行
复制
CREATE VIEW dbo.RecruiterViewCounts
WITH SCHEMABINDING
AS
  SELECT RecruiterID, COUNT_BIG(*)
    FROM dbo.tablename;
GO
CREATE UNIQUE CLUSTERED INDEX pk_rvc ON dbo.RecruiterViewCounts(RecruiterID);
GO

CREATE VIEW dbo.CandidateViewCounts
WITH SCHEMABINDING
AS
  SELECT CandidateID, COUNT_BIG(*)
    FROM dbo.tablename;
GO
CREATE UNIQUE CLUSTERED INDEX pk_cvc ON dbo.CandidateViewCounts(CandidateID);
GO

现在,这些聚集索引的维护成本很高,因此您需要针对它们测试您的写工作负载。但是,他们应该非常、非常快地进行这两个查询,而不必为非常繁忙的招聘人员或非常受欢迎的候选人查找您的大表,并可能读取多个页面。

票数 3
EN

Stack Overflow用户

发布于 2013-01-15 22:22:20

如果您的表聚集在RecruiterID上,您将有一个非常快的搜索,在我看来,根本没有性能问题。

在你所描述的这样一个狭窄的表格中,找出任何一个招聘人员查看的个人资料应该需要一个单一的阅读99+%。(假设填充因子= 80,页面分割最小;行宽假设两个int列= 16字节+开销,调用20字节;每页8040个左右字节;假设每个招聘人员平均获得4次查看,平均2.5行=每个数据页大约128个招聘人员)。表中的行总数与此无关,因为它可以查找聚集索引。是的,它必须穿过这棵树,但它还是会很快的。只要每个候选人的意见必须计算一次,就没有更好的办法了。如果它只是总的视图,则可以进行计数。

我觉得你没什么好担心的。如果你担心系统每秒会增加到数以万计的请求,你会得到某种有限的活动热点,只要在任何一个时间点访问的招聘人员没有偶然地给他们分配顺序ID,你就会没事的。

这里的大原则是,你想要避免任何需要从上到下扫描桌子的东西。只要您总是通过RecruiterIDRecruiterID, CandidateID进行搜索,就可以避免这种情况。当您想单独通过CandidateID进行搜索时,如果没有额外的索引,您就会遇到麻烦。在CandidateID上添加一个非聚集索引将使表占用的空间翻一番(一半用于集群,一半用于非聚集),但这并不是什么大不了的事情。然后CandidateID的搜索将同样快,因为非聚集索引将正确覆盖查询,并且不需要书签查找。

更新

这是对您在更新您的问题中提供的大量新信息的答复。

首先,CandidateViewCounts表的命名不正确。它更像是CandidateFirstViewedByRecruiterAtCompany。它只能间接地回答您的问题,即关于公司的问题,而不是招聘人员的问题,所以在我看来,您所描述的场景确实需要一个CompanyCandidateViewed表:

代码语言:javascript
运行
复制
CompanyID int FK
CandidateID int FK
PRIMARY KEY CLUSTERED (CompanyID, CandidateID)

存储查看候选人的招聘人员的CompanyID和CandidateID。很简单!现在,我最初的答案仍然适用于您,只需将RecruiterIDCompanyID交换即可。

如果您确实希望跟踪哪些招聘人员查看了哪些候选人,请在RecruiterCandidateViewed表中这样做(并存储所有招聘人员->候选人视图)。可以稍后查询或在数据仓库中查询。但是,您的实时OLTP需求将由上面描述的表来满足。

此外,我想提到的是,您有可能在不需要标识列的表中放置标识列。您应该避免使用标识列,除非该列将被用作另一个表中的FK (而且有时也不会像在适当的数据建模中那样,因为为了防止可能的反正规化,必须在FKs中使用复合键)。例如,在我看来,您的ViewsAssigner_Identifier表似乎需要一些帮助(当然,我这里没有所有的信息,而且可能不在基础上)。如果CompanyDate是该表最重要的部分,那么将它们放在集群PK中,并尽可能地去掉identity列。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14347916

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档