Search code examples
phphtmlmysqldirected-graphfamily-tree

MySQL Store Relationship (Family) Tree


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.


Solution

  • 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.