php - 近交免疫数据库结构

标签 php mysql cakephp database-design

我有一个需要“简单”家谱的应用程序。我希望能够执行查询,根据家庭成员的一个 ID,为我提供整个家庭的数据。我说简单是因为它不需要考虑采用或任何其他模糊性。申请条件如下:

  • 任何两个人如果来自同一遗传系,就无法繁殖
  • 需要允许添加新的家族谱系(没有以前的家族的新人)
  • 需要能够通过查询分别拉取 sibling 、 parent

我无法找到正确的数据库结构。到目前为止,我已经提出了两种解决方案,但它们不是很可靠,而且可能很快就会失控。

解决方案 1 涉及在 people 表上放置一个 family_ids 字段并存储唯一家庭 ID 的列表。每次两个人繁殖时,都会相互检查列表以确保没有 id 匹配,如果所有内容都检查完毕,则会合并两个列表并将其设置为 child 的 family_ids 字段。

示例:

Father (family_ids: (null)) breeds with Mother (family_ids: (213, 519)) ->
Child (family_ids: (213, 519)) breeds with Random Person (family_ids: (813, 712, 122, 767)) ->
Grandchild (family_ids: (213, 519, 813, 712, 122, 767))

等等......我看到的问题是随着时间的推移列表变得不合理地大。

解决方案2使用cakephp的关联来声明:

public $belongsTo = array(
    'Father' => array(
        'className' => 'User',
        'foreignKey' => 'father_id'
    ),
    'Mother' => array(
        'className' => 'User',
        'foreignKey' => 'mother_id'
    )
);

现在将递归设置为 2 将获取母亲和父亲的结果,以及他们的母亲和父亲,依此类推。此路线的问题在于数据位于嵌套数组中,我不确定如何有效地完成代码。

如果有人能够引导我以最有效的方式来处理我想要实现的目标,那将非常有帮助。非常感谢任何和所有的帮助,我很乐意回答任何人的任何问题。非常感谢。

最佳答案

在 SQL(更准确地说,RDBS)中,我将使用以下解决方案:

1) 创建一个包含以下字段的表 people - idnamefather_idmother_id。第一个是典型的主键列,father_id 和 mother_id 引用该列,但可以为 NULL(以允许添加新的家族世系)。

2) 创建一个包含以下字段的表 relatives - person_idancestor_id。两者都不为 NULL,都构成复合主键,而且都是 person.id 的 FK。

就是这样。不完全是! )现在考虑您的任务:

  • 添加一些没有家族血统的人

这也是非常可行的:INSERT INTO people (name) VALUES ('some_name')。诀窍是将与这个新人相关的另一个插入到亲戚中: 插入亲属值(%new_person_id%、%new_person_id%)

那是做什么用的?考虑最常见的任务:添加一些实际上已经在表中列出了父亲和母亲的人。使用这个结构,它的完成就像(将相应的记录插入 people 后,并获取此 person_id 作为结果)...

INSERT INTO relatives 
    SELECT %new_person_id%, ancestor_id 
      FROM relatives 
     WHERE person_id IN (%father_id%, %mother_id%);
INSERT INTO relatives VALUES (%new_person_id%, %new_person_id%);
  • 任何两个人如果来自同一遗传系,就无法繁殖。

使用上述结构就相当简单了:您必须在 relatives 中查找 ancestor_id 字段中具有相同值的两条记录。例如:

    SELECT COUNT(*) 
      FROM relatives ra 
INNER JOIN relatives rb ON ra.ancestor_id = rb.ancestor_id
     WHERE ra.person_id = %person_a_id%
       AND rb.person_id = %person_b_id%

在这个结构中查找所有祖先和子代是相当容易的;但我仍然更喜欢非规范化方法(即,将father_id和 mother_id存储在第一个表中)以加快查找直接 parent / child 的速度 - 实际上可以单独使用第一个表来完成。

这是一个工作(虽然有点短)SQL Fiddle示例以更实用的颜色来展示这一点。 )

关于php - 近交免疫数据库结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11372248/

相关文章:

php - Laravel 函数中无法识别变量

mysql - 如何在 mysql5 存储过程中内爆查询结果?

mysql - **[错误]1416 : GEOMETRY field in DB Query

xml - CakePHP 生成 XML

php - 如何处理同一多对多关系的多种类型?

php - 在 PHP 中处理动态数量的输入

php - CakePHP - 第三部分作业

php - PHP 应用程序的可扩展性

php - php explode 问题,尝试分隔字符串

Mysql - 一张表中有两个主键 - (自动递增,一个主键为一个主键 - 子类型)