PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Contraintes de clé étrangère dans les relations plusieurs-à-plusieurs

C'est demander des ennuis. Vous continuerez à rencontrer des incompatibilités mineures. Ou même pas les remarquer jusqu'à bien plus tard, lorsque le mal est fait. Ne le faites pas. Utilisez également PostgreSQL localement. Il est disponible gratuitement pour la plupart des systèmes d'exploitation. Pour quelqu'un impliqué dans un "projet de cours sur les bases de données", c'est une folie surprenante. Connexe :

Autre conseil :

Tout assemblé, cela pourrait ressembler à ceci :

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

Déclencheur

Pour supprimer les libellés inutilisés, mettez en œuvre un déclencheur . Je fournis une autre version car je ne suis pas satisfait de celui fourni par @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 fonction de déclenchement doit être créé avant le déclencheur .

  • Un simple DELETE la commande peut faire le travail. Aucune deuxième requête nécessaire - en particulier pas de count(*) . EXISTS est moins cher.

  • Les guillemets simples autour du nom de la langue sont tolérés, mais c'est vraiment un identifiant, alors omettez simplement le non-sens :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();

Il n'y a pas de CREATE OR REPLACE TRIGGER dans PostgreSQL, pour le moment. Juste CREATE TRIGGER .