Mysql 使用闭包表的SQL家谱,支持配偶、兄弟姐妹、姻亲、啃咬等

Mysql 使用闭包表的SQL家谱,支持配偶、兄弟姐妹、姻亲、啃咬等,mysql,family-tree,transitive-closure-table,genealogy,Mysql,Family Tree,Transitive Closure Table,Genealogy,我读过比尔·卡温(Bill Karwin)在博文中的回答,我很惊讶它如何解决了我一直在用MySQL数据库研究的家谱(至少在父子关系或祖先后代层次上)的基本问题。 与邻接列表和其他模型相比,它的优点使它成为我的项目的一个很好的选择。但是,正如前面所讨论的,不支持为兄弟姐妹或侄子连接节点。此外,我想将这种原则应用到我的数据库项目中 为了支持姻亲、侄子、外甥、配偶等的连接,如果可能的话,我想扩展闭包表原则及其查询来支持这种关系 参考图像(黄色节点为): 具有正确节点连接的查询可以给出以下答案: (4

我读过比尔·卡温(Bill Karwin)在博文中的回答,我很惊讶它如何解决了我一直在用MySQL数据库研究的家谱(至少在父子关系或祖先后代层次上)的基本问题。 与邻接列表和其他模型相比,它的优点使它成为我的项目的一个很好的选择。但是,正如前面所讨论的,不支持为兄弟姐妹或侄子连接节点。此外,我想将这种原则应用到我的数据库项目中 为了支持姻亲、侄子、外甥、配偶等的连接,如果可能的话,我想扩展闭包表原则及其查询来支持这种关系

参考图像(黄色节点为):

具有正确节点连接的查询可以给出以下答案:

  • (4) 至(5):兄弟姐妹

  • (9) 至(2):配偶

  • (3) 致(5):侄子/侄女

  • (4) 至(3)或(6)至(2):叔叔/婶婶

  • (1) 至(9):儿媳

  • (10) 致(4):侄子

  • 在这种情况下,当我引用单个节点时,比如(2),它可以给我相关节点的列表以及它们之间的关系:

  • (1) 是父母吗

  • (5) (4)是儿童

  • (3) 他是兄弟姐妹

  • (9) 她是一个配偶

  • (10) 她是一个姐夫

  • (6) 她是侄子/侄女

  • (8) (7)是孙辈

  • 在构建家谱树系谱时,还有其他场景,例如同父异母(父节点不同,因此不能假设这两个节点具有相同的父节点);其他关系,如“我的配偶和我兄弟姐妹的配偶也是兄弟姐妹”。这也说明我的孩子是我兄弟姐妹配偶的侄子)


    我相信这可以通过闭包表完成,但可能不是那么简单。任何文章、建议或疑问都会大有帮助。谢谢(可能很久以前就有人解决了这个问题,我就是找不到合适的资源。):)

    闭包表对于有向无环图(DAG)很有用。但家谱更为复杂,DAG的价值有限。我使用了Neo4j,它支持更复杂的图形,并支持所有祖先或后代的msec查询,类似于闭包表。它还支持同级查询:

    兄弟姐妹:

    match p=(n:Person{RN:1})-[:father|mother]->(m) match (m)<-[:father|mother*..1]-(s) return distinct n.RN,s.RN,s.fullname
    
    match p=(n:Person{RN:1})-[:父|母]->(m)match(m)(m),其中长度(p)=1
    匹配q=(m)
    
    match p=(n:Person{RN:1})-[:father|mother*..2]->(m) where length(p)=1
    match q=(m)<-[:father|mother*..1]-(s) where length(q)=1 
    match (s)<-[:husband|wife]-(t) return distinct n.RN,s.RN,s.fullname,t.RN,t.fullname
    
    match p=(n:Person{RN:1})-[:father|mother*..2]->(m) where length(p)=2
    match q=(m)<-[:father|mother*..1]-(s) where length(q)=1 return distinct n.RN,s.RN,s.fullname
    
    match p=(n:Person{RN:1})-[:father|mother*..3]->(m) where length(p)=2
    match q=(m)<-[:father|mother*..3]-(s) where length(q)=2 return distinct n.RN,s.RN,s.fullname
    
    match p=(n:Person{RN:1})-[:father|mother*..4]->(m) where length(p)=3
    match q=(m)<-[:father|mother*..4]-(s) where length(q)=3 return distinct n.RN,s.RN,s.fullname