我正在开发一个应用程序,我必须处理一个名为'Skill'的实体。现在的问题是,“技能A”可以与“技能B”具有一定的相关性(相关性用于搜索目的)。类似地,“技能B”也可以与“技能C”相关。我们目前有以下数据模型来表示这种情况
技能{SkillId,SkillName}
RelevantSkill {SkillId,RelevantSkillId,RelevanceLevel}
现在,鉴于上述情况,我们在“技能A”和“技能C”之间存在隐含关系。这种情况的最佳数据模型是什么?执行搜索时,我们还必须遍历此层次结构。
答案 0 :(得分:1)
你最好的选择是:
使用ImplicitRelevance
布尔列扩充RelevantSkill:
RelevantSkill {SkillId, RelevantSkillId, RelevanceLevel, ImplicitRelevance}
插入(进入RelevantSkill
表)对应于所有隐式(间接)相关关系的行(例如“技能A” - >“技能C”)及其对应的计算 RelevanceLevel
,当且仅当计算出的RelevanceLevel
高于设定的阈值时。这些行的ImplicitRelevance
设置为true
skill_a_id, skill_b_id, computed_level, 'T'
如果对显式相关性级别(指标)进行了任何更改,请删除ImplicitRelevance = true的所有行并重新计算(重新插入)它们。
答案 1 :(得分:1)
你的解释留下的是在间接(“隐含”)关系的情况下如何组合相关性水平。例如。如果技能A与B级别相关且技能B与级别5的技能C相关,则技能A与技能C间接相关的级别(作为数字)是什么?
正确的数据模型取决于两件事:你拥有多少技能,以及关系结构的密集程度(密集=很多技能与其他技能相关)。如果关系结构密集且技能很少(<1000),那么最好将整个事物表示为矩阵。
但是如果你有很多技能但是稀疏的关系结构你可以把它表示为三个表:
Skill {SkillId, SkillName}
RelevantSkill {SkillId, RelevantSkillId, RelevanceLevel}
IndirectRelevance { SkillId, RelevantSkillId, RelevanceLevel}
第三个表(IndirectRelevance)是根据两个主表计算的;无论何时更改Skill或RelevantSkill表,都需要更新IndirectRelevance表。
我认为最好有三张桌子而不是两张桌子;这使得实现更清晰,更直接。 RelevantSkill包含明确规定的关系; IndirectRelevance所有派生的事实。
答案 2 :(得分:1)
你所要求的似乎基本上是从一组成对距离计算的图距离算法(斜线数据结构)。一个合理的(可计算的)度量标准是commute time。
可以这样考虑:构造一个图形,其中每个节点都是一个技能,每个边缘代表它相互连接的节点的相关性。现在想象一下,你是从图中的某个节点(一些技能)开始,然后沿着定义的边缘随机跳转到其他节点。假设从技能A跳到技能B的概率与这些技能相互之间的相关性成正比(通过与其他技能的相关性来标准化......)。现在,通勤时间表示从技能A到技能C所需的平均步数。
这有一个非常好的属性,在两个节点之间添加更多路径会缩短通勤时间:如果技能A和B,B和C,C和D,以及D和A相关,那么A和A之间的通勤时间C会缩短。此外,使用稀疏连接的技能图的特征值分解可以非常容易地计算通勤时间(我认为我给你的参考显示了这一点,但如果没有,则有很多可用)。
如果你想在任何一对技能之间存储通勤时间,你需要一个完全连接的图形,或者NxN矩阵(N是技能的数量)。然而,一个更好的变体是,如上所述,删除所有弱于某个阈值的连接,然后将稀疏连接的图形存储为数据库中的行。
祝你好运,我希望这有所帮助!答案 3 :(得分:0)
在选择最佳选项之前,有一些因素需要考虑:
结构显然会像antti.huima提出的那样。不同之处在于如何实施IndirectRelevance。如果有很多变化,很多关系和关系是密集的,那么最好的方法可能是存储过程(也许通过视图访问)。如果关系稀疏并且存在阈值,则最佳选项可能是物化视图或通过触发器更新的表。