Frage

I have the following tables:

users:
  - id
  - name
  - user_type_id (references id on user_types)

neighborhoods:
  - id
  - name

homes:
  - id
  - house_number
  - neighborhood_id (references id on neighborhoods)

user_types:
  - id
  - label

The available user_types are resident, neighborhood_admin, super_admin. Each type of user has access to different parts of the system. Only residents must have a relationship with the homes table.

I was thinking adding a pivot table like:

residents:
  - user_id (references id on users)
  - home_id (references id on home)

but I'm not sure if this approach is correct. I've used pivot tables for many-to-many relationships only. Also, using code I would have to check the user_type before assigning a home, but I could just as easily assign a home to a super_admin if I'm not careful.

How can I make the database enforce this restriction so that it doesn't have to be done through code?

UPDATE: I forgot to add, neighborhood_admins must be assigned to a neighborhood. I could add the following table:

neighborhood_admins:
   - user_id (references id on users)
   - neighborhood_id (references id on neighborhoods)

But this creates a problem. The users table now has two different relationships to the neighborhoods table; if the user is a neighborhood_admin, then the relationship is obtained from the pivot table neighborhood_admin but if the user is a resident, then we must first obtain the home relationship and then the home's neighborhood.

I'm thinking I might as well just add a neighborhood_id column to the users table and be done with it, but I don't like those relationship triangles. Also, that column would be null for super_admins so it couldn't be a foreign key.

War es hilfreich?

Lösung

In most RDBMSs you'll have the ability to set-up column conditionals, which are useful for cases like this. Say your user types are 1, 2 and 3 (res, admin, super respectively). You can set users this way:

CREATE TABLE users (
  id serial NOT NULL PRIMARY KEY,
  name varchar(100) NOT NULL,
  user_type_id int NOT NULL REFERENCES user_types,
  home_id int NULL REFERENCES homes,
  -- a resident must have a home, a non-resident cannot have a home
  CHECK ((user_type_id = 1 AND home_id IS NOT NULL) OR
         (user_type_id <> 1 AND home_id IS NULL))
);
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit dba.stackexchange
scroll top