我是图数据库的新手,需要针对这种情况的建议。我有喜欢类别的人(仅在树上留有叶子),其他节点(父母)不喜欢。然后,我为特定用户与其他用户的所有连接计算得分。这是一个图形示例:
我尝试使用neo4j,但没有任何问题(非常小的数据集),但是我担心很多用户的性能。我已经测试以下查询:
MATCH (n:Person)-[:LIKES*]->()-[r:SUB*0..4]-()<-[:LIKES*]-(m:Person)
WHERE n.name='Gabriel' and n<>m
WITH n.name as user, m.name as connection, 1.0/(length(r)+1)*count(r) as score
RETURN user, connection, sum(score)
我还考虑过在关系数据库中执行此操作,为类别likes(cat1,cat2,cat3)保存3个字段,然后进行3个自我联接,以查找不同类别级别的匹配项。这样的事情(从用户1开始并尝试与其他用户匹配):
select l2.user_id, sum(
case
when (l1.cat2 = l2.cat2 and l1.cat3 = l2.cat3) then 1
when (l1.cat2 = l2.cat2) then 0.25
else 0.05
end)
from likes l1
inner join likes l2 on l1.cat1 = l2.cat1 and l2.user_id <> 1
where l1.user_id = 1
group by l2.user_id
但我也读到您应该避免进行自我联接。
我澄清我正在寻找阅读性能,写作并不重要。 我的目标是与1百万个用户(每个有10个赞)一起使用。 我听任何意见,谢谢!
答案 0 :(得分:0)
TLDR; IMO的关系数据库会更好,因为您可以查看一件事与另一件事的关系,即一个人有多少(团队)喜欢。您可以轻松更新用户,团队或运动的元数据,而不必担心搞乱您的分析查询。另外,您可以轻松地扩展以添加诸如大学,高中等运动类型,而不必担心您之前的设置可能会搞砸。
但是,我承认我以前从未使用过图形数据库。 :)
建立关系数据库可能看起来像这样:
我喜欢称呼这些信息表,因为它们仅提供特定项目的信息,有些人也称它们为参考表: 体育(Sport_ID,Sport_Name等[...] ...)体育名称,例如足球,篮球等 示例视图:
╔══════════╦════════════╦═════╗
║ Sport_ID ║ Sport_Name ║ ... ║
╠══════════╬════════════╬═════╣
║ 1 ║ Football ║ ... ║
║ 2 ║ Basketball ║ ... ║
║ ... ║ ... ║ ... ║
╚══════════╩════════════╩═════╝
团队(Team_ID,Team_Name,Home_State等)...-团队将是所有团队,无论他们从事哪种运动。 示例视图:
╔═════════╦═════════════╦═════╗
║ Team_ID ║ Team_Name ║ ... ║
╠═════════╬═════════════╬═════╣
║ 1 ║ Boca Junior ║ ... ║
║ 2 ║ River Plate ║ ... ║
║ 3 ║ Spurs ║ ... ║
║ ... ║ ... ║ ... ║
╚═════════╩═════════════╩═════╝
User(用户ID,User_First_Name,[etc] ...)-仅所有用户特定信息会在此处。 示例视图:
╔═════════╦═════════════════╦═════╗
║ User_ID ║ User_First_Name ║ ... ║
╠═════════╬═════════════════╬═════╣
║ 1 ║ Mario ║ ... ║
║ 2 ║ Gabriel ║ ... ║
║ 3 ║ Juana ║ ... ║
║ 4 ║ Raul ║ ... ║
║ ... ║ ... ║ ... ║
╚═════════╩═════════════════╩═════╝
然后,您将创建关系表以在运动,团队和用户之间建立联系。
Sports_Team(Sport_ID,Team_ID)-在这里您将显示哪个队参加了哪种运动。 示例视图:
╔══════════╦═════════╦═════╗
║ Sport_ID ║ Team_ID ║ ... ║
╠══════════╬═════════╬═════╣
║ 1 ║ 1 ║ ... ║
║ 1 ║ 2 ║ ... ║
║ 2 ║ 3 ║ ... ║
║ ... ║ ... ║ ... ║
╚══════════╩═════════╩═════╝
Team_User_Likes(团队ID,用户ID)-在这里您将显示哪些人喜欢哪些球队参加了哪种运动。 示例视图:
╔═════════╦═════════╦═════╗
║ Team_ID ║ User_ID ║ ... ║
╠═════════╬═════════╬═════╣
║ 1 ║ 1 ║ ... ║
║ 2 ║ 2 ║ ... ║
║ 2 ║ 3 ║ ... ║
║ 3 ║ 3 ║ ... ║
║ ... ║ ... ║ ... ║
╚═════════╩═════════╩═════╝
现在要获得用户喜欢的球队得分,您要做的就是:
SELECT tul.User_ID
, COUNT(tul.Team_ID) AS Likes
FROM team_user_likes tul
GROUP
BY tul.User_ID
如果您想要用户元数据(如用户名),则可以将此查询放入CTE,然后使用user表联接到CTE表。
这看起来和听起来很复杂,但将使编辑/更新用户/团队/体育信息变得更加容易。您将能够进行一些有趣的分析,例如使用喜欢的数据有多少用户喜欢/更喜欢一项运动而不用担心另一项运动,而不必担心影响关系表,或者每种运动的哪个团队是最受欢迎的。
此外,这应该容易扩展,具体取决于您使用的关系数据库。并说您想开始添加高中,大学等体育项目,您可以只添加一个sport_type表,然后创建一个sport_sport_type关系表,以将哪些运动是专业运动或其他运动之一联系起来。 Viola之后,您可以按运动类型进行分析,而不必担心它会如何影响您之前的设置。
我更喜欢关系数据库,因为它们似乎使事情保持整洁。话虽如此,我从未使用过图形数据库。但是考虑到您看到一件事与另一件事之间的关系,即一个人喜欢多少团队,我认为您应该使用关系数据库。