下面是两个模式,我相信它会获得相同的结果,即m:n与默认/首选值选项的关系。有没有理由使用其中一个?
架构#1
CREATE TABLE people (
id serial,
primary key (id)
);
CREATE TABLE names (
id serial,
first_name text not null,
last_name text not null,
primary key (id)
);
CREATE TABLE person_has_name (
person_id integer not null references people (id),
name_id integer not null references names (id),
is_default boolean not null default false,
primary key (person_id, name_id)
);
架构#2
CREATE TABLE people (
id serial,
default_name_id integer references names (id),
primary key (id)
);
-- this table has not changed
CREATE TABLE names (
id serial,
first_name text not null,
last_name text not null,
primary key (id)
);
CREATE TABLE person_has_name (
person_id integer not null references people (id),
name_id integer not null references names (id),
primary key (person_id, name_id)
);
答案 0 :(得分:1)
让我们分析一下:
name
设置为默认值,但不要阻止您将某些不相关的名称设置为默认name
。 我向你(对你的僵尸用户)建议解决数学问题的第三个模式:
CREATE TABLE people (
id serial,
default_name_id integer ,
primary key (id),
constraint default_person_name_fk --<--HERE
foreign key (id, default_name_id)
references person_has_name (person_id, name_id)
);
-- this table has not changed
CREATE TABLE names (
id serial,
first_name text not null,
last_name text not null,
primary key (id)
);
CREATE TABLE person_has_name (
person_id integer not null references people (id),
name_id integer not null references names (id),
primary key (person_id, name_id)
);
对延迟感到抱歉和抱歉,我迟到了;)
答案 1 :(得分:0)
使用第二个架构,您无法在不知道其名称的情况下添加人员。只要这是可以的(即你知道无论什么时候添加一个人,他们都必须透露他们的名字),那么我会说这些模式中的任何一个都很好,并且模式#2甚至可能在您只需要查询默认名称的方案。
答案 2 :(得分:0)
我不会使用这两个。
解决方案1不会阻止您拥有2个人的默认名称。
解决方案2不会阻止具有默认名称的人不是他的。您可以将外键从default_name_id references names(id)
更改为(person_id, default_name_id) references person_has_name(person_id, name_id)
,但之后您将获得循环引用,这是另一个难以解决的问题。
你可以使用它,类似于你的第二个解决方案:
CREATE TABLE people (
id serial,
--- no default_name_id as foreign key here
primary key (id)
);
CREATE TABLE names (
id serial,
first_name text not null,
last_name text not null,
primary key (id)
);
CREATE TABLE person_has_name (
person_id integer not null references people (id),
name_id integer not null references names (id),
primary key (person_id, name_id)
);
使用此额外表格,对于那些具有默认名称的人:
CREATE TABLE person_default_name (
person_id integer not null,
name_id integer not null,
primary key (person_id),
foreign key (person_id, name_id)
references person_has_name (person_id, name_id)
);