Isso é implorar por problemas. Você continuará se deparando com pequenas incompatibilidades. Ou nem mesmo notá-los até muito mais tarde, quando o dano estiver feito. Não faça isso. Use o PostgreSQL localmente também. Está disponível gratuitamente para quase todos os sistemas operacionais. Para alguém envolvido em um "projeto de curso de banco de dados" isso é uma loucura surpreendente. Relacionado:
Outros conselhos:
-
Como @Priidu mencionou nos comentários , suas restrições de chave estrangeira estão invertidas. Isso não está em debate, eles estão simplesmente errados .
-
No PostgreSQL use umserial
ouIDENTITY
coluna (Postgres 10+) em vez de SQLiteAUTOINCREMENT
. Ver:
-
Usetimestamp
(outimestamptz
) em vez dedatetime
.
-
Não use identificadores de maiúsculas e minúsculas.
-
Não use nomes de coluna não descritivos comoid
. Sempre. Esse é um antipadrão introduzido por middleware e ORMs. Quando você junta algumas tabelas, você acaba com várias colunas com o nomeid
. Isso é ativamente doloroso.
-
Existem muitos estilos de nomenclatura, mas a maioria concorda que é melhor ter termos singulares como nomes de tabelas. É mais curto e pelo menos tão intuitivo/lógico.label
, nãolabels
.
Tudo junto, pode ficar assim:
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)
);
Acionador
Para excluir rótulos não utilizados, implemente um gatilho . Forneço outra versão, pois não estou satisfeito com a fornecida 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$;
-
A função do gatilho deve ser criado antes o gatilho .
-
Um simplesDELETE
comando pode fazer o trabalho. Nenhuma segunda consulta necessária - em particular, semcount(*)
.EXISTS
é mais barato.
-
Aspas simples ao redor do nome do idioma são toleradas, mas na verdade é um identificador, então apenas omita o absurdo: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();
Não há
CREATE OR REPLACE TRIGGER
no PostgreSQL, ainda. Basta CREATE TRIGGER
.