Il modo più semplice per imporre ciò è aggiungere una seconda chiave esterna a ticket_type
che fa riferimento alla tabella di estensione.
La difficoltà con questa dipendenza circolare è che un INSERT
in entrambe le tabelle viola un vincolo di chiave esterna, prima di avere la possibilità di creare l'altro record. È possibile evitare questo utilizzando i vincoli anticipate, che ritarderà il controllo della chiave estera fino a quando la transazione si impegna:
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;
Un approccio alternativo che può essere opportuno prendere in considerazione è quello di utilizzare table inheritance:
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);
record inseriti nella tabella di estensione verrà visualizzato quando si esegue una query su ticket_type
, pertanto il modulo principale non deve essere modificato. È possibile impedire inserti direttamente nella tabella ticket_type
aggiungendo un trigger, che potrebbe o blocchi inseriti complessivamente (alzando un'eccezione), o potrebbe reindirizzare automaticamente nuovi record alla tabella estensione:
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();
fonte
2016-04-20 08:17:35
Cosa ti impedisce di aggiungere un vincolo di chiave esterna a 'ticket_type' facendo riferimento alla tabella di estensione? –
@NickBarnes Buona domanda. La tabella 'ticket_type' viene dal core. Poiché 'myplugin' è facoltativo, la tabella iniziale non deve avere questo vincolo FK. Ma potrei aggiungerlo in una migrazione specifica dello schema di plugin. – guettli