PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

Restrições de chave estrangeira em relacionamentos muitos-para-muitos


Isso é implorar por problemas. Você continuará se deparando com pequenas incompatibilidades. Ou nem mesmo notá-los até muito mais tarde, quando o dano estiver feito. Não faça isso. Use o PostgreSQL localmente também. Está disponível gratuitamente para quase todos os sistemas operacionais. Para alguém envolvido em um "projeto de curso de banco de dados" isso é uma loucura surpreendente. Relacionado:

Outros conselhos:

Tudo junto, pode ficar assim:
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)
);

Acionador


Para excluir rótulos não utilizados, implemente um gatilho . Forneço outra versão, pois não estou satisfeito com a fornecida por @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$;

  • A função do gatilho deve ser criado antes o gatilho .

  • Um simples DELETE comando pode fazer o trabalho. Nenhuma segunda consulta necessária - em particular, sem count(*) . EXISTS é mais barato.

  • Aspas simples ao redor do nome do idioma são toleradas, mas na verdade é um identificador, então apenas omita o absurdo: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();

Não há CREATE OR REPLACE TRIGGER no PostgreSQL, ainda. Basta CREATE TRIGGER .