【问题标题】:Iterating through a social graph in a SQL database遍历 SQL 数据库中的社交图
【发布时间】:2013-06-15 15:24:57
【问题描述】:

我像这样存储简单的社交图信息:

People ( PersonId bigint, Name nvarchar )
Relationships ( From bigint, To bigint, Title nvarchar )

所以数据看起来像这样:

People
1, John Smith
2, Joan Smith
3, Jack Smith

Relationships
1, 2, Spouse
1, 3, Parent
2, 3, Parent

注意关系的标题是规范化的:所以没有“丈夫”和“妻子”,只有“配偶”,这也避免了需要创建两个单独的关系形成相同的链接,同样适用于“父母” " 而不是“儿子”或“女儿”。

问题是如何遍历整个连通图(即仅返回一个家庭),例如,无需创建显式的兄弟关系条目即可找到兄弟姐妹。节点不一定需要以任何特定顺序返回。我可能还想只返回距给定起始节点最多 N 度的节点。

我知道你可以在最近的 SQL 语言版本中使用一些新技巧来执行递归 SQL SELECT 语句,但这不一定是递归操作,因为这些关系可以表示一个循环无向图(想想如果添加了“朋友”作为关系)。你会如何在 SQL 中做到这一点?

【问题讨论】:

  • 您使用的是哪个数据库?
  • MS SQL Server 2012,谢谢!
  • 非常有趣的问题。你能详细说明你的确切问题吗?您的问题可以是“从PeopleRelationships 查找兄弟姐妹”。如果可能,您能否向我们展示您期望的示例结果集?
  • 你知道neo4j.org吗?它声称在计算这些关系方面速度非常快。

标签: sql recursion graph sql-server-2012


【解决方案1】:

非常酷的问题。虽然它是一个社交网络图,但它仍然是一个层次问题,即使层次结构在逻辑上可以变成一个互连网络。在 MSSQL 中,您仍然希望使用 WITH 子句进行递归查询,唯一的区别是由于需要使用多个互连来确保唯一的结果,或者使用 DISTINCT 或使用 IN 子句在WHERE 条件。

这行得通:

DECLARE @PersonID bigint;
SET @PersonID = 1;

WITH RecurseRelations (PersonID, OriginalPersonID)
AS
(
    SELECT  PersonID, PersonId OriginalPersonID
    FROM    People

    UNION ALL

    SELECT  ToPersonID, RR.OriginalPersonID
    FROM    Relationships R
                    INNER JOIN
            RecurseRelations RR
                    ON
                R.FromPersonID = RR.PersonID
)
SELECT  PersonId, Name
FROM    People
WHERE   PersonId IN 
        (               
            SELECT  PersonID
            FROM    RecurseRelations
            WHERE   OriginalPersonID = @PersonID
        )

这里有一些测试数据,它们的关系比你原来和整个其他家庭的关系要多,以确保它不会超出预期。

create table People ( PersonId bigint, Name nvarchar(200) );
create table Relationships ( FromPersonID bigint, ToPersonID bigint, Title nvarchar(200) );

insert into People values (1, 'John Smith');
insert into People values (2, 'Joan Smith');
insert into People values (3, 'Jack Smith');
insert into People values (4, 'Joey Smith');
insert into People values (9, 'Jaime Smith');

insert into People values (5, 'Edward Jones');
insert into People values (6, 'Emma Jones');
insert into People values (7, 'Eva Jones');
insert into People values (8, 'Eve Jones');

insert into Relationships values (1, 2, 'Spouse');
insert into Relationships values (1, 3, 'Parent');
insert into Relationships values (2, 3, 'Parent');
insert into Relationships values (3, 4, 'Child');
insert into Relationships values (2, 4, 'Child');
insert into Relationships values (4, 9, 'Child');

insert into Relationships values (5, 6, 'Spouse');
insert into Relationships values (5, 7, 'Parent');
insert into Relationships values (6, 7, 'Parent');
insert into Relationships values (5, 8, 'Child');

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-01-09
    • 2011-08-14
    • 2010-12-16
    • 1970-01-01
    • 2018-03-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多