Die einfachste Möglichkeit, dies zu erzwingen, wäre das Hinzufügen eines zweiten Fremdschlüssels zu ticket_type
, der auf die Erweiterungstabelle verweist.
Die Schwierigkeit mit dieser zirkulären Abhängigkeit besteht darin, dass eine INSERT
in eine der Tabellen eine Fremdschlüsseleinschränkung verletzt, bevor Sie die Möglichkeit haben, den anderen Datensatz zu erstellen. Sie können dies vermeiden, indem latente Einschränkungen verwenden, die die Fremdschlüsselprüfung verzögern, bis die Transaktion festgeschrieben:
CREATE TABLE ticket_type (id INT PRIMARY KEY);
CREATE TABLE myplugin_ticket_type_extension (
id INT PRIMARY KEY,
ticket_type_id INT UNIQUE NOT NULL FOREIGN KEY
REFERENCES ticket_type (id)
DEFERRABLE INITIALLY DEFERRED
);
ALTER TABLE ticket_type ADD FOREIGN KEY (id)
REFERENCES myplugin_ticket_type_extension (ticket_type_id)
DEFERRABLE INITIALLY DEFERRED;
BEGIN;
INSERT INTO ticket_type VALUES (1);
INSERT INTO myplugin_ticket_type_extension VALUES (1,1);
COMMIT;
Ein alternativer Ansatz, die eine Überlegung wert sein kann, ist table inheritance zu verwenden:
CREATE TABLE ticket_type (id INT PRIMARY KEY);
CREATE TABLE myplugin_ticket_type_extension (extension_field INT) INHERITS (ticket_type);
INSERT INTO myplugin_ticket_type_extension (id, extension_field) VALUES (1,1);
Datensätze eingefügt in die Erweiterungstabelle wird angezeigt, wenn Sie ticket_type
abfragen, so sollte Ihr Kernmodul nicht betroffen sein. Sie können Einsätze direkt in die ticket_type
Tabelle verhindern, indem ein Trigger hinzufügen, die entweder Block-Einsätze insgesamt konnte (durch Auslösen einer Ausnahme) oder automatisch neue Datensätze in die Erweiterungstabelle umleiten könnte:
CREATE FUNCTION ticket_type_trg() RETURNS TRIGGER AS $$
BEGIN
INSERT INTO myplugin_ticket_type_extension (id) VALUES (new.id);
RETURN NULL;
END
$$
LANGUAGE plpgsql;
CREATE TRIGGER ticket_type_trg
BEFORE INSERT ON ticket_type FOR EACH ROW
EXECUTE PROCEDURE ticket_type_trg();
Was hindert Sie daran, eine Fremdschlüsseleinschränkung zu "ticket_type" hinzuzufügen, die auf die Erweiterungstabelle verweist? –
@NickBarnes Gute Frage. Die Tabelle 'ticket_type' kommt von core. Da 'myplugin' optional ist, darf die initiale Tabelle diese FK-Bedingung nicht haben. Aber ich könnte es in einer Plugin-spezifischen Schemamigration hinzufügen. – guettli