mysql - 使用 Closure Table 的 SQL 家谱谱系,支持配偶、 sibling 、姻亲、 sibling 等

标签 mysql family-tree transitive-closure-table genealogy

我已阅读 Bill Karwin 在 this 上的回答这篇文章让我感到惊讶的是它如何使用 MySQL 数据库解决了我一直在研究的家谱谱系的基本问题(至少在亲子关系或祖先后代层面上)。 与邻接列表和其他模型相比,它的优点使其成为我的项目的绝佳选择。然而,正如所讨论的,不支持连接 sibling 或侄子的节点。此外,我想将这样的原则应用到我的数据库项目中 还支持姻亲、侄子、孙子、配偶等的连接。如果可能的话,我想扩展封闭表原则及其查询来支持此类关系。

引用图片(黄色节点为配偶): Sample Family Tree Structure

具有正确节点连接的查询可以给出答案,例如引用时:

  1. (4)到(5): sibling

  2. (9)至(2):配偶

  3. (3)至(5):侄子/侄女

  4. (4)至(3)或(6)至(2):叔叔/阿姨

  5. (1)至(9):儿媳

  6. (10)至(4):侄子

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

  1. (1) 是父级

  2. (5) 和 (4) 是子级

  3. (3) 是 sibling

  4. (9) 是配偶

  5. (10) 是姐夫

  6. (6) 是侄子/侄女

  7. (8)和(7)是孙子

构建家谱谱系时还存在其他情况,例如同父异母的 sibling ( parent 不同,因此您不能假设这两个节点是否具有相同的 parent );以及其他关系,例如“我的配偶和我 sibling 的配偶也是姐夫”。这也表明我的 child 是我 sibling 的配偶的侄子)。

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

最佳答案

闭包表对于有向非循环图 (DAG) 非常有用。但谱系更为复杂,DAG 的值(value)也有限。我使用了 Neo4j,它支持更复杂的图形,并支持对所有祖先或后代进行毫秒查询,类似于闭包表。它还支持同级查询:

sibling :

match p=(n:Person{RN:1})-[:father|mother]->(m) match (m)<-[:father|mother*..1]-(s) return distinct n.RN,s.RN,s.fullname

sibling

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

第二代表 sibling

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

等等。

关于mysql - 使用 Closure Table 的 SQL 家谱谱系,支持配偶、 sibling 、姻亲、 sibling 等,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43013720/

相关文章:

php - 输入 PHP/mysql 表值时需要快速帮助

java - 家谱程序的逻辑

mysql - 在数据库中保存树数据(家谱)

Prolog:程序中的统一或回溯错误

ruby-on-rails - 使用闭包表模式实现版本历史

java - Java SQL 中的错误

mysql - 为什么 TINYINT(1) 作为 bool 值运行而 INT(1) 不运行?

MySQL 分区 : why it's not taking appropriate partition

mysql - 使用 MySQL 移动传递闭包子树

sql - SQL 中图形结构的闭包表等价物