PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

Fremdschlüsselbeschränkungen in Viele-zu-Viele-Beziehungen

Das schreit nach Ärger. Sie werden immer wieder auf kleinere Inkompatibilitäten stoßen. Oder bemerken sie erst viel später, wenn der Schaden angerichtet ist. Tu es nicht. Verwenden Sie PostgreSQL auch lokal. Es ist für die meisten Betriebssysteme frei verfügbar. Für jemanden, der an einem "Datenbankkursprojekt" beteiligt ist, ist dies eine überraschende Dummheit. Verwandte:

Andere Ratschläge:

Alles zusammen könnte so aussehen:

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)
);

Auslöser

Um ungenutzte Labels zu löschen, implementieren Sie einen Trigger . Ich liefere eine andere Version, da ich mit der von @Priidu nicht zufrieden bin :

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$;
  • Die Trigger-Funktion muss vorher erstellt werden der Auslöser .

  • Ein einfaches DELETE Befehl kann die Arbeit erledigen. Keine zweite Abfrage nötig - insbesondere kein count(*) . EXISTS ist billiger.

  • Einfache Anführungszeichen um den Sprachnamen werden toleriert, aber es ist wirklich ein Bezeichner, also lassen Sie einfach den Unsinn weg: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();

Es gibt keinen CREATE OR REPLACE TRIGGER in PostgreSQL, noch. Einfach CREATE TRIGGER .