Designing a mysql database of relationships between contacts?

user2012105 :

I'm trying to design a database of contacts but I also want to keep track of their relationships with other contacts whether it be family, friends, cowokers etc. I created a table for contacts and created an affiliates table that labels the type of relationship but I'm not sure if I did the design correct and I'm unsure if this would just be a normal many to many relationship or some sort of recursive relationship. I would also like to know how I would query to be able to get all the relationships to one contact and all of the relationships to all contacts.

Contacts Table
CID CFirstName CLastName
1   Roy        Saldana
2   Linda      Rodriguez
3   Hector     Rodriguez

Both CID & C_ID are the same I just thought I couldn't name both columns the same so I gave one a _.

Affiliates Table
CID   AfiliateType C_ID  ex: CID is the mother of C_ID 1
2     mother        1 
1     son           2 
3     husband       2 
3     step-father   1 
3     wife          3
SELECT Contacts.FirstName, Contacts.LastName, Afiliates.AfiliateType 
FROM Contacts 
INNER JOIN Afiliates 
ON Contacts.CID = Afiliates.C_ID

I know this isn't the correct way but I can't seem to get passed this part, I'm thinking I need to query the names twice or maybe it's a programming issue not the design, I'm totally lost. Any help would be appreciated. Thanks in advance

Damir Sudarevic :
-- Contact CID is named FIRST_NAME LAST_NAME.
--
contacts {CID, FIRST_NAME, LAST_NAME}
      PK {CID}
      AK {FIRST_NAME, LAST_NAME}


-- Contact CID_1 is AFF_TYPE of contact CID_2.
--
affiliates {CID_1, CID_2, AFF_TYPE}
        PK {CID_1, CID_2}

FK1 {CID_1} REFERENCES contacts {CID}
FK2 {CID_2} REFERENCES contacts {CID}

CHECK (CID_1 <> CID_2)

Contact FROM_FIRST FROM_LAST is AFF_TYPE of TO_FIRST TO_LAST.

SELECT b.FIRST_NAME AS FROM_FIRST
     , b.LAST_NAME  AS FROM_LAST
     , a.AFF_TYPE
     , c.FIRST_NAME AS TO_FIRST
     , c.LAST_NAME  AS TO_LAST
FROM affiliates AS a
JOIN contacts   AS b ON b.cid = a.cid_1
JOIN contacts   AS c ON c.cid = a.cid_2
WHERE a.cid_1 = the_contact_id
   OR a.cid_2 = the_contact_id ;

One thing to consider is what to do with symmetrical relations, for example CID_1 is mother of CID_2, is not symmetrical, but CID_1 is brother of CID_2 is. For symmetrical relations it is the usual way to insert rows only for CID_1 < CID_2.

Note:

All attributes (columns) NOT NULL

PK = Primary Key
AK = Alternate Key   (Unique)
FK = Foreign Key

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=379279&siteId=1