PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

Design de banco de dados para o emparelhamento de imposição de restrições


Não sei se isso pode funcionar no Postgress, mas aqui está uma solução do SQL Server:
CREATE TABLE dbo.Teams(TeamID INT NOT NULL PRIMARY KEY);
GO
CREATE TABLE dbo.Players(PlayerID INT NOT NULL PRIMARY KEY,
  TeamID INT NOT NULL FOREIGN KEY REFERENCES dbo.Teams(TeamID),
  NumberInTeam INT NOT NULL CHECK(NumberInTeam IN (1,2)),
  TeamMateID INT NOT NULL,
  TeamMatesNumberInTeam INT NOT NULL,
-- if NumberInTeam=1 then TeamMatesNumberInTeam must be 2
-- and vise versa
  CHECK(NumberInTeam+TeamMatesNumberInTeam = 3), 
  UNIQUE(TeamID, NumberInTeam),
  UNIQUE(PlayerID, TeamID, NumberInTeam),
  FOREIGN KEY(TeamMateID, TeamID, TeamMatesNumberInTeam)
    REFERENCES dbo.Players(PlayerID, TeamID, NumberInTeam)
);

INSERT INTO dbo.Teams(TeamID) SELECT 1 UNION ALL SELECT 2;
GO

-- você só pode inserir jogadores em pares completos
INSERT INTO dbo.Players(PlayerID, TeamID, NumberInTeam, TeamMateID, TeamMatesNumberInTeam)
SELECT 1,1,1,2,2 UNION ALL
SELECT 2,1,2,1,1;

Você pode tentar inserir um único jogador, ou deletar um jogador de um time, ou inserir mais de dois jogadores por time - tudo falhará devido a um conjunto completo de restrições.

Observação:a prática no SQL Server é nomear explicitamente todas as restrições. Eu não nomeei minhas restrições apenas no caso de não ser compatível com o Postgres.