-1
          USERS

 1. GFER: SUPERADMIN

Foundation(VAG):
  2. John: Incharge
  3. Jessi: IT Head

University(MIT):
 4: Bill: Adminstrator
 5: Gates: Prinicipal investigator
 6: Donald: Researcher

Organizations(YE):
 6. Jason: Head of R&D
 7. Johnny: Researcher

University, organization or company can't exist without a user. There would always exist a user who'll create it or own it. And every user would have a personal profile as well.

Schema looks like this:

User

- email
- name

Roles:

 - id
 - name

University(Profile):

 - name
 - short history

Organizatons(Profile):

  - name
  - logo of the brand

Foundation(Profile):

  - name
  - Adminstrative contacts

How can i know a user is bind to which table(foundation, organization or university) and what role does it have in that group(foundation, organization or university)? I thought to create a bridge table like this:

  Group:
    - id
    - name
    - type(University, Foundation, Organization)
  
 Group_members:
   - id
   - roleId
   - groupId
   - userId

But the problem is that i can't create a groups table as data for university, foundation and organization is totally different for each other. So i'll have to create a separate table for each. How can i solve this problem?

Aamir
  • 101
  • 1
  • 12

1 Answers1

2
-- User USR exists.
--
user {USR}
  PK {USR}
-- Role ROL exists.
--
role_ {ROL}
   PK {ROL}

Xorg is a generic term for a university, an organization, or a foundation. Discriminator TYP is used to distinguish between these three.

-- Xorg XOG, of type TYP, named XNM was created
-- (is owned) by user USR.
--
xorg {XOG, TYP, USR, XNM, ...common_cols}
  PK {XOG}
  SK {XOG, TYP}

CHECK TYP in {'U', 'O', 'F'}

FK {USR} REFERENCES user {USR}
-- University (xorg) XOG, of xorg-type TYP = 'U', exists.
--
university {XOG, TYP, ...university_specific_cols}
        PK {XOG}

CHECK TYP = 'U'

FK {XOG, TYP} REFERENCES xorg {XOG, TYP}
-- Organization (xorg) XOG, of xorg-type TYP = 'O', exists.
--
organization {XOG, TYP, ...organization_specific_cols}
          PK {XOG}

CHECK TYP = 'O'

FK {XOG, TYP} REFERENCES xorg {XOG, TYP}
-- Foundation (xorg) XOG, of xorg-type TYP = 'F', exists.
--
organization {XOG, TYP, ...foundation_specific_cols}
          PK {XOG}

CHECK TYP = 'F'

FK {XOG, TYP} REFERENCES xorg {XOG, TYP}
-- User USR is member of xorg XOG, of xorg-type TYP,
-- in role ROL.
--
user_xorg {USR, XOG, TYP, ROL}
       PK {USR, XOG}

      FK1 {XOG, TYP} REFERENCES
     xorg {XOG, TYP}

      FK2 {USR} REFERENCES user  {USR}
      FK3 {ROL} REFERENCES role_ {ROL}

Note:

All attributes (columns) NOT NULL

PK = Primary Key
AK = Alternate Key   (Unique)
SK = Proper Superkey (Unique)
FK = Foreign Key

A word about subtypes. The proper way to implement constraints for subtypes would be to use assertions (CREATE ASSERTION), but it is still not available in major DBs. I am using FKs instead, and as all other substitute methods it is not perfect. People argue a lot, on SO and SE-DBA, what is better. I encourage you to check other methods too.

Damir Sudarevic
  • 21,891
  • 3
  • 47
  • 71