Defining Two Distinct Relationships Between User Table and Company Table in MySQL

database-designMySQL

A very basic design question here. I would like to build a scalable app and would want to know what's the best way forward.
So in the database there are two tables : users and companies.

users has the following fields:

-id
-name
-company_id
-join_date
-leave_date

companies has the following fields:

-id
-admin_id
-address

I want a 1-to-M between users and companies as one company could have many users, but one user belongs to only one company. Also, I want to have a 1-to-1 on users and companies because one company has one admin and vice versa.
I'm not sure if I am tackling this right. The admin role would basically have more privileges on the system. But I cannot understand if it should be a 1-to-1 or not. Who would the parent be, etc.

Best Answer

To guarantee that a company, which can have many users, can ever have at most one admin, and further guarantee that the user defined as the admin is also a user defined for the same company, create a separate admin table. However, the foreign key definition has to be created in a specific way.

create table Companies(
  ID      int not null auto_increment,
  Name    varchar not null,
  Address varchar,
  primary key( ID )
);

create table Users(
  ID      int not null auto_increment,
  Name    varchar not null,
  primary key( ID )
);

create table CompanyUsers(
  UserID    int not null references Users( ID ),
  CompanyID int not null references Companies( ID ),
  JoinDate  date not null,
  LeaveDate date,
  primary key( UserID ), -- makes this 1-n
  unique( UserID, CompanyID )
);

create table Admins(
    UserID   int not null,
    CompanyID int not null,
    ..., -- other admin-related data
    primary key CompanyID,
    foreign key( UserID, CompanyID ) references CompanyUsers( UserID, CompanyID )
);

At first, the Admins table appears to define a 1-n relationship the same way as the CompanyUsers table. But if you follow the FK relationship through, you will see that it can only support 1-1 relationships.

Technically, you don't need the CompanyUsers table as you can define the company and dates in the Users table. This maintains the 1-n relationship but then it is no longer in 3nf. If you are going to have attributes (JoinDate, LeaveDate) that are dependent on more than the PK (that is, they describe the relationship rather than the user), they should go in a new table.