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:
-
Come @Priidu menzionato nei commenti , i tuoi vincoli di chiave esterna sono arretrati. Questo non è in discussione, sono semplicemente sbagliati .
-
In PostgreSQL usa un
serial
oIDENTITY
colonna (Postgres 10+) invece di SQLiteAUTOINCREMENT
. Vedi: -
Usa
timestamp
(otimestamptz
) invece didatetime
. -
Non utilizzare identificatori di maiuscole e minuscole misti.
-
Non utilizzare nomi di colonna non descrittivi come
id
. Mai. Questo è un anti-pattern introdotto da middleware e ORM half-wit. Quando ti unisci a un paio di tabelle ti ritrovi con più colonne con il nomeid
. È attivamente dannoso. -
Esistono molti stili di denominazione, ma la maggior parte concorda sul fatto che è meglio avere termini singolari come nomi di tabelle. È più breve e almeno altrettanto intuitivo / logico.
label
, nonlabels
.
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 nessuncount(*)
.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
.