views:

96

answers:

5

I am building my wife a Contacts Manager program as a fun exercise in learning Silverlight 4. It will track peoples Addresses, Phone Numbers, Emails, Special Occasions(Birthday, Anniversary, etc)

Along the way I hit a minor road bump while designing the Database. She would like to be able to group Contacts(people) by Family so I created a Families table that has FamilyID and FamilyDescription and then added FamilyID to table People.

Now SELECT * FROM People WHERE FamilyID = 2 would return everyone in that particular family.

I THINK this is an acceptable idea; where I am struggling, though, is how to incorporate children, as in kids. We have a very, very large family so there will be multiple kids per family. Do I just add them to table People, if so, how do I differentiate who the kids are from the adults?

I am very grateful for any insight, thanks.

+2  A: 

Wouldn't you have a Mother and Father column per People entity, which referenced another PeopleId?

Children are people too, you know!

Also, what is your definition of a Family? People who live at the same address. Boxing people in to a family sounds difficult, how many generations constitutes a family.

And my idea about a mother and father column per People entity does not take in to account gay couples with children, but we shouldn't over think the problem or you could drive yourself mad.

Check out this WPF sample appliction - http://www.vertigo.com/familyshow.aspx

benPearce
Children are slave labour and tax deductions =)
OMG Ponies
And you're lucky to get the labor, if you can.
Adam Musch
A: 

You can create a column Level in People table and assign the generation to it.

Example: Grandparents will have level -2, parents will have -1, kids/teens will have 0, their kids (future) will have 1, pets can have 2, etc.

Then you can easily generate the list of a family by generations.

shamittomar
Consider that while I'm a grandfather to one child, I'm an uncle to another, and cousins after that...
OMG Ponies
@OMG Ponies, you are your own child's grandfather?
tster
A: 

I would do some sort of intersection table and maybe assign a field on the relation for "relation type" ... so you could define like aunts and uncles, or mother in law, father in law ... etc. Then also have a family table like you describe. That keeps the number of fields lower, and prevents potential empties or nulls creeping in, at the expense of more rows...

The benefit here is that kids can also be parents later. So you can just keep defining new families and don't change the prior relations. Also allows you to find all the families one person belongs too, or lets you do chaining to find related families ... (find all families where familyX.relationtype = children appear ...)

Just how I would choose to do it.

drachenstern
sounds very complex. Also, I don't like with my mother or my father. How would this system know that we aren't a "family"?
tster
Families are very complex. Did you miss something there? Who says you must live with the family that you're part of? As soon as children grow up, they routinely move out. But I know adults who live with their parents still.
drachenstern
@drachenstern, he's not developing a genealogy application, he's making a contacts application.
tster
@tster - And your point? If this were on TDWTF everyone would bash it for not having genealogical functions. Besides, if you want to accurately model a phenomenon, then accurately model it...
drachenstern
@drachenstern. It's better to model the business need than reality. If you writing a program to manage inventory for a warehouse you aren't going to track individual apples. Instead you will track boxes or pallets.
tster
@tster +1 for being right, but I still saw this as an exercise in what's the most concise way to do it, and putting in an intersection table with a relationship type seems to be not only the easiest (KISS, ya?) but also the selected answer. So I'm still not sure why my answer, besides "complexity" is any less valid.
drachenstern
+8  A: 

The problem with the PEOPLE.familyid is that it ensures a person can belong to only one family--ever. Which means if you wanted to differentiate between immediate and extended family, you'd be looking a hierarchical structure to associate the families when they aren't necessarily hierarchical...

The most accommodating solution would be to include a many-to-many table, so you could associate a PEOPLE record to any number of FAMILY records:

PEOPLE_FAMILY_MAP

  • PEOPLE_ID (primary key, foreign key to PEOPLE.id)
  • FAMILY_ID (primary key, foreign key to FAMILY.familyid)

If you want to show relationships between people - you'd need a relationship type table (type_code, description), and associate relations using:

  • PERSON_ID (primary key, foreign key to PEOPLE.id)
  • RELATED_TO_PERSON_ID (primary key, foreign key to PEOPLE.id)
  • RELATIONSHIP_TYPE_CODE (primary key, foreign key to RELATIONSHIP_TYPE_CODES.RELATIONSHIP_TYPE_CODE)
OMG Ponies
I like this idea. Keep the foreign key for "nuclear" style families. but allow for "extended" style families as well.
tster
Out of curiosity, am I taking your answer TOO literal or would you have **2 PK's** on `PEOPLE_FAMILY_MAP` and **3 PK's** on the second part(*is that a new table as well*)
Refracted Paladin
@Refracted Paladin: Keys (primary, foreign) can be more than one column - they're called composites. Making the key a composite means the combination of values will be unique - you can't add duplicates (why would you associate to the same family twice?), without having to resort to triggers/etc
OMG Ponies
Sorry, I should have clarified my question as I do know about composite keys, I just wanted to make sure that was what you were advocating in your answer. Where I work the DBA's never use them, they always throw another column in front and have that be the PK. That has always felt wrong to me but it is also all I have really known. Don't be surprised to see a follow up question on `Composite Keys and LINQ2SQL or Entity Framework` Thank you very much for your time and patience. I will give this a go.
Refracted Paladin
@Refracted Paladin: I'm aware of ORMs preferring to use a single column - it's just to make things easier for the ORM. Still need an equivalent unique constraint/index for data validation...
OMG Ponies
A: 

OK, I'm going to go a different route here.

She wants families because she wants to be able to mass email them spam junk mail of course. So it's not like we need every single family in the families list. Really she will create families and add people to them as needed (just like a mailing list).

So:

Have a families table:

  • FamilyId
  • Name
  • Description

Then just have a mapping table:

  • FamilyId
  • PersonId
  • Role

role can be any of the following ("Head of family" (aka the deciders - aka, the buck stops there), "Peon")

Then for Mr and Mrs Johnson you can have the family "The Johnsons". but if you want to spam all their relatives you use "The Johnsons extended"

tster