Esto está pidiendo problemas. Te seguirás encontrando con incompatibilidades menores. O ni siquiera notarlo hasta mucho más tarde, cuando el daño ya está hecho. No lo hagas. Utilice PostgreSQL localmente también. Está disponible gratuitamente para la mayoría de los sistemas operativos. Para alguien involucrado en un "proyecto de curso de bases de datos", esto es una locura sorprendente. Relacionado:
Otros consejos:
-
Como @Priidu mencionado en los comentarios , sus restricciones de clave externa están al revés. Esto no está en debate, están simplemente equivocados .
-
En PostgreSQL use un
serial
oIDENTITY
columna (Postgres 10+) en lugar de SQLiteAUTOINCREMENT
. Ver: -
Use
timestamp
(otimestamptz
) en lugar dedatetime
. -
No utilice identificadores de mayúsculas y minúsculas.
-
No use nombres de columna no descriptivos como
id
. Alguna vez. Ese es un antipatrón introducido por middleware y ORM medio tontos. Cuando te unes a un par de tablas, terminas con múltiples columnas del nombreid
. Eso es activamente hiriente. -
Hay muchos estilos de nombres, pero la mayoría está de acuerdo en que es mejor tener términos singulares como nombres de tablas. Es más corto y al menos tan intuitivo/lógico.
label
, nolabels
.
Todo junto, podría verse así:
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)
);
Disparador
Para eliminar etiquetas no utilizadas, implemente un activador . Proporciono otra versión ya que no estoy contento con la proporcionada 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$;
-
La función del disparador se debe crear antes el gatillo .
-
Un simple
DELETE
comando puede hacer el trabajo. No se necesita una segunda consulta, en particular, nocount(*)
.EXISTS
es más barato. -
Se toleran las comillas simples alrededor del nombre del idioma, pero en realidad es un identificador, así que simplemente omita las tonterías:
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();
No hay CREATE OR REPLACE TRIGGER
en PostgreSQL, todavía. Simplemente CREATE TRIGGER
.