I need to build a family tree in php and MySQL. I'm pretty surprised at the lack of open source customizable html family tree-building software there is out there, but I digress. I have spent a lot of time reading about storing MySQL digraphs and family trees. Everything makes sense to me: have a table with nodes (people) and a table with edges (relationships).
The only problem I have is I'm not sure of the best way to store relationships that are not necessarily adjacent, for example sibling and grandparent relationships. At first I didn't think this would be a big deal because I can just invisibly enforce a parent (everyone has parents) that would resolve these connections.
However, I also need to be able to store relationships that may not have a common parent such as romantic partners. Everything I have read suggests a parent-child relationship, but since romantic partners do not share a common parent (hopefully), I'm not sure how to store it in the edges table. Should I use a different table, or what? If it's in the same table, how do I represent this? As long as I am doing this with non-familiar relationships, I might as well do it with family too.
To sum up, three questions:
- How do I represent lateral relationships?
- If a lateral relationship has a common parent, how do I store it? Should this be a
family
flag on the table where other lateral relationships are stored?
- How do I store parent-child relationships where the child is two or more edges away (a grandparent), but the immediate parent is unavailable?
Any help is appreciated, and if anyone has any suggestion for some javascript/html family tree building software, that would be wonderful.
An idea that comes from the Geneapro schema and RootsMagic.
person
------
person_id
name (etc)
life_event_types
----------------
life_event_type_id
life_event_type_description (divorce, marriage, birth, death)
life_events
-----------
life_event_id
life_event_type_id
life_event_description
life_event_date
life_event_roles
----------------
life_event_role_id
life_event_role (mother, father, child)
person_event_role
-----------------
person_id - who
life_event_id - what happened
life_event_role_id - what this person did
So you could have a life event of type "birth", and the role_id tells you who were the parents, and who was the child. This can be extended to marriages, deaths, divorces, foster parents, surrogate parents (where you might have 3 or 4 parents with a very complicated relationship), etc.
As for storing more distant relationships, you can calculate these. For example, you can calculate the Father of anybody by getting the person who has the 'father' role with a matching event_id. You can then get the father of that person, and you have the grandfather of the original person. Anywhere that somebody is unknown, create the person with unknown data.
person
-------
person_id
other_stuff
relation
----------
person_id_1
person_id_2
relationship_type
begin_dt
end_dt
just populate the relationship type with any value you are interested in. (FK to some picklist would be great)
I put the dates on for an interesting subdiscussion/thought provokation.
The GEDCOM data model and the Gramps data model are two of the most popular formats for exchanging geneological data between different tools. Using either of these data models should both (1) make your tool more compatible with other tools and (2) ensure that your data model is compabible with many special cases, considering both data models are specially designed to deal with geneological data.
Tools like Oxy-Gen or the Gramps PHP exporter should get you on your way with respect to how to import GEDCOM data into a database.
For more details, see also my answer to “Family Tree” Data Structure.