Non so se questo può funzionare su Postgress, ma ecco una soluzione di 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
-- puoi inserire solo giocatori a coppie complete
INSERT INTO dbo.Players(PlayerID, TeamID, NumberInTeam, TeamMateID, TeamMatesNumberInTeam)
SELECT 1,1,1,2,2 UNION ALL
SELECT 2,1,2,1,1;
Puoi provare a inserire un singolo giocatore, a eliminare un giocatore da una squadra o a inserire più di due giocatori per squadra:tutto fallirà a causa di una serie completa di vincoli.
Nota:la pratica in SQL Server è di nominare in modo esplicito tutti i vincoli. Non ho nominato i miei vincoli nel caso in cui non fosse compatibile con Postgres.