Det här är att tigga om problem. Du kommer att fortsätta stöta på mindre inkompatibiliteter. Eller inte ens märka dem förrän långt senare, när skadan är skedd. Gör det inte. Använd PostgreSQL lokalt också. Det är fritt tillgängligt för nästan alla operativsystem. För någon som är involverad i ett "databaskursprojekt" är detta en överraskande dårskap. Relaterat:
Andra råd:
-
Som @Priidu nämnde i kommentarerna , dina främmande nyckelbegränsningar är bakåtriktade. Detta är inte uppe för debatt, de har helt enkelt fel .
-
I PostgreSQL använd en
serial
ellerIDENTITY
kolumn (Postgres 10+) istället för SQLiteAUTOINCREMENT
. Se: -
Använd
timestamp
(ellertimestamptz
) istället fördatetime
. -
Använd inte identifierare med blandade skiftlägen.
-
Använd inte icke-beskrivande kolumnnamn som
id
. Någonsin. Det är ett antimönster som introducerats av halvvettig middleware och ORM. När du går med i ett par tabeller får du flera kolumner med namnetid
. Det är aktivt sårande. -
Det finns många namngivningsstilar, men de flesta är överens om att det är bättre att ha singulära termer som tabellnamn. Det är kortare och minst lika intuitivt/logiskt.
label
, intelabels
.
Allt tillsammans kan det se ut så här:
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)
);
Trigger
Om du vill ta bort oanvända etiketter implementerar du en utlösare . Jag tillhandahåller en annan version eftersom jag inte är nöjd med den som tillhandahålls av @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$;
-
Utlösarens funktion måste skapas före utlösaren .
-
En enkel
DELETE
kommando kan göra jobbet. Ingen andra fråga behövs - i synnerhet ingencount(*)
.EXISTS
är billigare. -
Enkla citattecken runt språknamnet tolereras, men det är egentligen en identifierare, så utelämna bara nonsensen:
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();
Det finns ingen CREATE OR REPLACE TRIGGER
i PostgreSQL, ännu. Bara CREATE TRIGGER
.