PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Vincoli di chiave esterna nelle relazioni molti-a-molti

Questo è chiedere guai. Continuerai a incorrere in piccole incompatibilità. O nemmeno notarli fino a molto tempo dopo, quando il danno è fatto. Non farlo. Usa PostgreSQL anche localmente. È disponibile gratuitamente per la maggior parte dei sistemi operativi. Per qualcuno coinvolto in un "progetto di corso database" questa è una follia sorprendente. Correlati:

Altri consigli:

Tutto messo insieme, potrebbe assomigliare a questo:

CREATE TABLE IF NOT EXISTS post (
   post_id   serial PRIMARY KEY
 , author_id integer
 , title     text
 , content   text
 , image_url text
 , date      timestamp
);

CREATE TABLE IF NOT EXISTS label (
   label_id  serial PRIMARY KEY
 , name      text UNIQUE
);

CREATE TABLE IF NOT EXISTS label_post(
    post_id  integer REFERENCES post(post_id) ON UPDATE CASCADE ON DELETE CASCADE
  , label_id integer REFERENCES label(label_id) ON UPDATE CASCADE ON DELETE CASCADE
  , PRIMARY KEY (post_id, label_id)
);

Innesco

Per eliminare le etichette non utilizzate, implementa un trigger . Fornisco un'altra versione poiché non sono soddisfatto di quella fornita da @Priidu :

CREATE OR REPLACE FUNCTION f_trg_kill_orphaned_label() 
  RETURNS trigger
  LANGUAGE plpgsql AS
$func$
BEGIN
   DELETE FROM label l
   WHERE  l.label_id = OLD.label_id
   AND    NOT EXISTS (
      SELECT 1 FROM label_post lp
      WHERE  lp.label_id = OLD.label_id
      );
END
$func$;
  • La funzione di attivazione deve essere creato prima il trigger .

  • Un semplice DELETE il comando può fare il lavoro. Nessuna seconda query necessaria, in particolare nessun count(*) . EXISTS è più economico.

  • Le virgolette singole attorno al nome della lingua sono tollerate, ma in realtà è un identificatore, quindi ometti semplicemente le sciocchezze:LANGUAGE plpgsql

CREATE TRIGGER label_post_delaft_kill_orphaned_label
AFTER DELETE ON label_post
FOR EACH ROW EXECUTE PROCEDURE f_trg_kill_orphaned_label();

Non c'è nessun CREATE OR REPLACE TRIGGER in PostgreSQL, ancora. Solo CREATE TRIGGER .