Fremdschlüsselkontrakte in vielen Beziehungen
Wir bauen einen Blog für ein Intro. zu Datenbanken Kursprojekt.
In unserem Blog wollen wir einstellen könnenLabels
aufPosts
. DasLabels
kann nicht für sich existieren, sie tun dies nur, wenn sie mit einem verwandt sindPosts
. Diesen Weg,Labels
die von keinem benutzt werdenPosts
sollte nicht in der Datenbank bleiben.
Mehr als eineLabel
kann zu einer einzigen gehörenPost
und mehr als einePost
kann ein verwendenLabel
.
Wir verwenden sowohl SQLite3 (lokal / testing) als auch PostgreSQL (Deployment).
ImplementierungHier ist die SQL (SQLite3-Variante), mit der wir diese beiden Tabellen zusammen mit der Beziehungstabelle erstellen:
BeiträgeCREATE 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
)
EtikettenCREATE 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 (Beziehung zwischenPost
[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
)
ProblemMit SQLite3,Labels
werden nicht aus der Datenbank gelöscht, wenn ich alle Verweise darauf aus der Datenbank entferneLabelPosts
Tabelle. Ich denke aus dem von Postgres angegebenen Grund, obwohl SQLite die Tabelle ohne Vorwarnung akzeptiert.
PostgreSQL beschwert sich darüberlabelId
ist nicht einzigartig inLabelPosts
Dies ist wahr und auch erforderlich, da es viele zu viele sind:
pq: S: "ERROR" R: "transformFkeyCheckAttrs" L: "6511" C: "42830" F: "tablecmds.c"
M: Es gibt keine eindeutige Einschränkungsübereinstimmung für bestimmte Schlüssel für die referenzierte Tabelle "labelposts".
Also verstehe ich, dass ich meine Einschränkung falsch mache. Allerdings weiß ich nicht, wie ich es richtig machen soll.