13

我有一个三表结构tournamentgroupteam。和表具有一对多关系,tournament并且具有一对多关系,如下所示。groupgroupteam

表结构

如何将表中的值复制到tournament_id表中?groupgroup_tournament_idteam

我正在寻找一个答案,它可以使用 create 语句来实现这一点

create table team (
    id serial primary key, 
    group_id int references group, 
    group_tournament_id int references group(tournament_id)
);

当然这是行不通的,因为为了引用它必须是唯一的,在这种情况下,锦标赛 ID 不是唯一的

当我插入团队时,我需要一种标准方法来将tournament_idfrom的值复制group到“团队”表中group_tournament_idgroup_id insidetable

编辑:不再需要 symfony 中的答案,只需 postgreSQL 就可以了

4

3 回答 3

5

您应该直接使用从teamsto 的引用tournaments。使用触发器自动获取适当的引用groups.(但请注意,引用不是必需的,因为您始终可以tournament_idgroups查询中获取。我假设此引用是为了简化一些查询)。

我稍微修改了表和列的名称(group不能是表的名称)。

表:

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)
于 2017-02-01T11:42:52.063 回答
3

您可以只使用识别关系:

在此处输入图像描述

这会产生一直向下“传播”的密钥,因此您得到的密钥team.tournament_id保证指向与父组相同的锦标赛。

请注意,我使用group_no(not group_id) 作为命名约定,表示它不会单独标识组,而是与tournament_id. 同上team_no

但是,这使插入变得复杂。您不能再让数据库为您的组或团队生成下一个自动递增的 ID(因为您现在使用值的组合来标识它,而不仅仅是一个值),但您可以轻松地手动完成 - 例如在插入时into group,assign SELECT MAX(group_no) + 1 FROM group WHERE tournament_id = ...to new group_no,以及类似的团队。

顺便说一句,如果您仍然需要它们,除了代理键(在您的图表中)之外,还可以这样做。id

于 2017-02-05T08:43:13.600 回答
1

您可以使用 a来使用orSELECT提供值:INSERTUPDATE

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

这就是我用来让 Postgres 在没有(不一致的)双重查询(从组中选择,插入到团队中)的情况下为外键插入 id 的方法。

于 2017-02-08T08:25:21.983 回答