Dette tigger om ballade. Du vil blive ved med at løbe ind i mindre uforeneligheder. Eller ikke engang bemærke dem før meget senere, når skaden er sket. Lad være med at gøre det. Brug også PostgreSQL lokalt. Det er frit tilgængeligt for stort set alle OS. For en person involveret i et "databasekursusprojekt" er dette en overraskende tåbelighed. Relateret:
Andre råd:
-
Som @Priidu nævnt i kommentarerne , dine begrænsninger for fremmednøgle er baglæns. Dette er ikke til debat, de er simpelthen forkerte .
-
Brug en
serial
i PostgreSQL ellerIDENTITY
kolonne (Postgres 10+) i stedet for SQLiteAUTOINCREMENT
. Se: -
Brug
timestamp
(ellertimestamptz
) i stedet fordatetime
. -
Brug ikke id'er med blandede store og små bogstaver.
-
Brug ikke ikke-beskrivende kolonnenavne som
id
. Nogensinde. Det er et anti-mønster introduceret af halvkloge middleware og ORM'er. Når du slutter dig til et par tabeller, ender du med flere kolonner med navnetid
. Det er aktivt sårende. -
Der er mange navnestile, men de fleste er enige om, at det er bedre at have entalsudtryk som tabelnavne. Det er kortere og mindst lige så intuitivt/logisk.
label
, ikkelabels
.
Alt sammen kunne det se sådan ud:
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
For at slette ubrugte etiketter skal du implementere en trigger . Jeg leverer en anden version, da jeg ikke er tilfreds med den leveret af @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$;
-
Udløserens funktion skal oprettes før udløseren .
-
En simpel
DELETE
kommando kan gøre jobbet. Ingen anden forespørgsel nødvendig - især ingencount(*)
.EXISTS
er billigere. -
Enkelte anførselstegn omkring sprognavnet tolereres, men det er virkelig en identifikator, så bare udelad vrøvlerne:
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();
Der er ingen CREATE OR REPLACE TRIGGER
i PostgreSQL, endnu. Bare CREATE TRIGGER
.