2014-12-11 6 views
3

У меня есть четыре таблицы в базе данных PostgreSQL:SQL Constraint на таблицу соединения

  • Company
    • пользователя (с ключом company_id внешней колонки)
    • Местонахождение (с ключом company_id внешней колонны)
    • UserLocations (объединение таблицы, с внешним ключом user_id и LOCATION_ID)

По существу:

  • компания имеет много пользователей и мест
  • пользователь принадлежит к компании и имеет много мест,
  • местоположение принадлежит компании и имеет много пользователей

Я хочу знать, есть ли способ, чтобы база данных ограничивала записи в таблице ассоциации UserLocations таким образом, чтобы ссылочный пользователь и местоположение должны иметь одинаковое значение company_id. Я не хочу, чтобы пользователь из компании A имел место от компании B.

Я могу проверить это на своем уровне приложения (рельсы), но был бы заинтересован в том, чтобы сделать это жестким ограничением уровня базы данных, если эта опция существует.

+0

В реальном мире местоположение может иметь несколько компаний, и пользователь может иметь несколько компаний. –

ответ

2

Один из способов, которым вы можете выполнить это, - это ссылки на внешние ключи и избыточность.

Таким образом, таблица UserLocations будет иметь UserId, LocationId и CompanyId. Затем он будет иметь следующие основные внешние отношения:

foreign key (UserId, CompanyId) references Users(UserId, CompanyId) 
foreign key (LocationId, CompanyId) references Locations(LocationId, CompanyId) 

Конечно, вы должны объявить Users(UserId, CompanyId) и Locations(LocationId, CompanyId) в качестве уникальных ключей для справки. Это немного избыточно, но это гарантирует соответствие компании без создания триггеров.

1

Перекрытие ограничений внешнего ключа - ваш друг.

create table company (
    company_id integer primary key 
); 

-- Reserved words include "user". Better to use identifiers that 
-- are not reserved words. 
create table "user" (
    user_id integer primary key, 
    company_id integer not null references company (company_id), 
    -- Unique constraint lets this be the target of a foreign key reference. 
    unique (user_id, company_id) 
); 

create table location (
    location_id integer primary key, 
    company_id integer not null references company (company_id), 
    unique (location_id, company_id) 
); 

create table user_location (
    user_id integer not null, 
    location_id integer not null, 
    company_id integer not null, 
    -- Not sure what your primary key is here. 

    -- These foreign keys overlap on the column "company_id", so there 
    -- can be only one value for it. 
    foreign key (user_id, company_id) references "user" (user_id, company_id), 
    foreign key (location_id, company_id) references location (location_id, company_id) 
); 
Смежные вопросы