如何在一对多关系中复制另一个 table 的外键

How to replicate foreign key of another table in one to many relationship

我有一个三个 table 结构:tournamentgroupteamtournamentgroup table 具有 一对多 关系,并且 groupteam 具有一对多 关系,如下所示。

如何将 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 就可以了

您应该直接使用从 teamstournaments 的引用。使用触发器自动从 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 来提供 INSERTUPDATE 的值:

INSERT INTO "teams" ("group_id", "tournament_id")
SELECT , "groups"."tournament_id"
  FROM "groups" WHERE ("groups"."id" = )
RETURNING "id"

这就是我用来让 Postgres 在没有(不一致的)双重查询的情况下插入外键 ID 的方法(select 来自组,插入组)。