Я пытаюсь построить свою первую схему базы данных Postgres, включающую наследование. Мне известно о проблеме с внешним ключом, о которой говорилось в Внешний ключ PostgreSQL не существует, проблема наследования? . Однако ответы на этот вопрос на самом деле не дали пример для решения, поэтому я придумал свой собственный (вдохновленный http://people.planetpostgresql.org/dfetter/index.php?/archives/51-Partitioning-Is-Such-Sweet-Sorrow.html):
CREATE TABLE a (
id SERIAL PRIMARY KEY INITIALLY DEFERRED,
foo TEXT
);
CREATE TABLE b (
PRIMARY KEY(id),
a_number REAL
) inherits(a);
CREATE TABLE c (
PRIMARY KEY(id),
a_number INTEGER
) inherits(a);
-- SELECT * FROM ONLY a; will always return an empty record.
CREATE TABLE x (
a_id INTEGER NOT NULL,
bar TEXT
);
CREATE TABLE xb (
FOREIGN KEY( a_id ) REFERENCES b INITIALLY DEFERRED
) inherits(x);
CREATE TABLE xc (
FOREIGN KEY( a_id ) REFERENCES c INITIALLY DEFERRED
) inherits(x);
Для выполнения работы INSERT INTO x
я определил следующий триггер:
CREATE FUNCTION marshal_x()
RETURNS TRIGGER
LANGUAGE plpgsql
AS $$
DECLARE
ref_table varchar;
BEGIN
SELECT INTO ref_table p.relname FROM a, pg_class p WHERE a.id = NEW.a_id AND a.tableoid = p.oid;
IF ref_table = 'b'
THEN INSERT INTO xb ( a_id, bar ) VALUES ( NEW.a_id, NEW.bar );
ELSIF ref_table = 'c'
THEN INSERT INTO xc ( a_id, bar ) VALUES ( NEW.a_id, NEW.bar );
END IF;
RETURN NULL;
END;
$$;
CREATE TRIGGER insert_x_trg
BEFORE INSERT ON x
FOR EACH ROW
EXECUTE PROCEDURE marshal_x();
РЕДАКТИРОВАТЬ: Кто-нибудь видит проблемы с этим определением, которые не очевидны для моего неподготовленного глаза?
Предположим, что таблица c
пуста. Будет ли производительность
SELECT * FROM a JOIN x ON a.id= x.a_id;
будет таким же, как
SELECT * FROM b JOIN x ON b.id= x.a_id;
? Большое спасибо заранее.
Isam