PostgreSQL で継承したテーブルのキーを参照する
PostgreSQL 9.3.1 で確認。
まず実験に使うテーブルを作る。tbl_vips が tbl_users を継承している。
CREATE TABLE tbl_users ( id serial PRIMARY KEY , name varchar(64) ); CREATE TABLE tbl_vips ( asset integer ) INHERITS (tbl_users);
使ってみる。
INSERT INTO tbl_users (name) VALUES ('Terry'); INSERT INTO tbl_users (name) VALUES ('Bobby'); INSERT INTO tbl_vips (name, asset) VALUES ('Dolly', 20000); INSERT INTO tbl_vips (name, asset) VALUES ('Betty', 32000); SELECT * FROM tbl_users; ... SELECT * FROM tbl_vips; ...
ここで、次のような bl_vips を参照するテーブルを作ろうとするとエラーになる。
CREATE TABLE tbl_vip_options ( id serial PRIMARY KEY , vip_id integer REFERENCES tbl_vips (id) ON DELETE CASCADE , kani integer DEFAULT 0 , uni integer DEFAULT 0 ); ERROR: there is no unique constraint matching given keys for referenced table "tbl_vips"
エラーメッセージから tbl_vips の主キー id に UNIQUE 制約を付与してやればよいと推測できる。
ALTER TABLE tbl_vips ADD UNIQUE (id);
新規でテーブルを作る場合は次のようにすればよい。
CREATE TABLE tbl_vips ( asset integer , UNIQUE (id) ) INHERITS (tbl_users);
こうしてから再び tbl_vip_options を作ると、今度はうまくいった。
INSERT INTO tbl_vip_options (vip_id, kani, uni) VALUES (3, 1, 1); INSERT INTO tbl_vip_options (vip_id, kani, uni) VALUES (4, 1, 1); SELECT u.name, o.kani, o.uni FROM tbl_vip_options AS o LEFT OUTER JOIN tbl_vips AS u ON (u.id = o.vip_id);
問題発覚
ところが REFERENCES tbl_users (id) と、親のテーブルを指定しようとするとうまくいかない。tbl_users へ追加したデータは問題ないが、 tbl_vips のデータだとエラーになる。
調べていると Wikipedia にこんな記述を見つけた。
親テーブルに対する列の追加やCHECK制約の定義は自動的に子テーブルにも反映されるが、外部キーや一意性制約は継承をサポートしていない。
http://ja.wikipedia.org/wiki/PostgreSQL
どうやらこの方法には使えないようだ。別テーブルで管理する方法に切り替えよう。