如何在一对多关系中复制另一个 table 的外键
How to replicate foreign key of another table in one to many relationship
我有一个三个 table 结构:tournament
、group
和 team
。 tournament
和 group
table 具有 一对多 关系,并且 group
和 team
具有一对多 关系,如下所示。
如何将 tournament_id
的值从 group
table 复制到 team
table 的 group_tournament_id
中?
我正在寻找一个答案,它将使用像
这样的创建语句来实现这一点
create table team (
id serial primary key,
group_id int references group,
group_tournament_id int references group(tournament_id)
);
当然这行不通,因为为了引用它必须是唯一的,在这种情况下 tournament_id 不是唯一的
我需要一种标准方法来将 tournament_id
的值从 group
复制到 'team' table 的 group_tournament_id
中,每当我插入 group_id inside
团队table
编辑:不再需要在 symfony 中回答,只需 postgreSQL 就可以了
您应该直接使用从 teams
到 tournaments
的引用。使用触发器自动从 groups.
获取适当的引用(但请注意,引用不是必需的,因为您始终可以在查询中从 groups
获取 tournament_id
。我假设此引用是以简化一些查询)。
我稍微修改了 table 的名称和列(group
不能是 table 的名称)。
表:
create table tournaments (
tournament_id serial primary key);
create table groups (
group_id serial primary key,
tournament_id int references tournaments);
create table teams (
team_id serial primary key,
group_id int references groups,
tournament_id int references tournaments);
触发器:
create or replace function before_insert_or_update_on_teams()
returns trigger language plpgsql as $$
begin
new.tournament_id = (
select tournament_id
from groups
where group_id = new.group_id
limit 1);
return new;
end $$;
create trigger before_insert_or_update_on_teams
before insert or update on teams
for each row execute procedure before_insert_or_update_on_teams();
测试:
insert into tournaments values (default), (default);
insert into groups values (default, 2);
insert into teams values (default, 1, null);
select * from teams;
team_id | group_id | tournament_id
---------+----------+---------------
1 | 1 | 2
(1 row)
您可以只使用识别关系:
这会生成 "propagate" 一直向下的密钥,因此您会得到 team.tournament_id
,保证指向与父组相同的锦标赛。
请注意,我使用 group_no
(而不是 group_id
)作为命名约定,表明它不单独标识组,而是与 tournament_id
结合使用。 team_no
.
同上
但这会使插入变得复杂。您不能再让数据库为您的组或团队生成下一个 auto-incremented ID(因为您现在使用值的组合来识别它,而不仅仅是一个值),但您可以轻松地手动完成 - 例如插入 group
时,将 SELECT MAX(group_no) + 1 FROM group WHERE tournament_id = ...
分配给新的 group_no
,对团队也类似。
顺便说一句,如果您仍然需要它们,这可以 除了 surrogate keys(图表中的 id
)之外。
您可以使用 SELECT
来提供 INSERT
或 UPDATE
的值:
INSERT INTO "teams" ("group_id", "tournament_id")
SELECT , "groups"."tournament_id"
FROM "groups" WHERE ("groups"."id" = )
RETURNING "id"
这就是我用来让 Postgres 在没有(不一致的)双重查询的情况下插入外键 ID 的方法(select 来自组,插入组)。
我有一个三个 table 结构:tournament
、group
和 team
。 tournament
和 group
table 具有 一对多 关系,并且 group
和 team
具有一对多 关系,如下所示。
如何将 tournament_id
的值从 group
table 复制到 team
table 的 group_tournament_id
中?
我正在寻找一个答案,它将使用像
这样的创建语句来实现这一点create table team (
id serial primary key,
group_id int references group,
group_tournament_id int references group(tournament_id)
);
当然这行不通,因为为了引用它必须是唯一的,在这种情况下 tournament_id 不是唯一的
我需要一种标准方法来将 tournament_id
的值从 group
复制到 'team' table 的 group_tournament_id
中,每当我插入 group_id inside
团队table
编辑:不再需要在 symfony 中回答,只需 postgreSQL 就可以了
您应该直接使用从 teams
到 tournaments
的引用。使用触发器自动从 groups.
获取适当的引用(但请注意,引用不是必需的,因为您始终可以在查询中从 groups
获取 tournament_id
。我假设此引用是以简化一些查询)。
我稍微修改了 table 的名称和列(group
不能是 table 的名称)。
表:
create table tournaments (
tournament_id serial primary key);
create table groups (
group_id serial primary key,
tournament_id int references tournaments);
create table teams (
team_id serial primary key,
group_id int references groups,
tournament_id int references tournaments);
触发器:
create or replace function before_insert_or_update_on_teams()
returns trigger language plpgsql as $$
begin
new.tournament_id = (
select tournament_id
from groups
where group_id = new.group_id
limit 1);
return new;
end $$;
create trigger before_insert_or_update_on_teams
before insert or update on teams
for each row execute procedure before_insert_or_update_on_teams();
测试:
insert into tournaments values (default), (default);
insert into groups values (default, 2);
insert into teams values (default, 1, null);
select * from teams;
team_id | group_id | tournament_id
---------+----------+---------------
1 | 1 | 2
(1 row)
您可以只使用识别关系:
这会生成 "propagate" 一直向下的密钥,因此您会得到 team.tournament_id
,保证指向与父组相同的锦标赛。
请注意,我使用 group_no
(而不是 group_id
)作为命名约定,表明它不单独标识组,而是与 tournament_id
结合使用。 team_no
.
但这会使插入变得复杂。您不能再让数据库为您的组或团队生成下一个 auto-incremented ID(因为您现在使用值的组合来识别它,而不仅仅是一个值),但您可以轻松地手动完成 - 例如插入 group
时,将 SELECT MAX(group_no) + 1 FROM group WHERE tournament_id = ...
分配给新的 group_no
,对团队也类似。
顺便说一句,如果您仍然需要它们,这可以 除了 surrogate keys(图表中的 id
)之外。
您可以使用 SELECT
来提供 INSERT
或 UPDATE
的值:
INSERT INTO "teams" ("group_id", "tournament_id")
SELECT , "groups"."tournament_id"
FROM "groups" WHERE ("groups"."id" = )
RETURNING "id"
这就是我用来让 Postgres 在没有(不一致的)双重查询的情况下插入外键 ID 的方法(select 来自组,插入组)。