ALTER TABLE で足した 3 表の輪
3 つの表を作ったあと、ALTER TABLE で外部キーを足して a から b、b から c、c から a の輪を作る例です。後から足した外部キーも読み取れることを確かめます。
入力
SQL
CREATE TABLE a (id int, b_id int); CREATE TABLE b (id int, c_id int); CREATE TABLE c (id int, a_id int); ALTER TABLE a ADD FOREIGN KEY (b_id) REFERENCES b (id); ALTER TABLE b ADD FOREIGN KEY (c_id) REFERENCES c (id); ALTER TABLE c ADD CONSTRAINT fk_c FOREIGN KEY (a_id) REFERENCES a (id);
結果
エラー 0 件・警告 1 件・情報 0 件
指摘(エラー・警告・情報)
- 警告 4 行目 a・b・c の外部キーが循環している候補です(a(b_id) → b、b(c_id) → c、c(a_id) → a)。外部キーは参照先の行が存在していることを求めるため(CREATE TABLE 文書の REFERENCES)、どの表から作り・入れるかが決まらなくなります。一部の辺は NULL 許可の列または DEFERRABLE のため、緩和できる可能性があります。「候補」の検出であり、実際の登録順は業務の流れで確認してください。
| 表の数 | 3 個 |
|---|---|
| 外部キーの数 | 3 本 |
| 複数の表にまたがる循環 | 1 組 |
| 自己参照 | 0 表 |
循環の候補
| # | 循環に含まれる表 | 参照の向き(子 → 親) | 緩和の見込み |
|---|---|---|---|
| 1 | a ⇄ b ⇄ c | a(b_id) → b / b(c_id) → c / c(a_id) → a | 緩和できる可能性あり: a(b_id) → b(列が NULL 許可)、b(c_id) → c(列が NULL 許可)、c(a_id) → a(列が NULL 許可) |
検算(この結果になる理由)
ALTER TABLE ... ADD FOREIGN KEY の 3 本で a → b → c → a の輪ができ、3 表が 1 つの循環になります。3 つの参照列はどれも NULL を許可するため、緩和できる可能性ありと表示されます。
判定の根拠は仕様と根拠に、仕様の出典とともにまとめています。自分の入力で試すにはツールをお使いください。
このツールの制約
- 完全な SQL の構文解析はしません。貼られていない表の参照は先をたどれず、循環を見逃すことがあります(その旨を情報で示します)。
- 「候補」の検出です。業務の流れ(どの表に先にデータが入るか)までは判定しません。
- 自己参照(階層構造の親子)は多くの設計で普通の形のため、複数の表にまたがる循環とは区別して情報で示します。
- CREATE TABLE ... AS などの列定義のない形は読みません。ALTER TABLE は ADD [CONSTRAINT] FOREIGN KEY だけを読みます。
ご利用にあたって
- 結果は字句の読み取りにもとづく確認で、実際のデータベースでの解釈を保証するものではありません。
- ドキュメントは PostgreSQL License で公開されています。このサイトはその内容を要約して参照しており、転載はしていません。