保证表关系的唯一性

时间:2017-03-10 20:11:50

标签: sql database postgresql postgresql-9.4

所以我有一张州表。

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的一个区域相关。

E.G。 TX可以在“PADD 3”区域(类型为“PADD”)和“西南”区域(“内部”类型),但我想保证没有人意外地将TX放入PADD 3和PADD 2(均为PADD型)。

我如何保证?

2 个答案:

答案 0 :(得分: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已经是唯一的),但它确保区域和类型在两个表之间是兼容的。

答案 1 :(得分:-1)

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

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以及一个名字,但这是你的电话。