FK制約のルール
タイトルとテキストの最後にある質問に答えるには:
「2つの主キーを参照する1つの外部キーを作成する方法を知りたいのですが。」
それは不可能です。
-
外部キー
> 制約は1つのみを指すことができます テーブルと各テーブルは1つしか持つことができません主キーコード>
制約。 -
または、複数にすることもできます
外部キー
1つを参照する同じ列の制約PRIMARY KEY
それぞれ(異なる)テーブルの。 (めったに役に立ちません。)
ただし 、単一のPKまたはFKができます 複数の列にまたがります。
そして、FKは、PKだけでなく、ターゲット内の明示的に定義された一意の(セットの)列を参照できます。 マニュアル:
複数列のPKまたは一意
制約は、列タイプが一致する複数列のFK制約によってのみ参照できます。
質問すること
UNIQUE
の列リストで同じ列を複数回使用することは許可されていないため またはPRIMARYKEY
制約、 FOREIGN KEY
のターゲットリスト 同じ列を複数回使用することもできません。ただし、ソースで同じ列を複数回使用することを妨げるものは何もありません。 リスト。ここに、あなたが求めていることを実装する可能性があります(しかし、おそらくそうするつもりはありませんでした):
" team_statistics
で テーブルteam_statistics.team_id
matches.team_id
を参照する外部キーである必要があります およびmatches.team_id1
"
(team_id、team_id1)
の組み合わせ テーブル内のmatches
UNIQUE
を定義する必要があります 。 team_statistics.team_id
の値 team =team1
の場合に制限されます テーブル内のmatches
論理的帰結として:
ALTER TABLE matches
ADD constraint matches_teams_groups_uni UNIQUE (team_id, team_id1);
ALTER TABLE team_statistics
ADD constraint team_statistics_team_group fkey
FOREIGN KEY (team_id, team_id) -- same column twice!
REFERENCES matches(team_id, team_id1);
特定の設定では意味があるかもしれませんが、あなたの設定では意味がありません。
おそらく必要なもの
私の知識に基づいた推測では、次のようなものが必要です:
(match_id、team_id)
テーブルteam_statistics
内 どちらかを参照する外部キーである必要があります (match_id、team_id)
または (match_id、team_id1)
テーブル内のmatches
。
そして、それはFK制約と2つのテーブルだけでは不可能です。あなたはできた CHECK
を悪用する 偽のIMMUTABLE
による制約 関数を作成し、 NOT VALID
にします 。この回答の「チェック制約のある安い」の章を参照してください:
しかし、それは高度なトリックであり、信頼性は低くなります。ここでの私の提案ではないので、詳しく説明するつもりはありません。 正規化 することをお勧めします 次のような便利な方法でスキーマを作成します。
CREATE TABLE team (team_id serial PRIMARY KEY
, team text NOT NULL UNIQUE); -- add more attributes for team
CREATE TABLE match (match_id serial PRIMARY KEY); -- add more attributes for match
CREATE TABLE match_team (
match_id int REFERENCES match -- short notation for FK
, team_id int REFERENCES team
, home boolean -- TRUE for home team, FALSE for away team
, innings_score int
-- more attributes of your original "team_statistics"
, PRIMARY KEY (match_id, team_id, home) -- !!! (1st column = match_id)
, UNIQUE (team_id, match_id) -- optional, (1st column = team_id)
);
ホーム
試合のホームチームをマークしますが、PKに含めることにより、試合ごとに最大2チームに制限されます。 。 (PK列は NOT NULL
で定義されています 暗黙的に。)
オプションのUNIQUE
(team_id、match_id)
の制約 チームが自分たちと対戦するのを防ぎます。インデックス列の反転シーケンスを使用することにより(ルールの適用には関係ありません)、これはPKを補完するインデックスも提供します。これは通常も役立ちます。参照:
あなたはできた 別のmatch_team_statistics
を追加します 、ただし、これは match_team
のオプションの1:1拡張機能にすぎません。 今。または、 match_team
に列を追加するだけです。 。
ビューを追加する場合があります 次のような一般的なディスプレイの場合:
CREATE VIEW match_result AS
SELECT m.match_id
, concat_ws(' : ', t1.team, t2.team) AS home_vs_away_team
, concat_ws(' : ', mt1.innings_score, mt2.innings_score) AS result
FROM match m
LEFT JOIN match_team mt1 ON mt1.match_id = m.match_id AND mt1.home
LEFT JOIN team t1 ON t1.team_id = mt1.team_id
LEFT JOIN match_team mt2 ON mt2.match_id = m.match_id AND NOT mt2.home
LEFT JOIN team t2 ON t2.team_id = mt2.team_id;
基本的なアドバイス: