Klucze obce w relacjach wiele do wielu
Budujemy bloga na intro. do projektu kursu bazy danych.
W naszym blogu chcemy mieć możliwość ustawieniaLabels
naPosts
. TheLabels
nie mogą istnieć samodzielnie, robią to tylko wtedy, gdy są powiązane zPosts
. Tą drogą,Labels
które nie są używane przez nikogoPosts
nie powinien pozostać w bazie danych.
Więcej niż jedenLabel
może należeć do jednegoPost
i więcej niż jedenPost
może użyć aLabel
.
Używamy zarówno SQLite3 (lokalnie / testowanie), jak i PostgreSQL (wdrożenie).
RealizacjaOto SQL (smak SQLite3), którego używamy do tworzenia tych dwóch tabel, wraz z tabelą relacji:
PostyCREATE TABLE IF NOT EXISTS Posts(
id INTEGER PRIMARY KEY AUTOINCREMENT,
authorId INTEGER,
title VARCHAR(255),
content TEXT,
imageURL VARCHAR(255),
date DATETIME,
FOREIGN KEY (authorId) REFERENCES Authors(id) ON DELETE SET NULL
)
EtykietyCREATE TABLE IF NOT EXISTS Labels(
id INTEGER PRIMARY KEY AUTOINCREMENT,
name VARCHAR(255) UNIQUE,
-- This is not working:
FOREIGN KEY (id) REFERENCES LabelPosts(labelId) ON DELETE CASCADE
)
LabelPosts (relacja międzyPost
[1 .. *] - *Label
)
CREATE TABLE IF NOT EXISTS LabelPosts(
postId INTEGER,
labelId INTEGER,
PRIMARY KEY (postId, labelId),
FOREIGN KEY (postId) REFERENCES Posts(id) ON DELETE CASCADE
)
ProblemKorzystanie z SQLite3,Labels
nie są usuwane z bazy danych, gdy usuwam wszystkie odwołania do niej zLabelPosts
stół. Myślę, że z powodów podanych przez Postgres, mimo że SQLite akceptuje tabelę bez ostrzeżenia.
PostgreSQL narzeka na tolabelId
nie jest unikalny wewnątrzLabelPosts
, co jest prawdą, a także wymagane, ponieważ jest wiele do wielu:
pq: S: "BŁĄD" R: "transformFkeyCheckAttrs" L: "6511" C: "42830" F: "tablecmds.c"
M: „nie ma unikalnego ograniczenia pasującego do podanych kluczy dla tabeli, do której istnieją odwołania” „posterposts”
Rozumiem więc, że źle robię swoje ograniczenia. Nie wiem jednak, jak to zrobić poprawnie.