Това е молба за неприятности. Ще продължите да се натъквате на дребни несъвместимости. Или дори не ги забелязвайте до много по-късно, когато щетите са нанесени. Не го правете. Използвайте и PostgreSQL локално. Той е свободно достъпен за почти всяка ОС. За някой, участващ в "курсов проект за бази данни", това е изненадваща глупост. Свързани:
Други съвети:
-
Както @Priidu спомена в коментарите , вашите ограничения за външен ключ са обратно. Това не подлежи на дебат, те просто грешат .
-
В PostgreSQL използвайте
serial
илиIDENTITY
колона (Postgres 10+) вместо SQLiteAUTOINCREMENT
. Вижте: -
Използвайте
timestamp
(илиtimestamptz
) вместоdatetime
. -
Не използвайте идентификатори със смесен регистър.
-
Не използвайте неописателни имена на колони като
id
. някога. Това е анти-модел, въведен от полуостроумен мидълуер и ORM. Когато се присъедините към няколко таблици, вие завършвате с множество колони с иметоid
. Това е активно нараняващо. -
Има много стилове на именуване, но повечето са съгласни, че е по-добре да има единични термини като имена на таблици. Той е по-кратък и поне толкова интуитивен/логичен.
label
, а неlabels
.
Всичко взето заедно може да изглежда така:
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)
);
Задействане
За да изтриете неизползваните етикети, приложете тригер . Предоставям друга версия, тъй като не съм доволен от тази, предоставена от @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$;
-
Задействащата функция трябва да се създаде преди спусъка .
-
Просто
DELETE
команда може да свърши работа. Не е необходима втора заявка - по-специално неcount(*)
.EXISTS
е по-евтино. -
Единичните кавички около името на езика се толерират, но това наистина е идентификатор, така че просто пропуснете глупостите:
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();
Няма CREATE OR REPLACE TRIGGER
в PostgreSQL, все още. Просто CREATE TRIGGER
.