【问题标题】:SQL Constraint on join table连接表上的 SQL 约束
【发布时间】:2020-04-29 23:26:55
【问题描述】:

我在 PostgreSQL 数据库中有四个表:

  • Company
  • User(带有外键列company_id)
  • Location(带有外键列company_id)
  • UserLocations(关联表,外键列 user_id 和 location_id)

基本上:

  • 一家公司有许多用户和位置
  • 一个用户属于一个公司并且有很多位置
  • 某个位置属于一家公司并拥有许多用户

我想知道数据库是否有办法限制 UserLocations 关联表中的条目,以使引用的用户和位置必须具有相同的 company_id 值。我不希望 A 公司的用户拥有 B 公司的位置。

我可以在我的应用程序层 (rails) 进行检查,但如果该选项存在,我有兴趣将其设为硬数据库级别约束。

【问题讨论】:

  • 在现实世界中,一个位置可以有好几家公司,而一个用户可以有好几家公司。

标签: sql postgresql


【解决方案1】:

实现此目的的一种方法是使用外键引用和冗余。

因此,UserLocations 表将具有 UserIdLocationIdCompanyId。然后它将具有以下外键关系:

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

当然,您必须将Users(UserId, CompanyId)Locations(LocationId, CompanyId) 声明为引用的唯一键。这有点多余,但它确实保证了与公司的匹配而不创建触发器。

【讨论】:

    【解决方案2】:

    重叠的外键约束是你的朋友。

    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)
    );
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-10-23
      • 1970-01-01
      • 1970-01-01
      • 2019-01-14
      • 1970-01-01
      • 2021-01-10
      • 1970-01-01
      相关资源
      最近更新 更多