2012-07-07 34 views
2

我有一個需要「簡單」家族樹的應用程序。我希望能夠執行查詢,爲家庭成員提供一個身份證號的整個家庭提供數據。我說簡單是因爲它不需要考慮收養或任何其他不明朗因素。對於應用程序的要求如下:近親免疫數據庫結構

  • 任何兩個人將無法繁殖,如果他們來自同一個基因線
  • 需要允許增加新的家系(新人們提供沒有以前的家庭)
  • 通過我在未來與數據庫的結構合理麻煩查詢

需要能拉兄弟姐妹,父母分開。到目前爲止,我已經提出了兩種解決方案,但它們不是很可靠,可能會很快失控。

解決方案1涉及在people表中放置family_ids字段並存儲唯一系列ID的列表。每次兩個人繁殖時,列表被互相檢查以確保沒有ids匹配,並且如果所有內容都會檢出,將合併兩個列表並將其設置爲孩子的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將獲取的父親和母親的結果,與他們的母親和父親一起,等等等等一路下線。這條路線的問題是數據是嵌套數組,我不確定如何有效地處理代碼。

如果任何人能夠引導我走向最有效的方式來處理我想要達到的,這將是非常有益的。任何和所有的幫助非常感謝,我很樂意回答任何人的問題。非常感謝。

回答

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')。訣竅是製作另一個插入與這個新鮮人有關的親戚: INSERT INTO relatives VALUES (%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存儲在第一個表中)來加速直接父母/孩子的查找 - 實際上可以單獨使用第一個表來完成。

下面是一個工作(雖然有點簡短)SQL Fiddle示例以更實用的顏色顯示此示例。 )

+0

我還想補充一點(儘管在我完成這些寫作和擺弄之後,我的一部分尖叫着我),你可能會考慮使用面向圖形的數據庫來完成這項任務。例如,我使用[Neo4J](http://neo4j.org/)的時間很愉快。 ) – raina77ow 2012-07-07 16:50:45

+0

非常好,非常感謝。這個例子也很有幫助。 – 2012-07-07 19:24:34

+0

是否有可能輕鬆檢索有序的樹(或一些固定的世代:fe.4或5)只知道一個people.id? – Danilo 2013-02-18 12:59:30