【问题标题】:guarantee uniqueness of table relationship保证表关系的唯一性
【发布时间】:2017-03-10 20:11:49
【问题描述】:

所以我有一张状态表。

CREATE TABLE public.states(
  state_code  char(2) NOT NULL
);

我有几种不同的方式将这些州分组到区域中,所以我想出了这个模式:

CREATE TABLE public.region_type (
  region_type_name varchar NOT NULL PRIMARY KEY
)
CREATE TABLE public.regions (
  region_id    serial NOT NULL PRIMARY KEY,
  region_type_name varchar NOT NULL ,
  region_name  varchar NOT NULL,
  /* Keys */
  CONSTRAINT regions_region_name_unq
    UNIQUE (region_name),
  CONSTRAINT regions_region_type_fk
    FOREIGN KEY (region_type_name)
    REFERENCES region_type(region_type_name)
)
CREATE TABLE public.region2state (
  region_id    int4 NOT NULL,
  state_code  char(2) NOT NULL
)

现在,这没有给我的一件事是我想保证每个状态只与特定 region_type 的一个区域相关。

例如TX 可以位于“PADD 3”区域(“PADD”类型)和“西南”区域(“内部”类型),但我想保证没有人不小心将 TX 放入 PADD 3 和 PADD 2(均为 PADD 类型)。

我如何保证?

【问题讨论】:

    标签: sql database postgresql postgresql-9.4


    【解决方案1】:

    您可以在region2state 中保证这一点。基本上,您希望每个州在每个地区只出现一次。因此,为此目的,在region2state 中包含区域类型很方便:

    CREATE TABLE public.region2state (
      region_id        int4    NOT NULL,
      region_type_name varchar NOT NULL,
      state_code       char(2) NOT NULL,
    
      constraint unq_r2s_regiontype_statecode unique (region_type_name, state_code),
      constraint fk_r2s_regionid_regiontype foreign key (region_id, region_type_name) references regions(region_id, region_type_name)
    );
    

    对于最终的外键约束,您需要在 regions 上的 (region_id, region_type_name) 上的唯一键。虽然这是多余的(region_id 已经是唯一的),但它确保了两个表之间的区域和类型兼容。

    【讨论】:

    • 所以需要在关系表中复制类型? region_id 和 region_type_name 上的 FK/唯一键保证不会出错。
    【解决方案2】:

    最好的办法是让您的多对多表包含该类型。这样您就可以将主键设置为整行:

    CREATE TABLE public.region2state (
      region_id        int4    NOT NULL,
      region_type_name varchar NOT NULL,
      state_code       char(2) NOT NULL,
    
      primary key(region_id, region_type_name, state_code)
    );
    

    就我个人而言,我会将 region_type 设置为一个整数 id 以及一个名称,但这是你的决定。

    【讨论】:

    • 这行不通。我可以在这个模式中有这两行(为清楚起见,删除了 ID:PADD 3 PADD TX PADD 2 PADD TX
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多