Warum benötigen ein CONSTRAINT auf Tabellen-Ebene einen Bezeichner?
Hallo zusammen,
ich lerne gerade SQL und habe eine Frage zu den CONSTRAINT 's. Im Buch (Einstieg in SQL) wurde zunächst der einfache Fall besprochen, CONSTRAINT auf Spalten-Ebene um z.B. den PRIMARY KEY zu definieren:
Alles verstanden. Im weiteren Verlauf wird dann der CONSTRAINT auf Tabellen-Ebene definiert:
Wenn ich das richtig verstehe macht man den CONSTRAINT auf Tabellen-Ebene hauptsächlich dann wenn mehrere Spalten mit einbezogen werden, richtig? Vermutlich auch da das Statement auch übersichtlicher zu lesen ist.
Auf Tabellen-Ebene bekommt der CONSTRAINT immer einen Bezeichner wie in diesem Beispiel "pk_dienstwagenid". Dessen Sinn bzw. Notwendigkeit ist mir nicht so klar. Wie und wo wird der später verwendet bzw. was ist der Sinn davon?
Hoffe die Fragestellung ist halbwegs verständlich.
Beste Grüße
pixel24
ich lerne gerade SQL und habe eine Frage zu den CONSTRAINT 's. Im Buch (Einstieg in SQL) wurde zunächst der einfache Fall besprochen, CONSTRAINT auf Spalten-Ebene um z.B. den PRIMARY KEY zu definieren:
CREATE TABLE dienstwagen(
dienstwagenid SMALLINT PRIMARY KEY,
kennzeichen CHAR(9) NOT NULL,
erstzulassung DATE NOT NULL,
...
);
Alles verstanden. Im weiteren Verlauf wird dann der CONSTRAINT auf Tabellen-Ebene definiert:
CREATE TABLE dienstwagen(
dienstwagenid SMALLINT,
kennzeichen CHAR(9) NOT NULL,
erstzulassung DATE NOT NULL,
...
CONSTRAINT pk_dienstwagenid PRIMARY KEY (dienstwagenid)
);
Wenn ich das richtig verstehe macht man den CONSTRAINT auf Tabellen-Ebene hauptsächlich dann wenn mehrere Spalten mit einbezogen werden, richtig? Vermutlich auch da das Statement auch übersichtlicher zu lesen ist.
Auf Tabellen-Ebene bekommt der CONSTRAINT immer einen Bezeichner wie in diesem Beispiel "pk_dienstwagenid". Dessen Sinn bzw. Notwendigkeit ist mir nicht so klar. Wie und wo wird der später verwendet bzw. was ist der Sinn davon?
Hoffe die Fragestellung ist halbwegs verständlich.
Beste Grüße
pixel24
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 7706146831
Url: https://administrator.de/contentid/7706146831
Ausgedruckt am: 25.11.2024 um 04:11 Uhr
4 Kommentare
Neuester Kommentar
Der offensichtlichste Grund: Alles muss eindeutig sein. Wenn du mehrere Constraints auf einer Tabelle hast, muss der SQL-Server diese eindeutig identifizieren und auseinanderhalten können. Schon alleine, um einen Constraint später zu bearbeiten oder zu löschen. Wenn du eine Constraint Violation hast, teilt dir der Server darüber ebenfalls mit, welcher Constraint gerade deine Datenänderungen verhindert.
Der andere Grund: Du kannst, abhängig von der eingesetzten Software, auch Trigger oder Functions haben, die explizit durch eine Constraint Violation getriggert werden. Auch hier musst du dann natürlich eindeutig den Constraint benennen können, der den Trigger auslösen soll.
Das genannte Beispiel ist ehrlich gesagt auch ein bisschen dämlich. Ein Primärschlüssel ist ja nunmal prinzipbedingt eindeutig und immer vorhanden, da kann ein Constraint wenig verbessern.
Ein besseres Beispiel für Constraints wäre IMHO:
Wir nehmen jetzt eine weitere Tabelle, in der wir Mitarbeiter verwalten und ggf. einen Dienstwagen zuordnen.
Das wäre dann:
Das gibt uns eine Reihe von Problemen:
Ein Dienstwagen kann mehreren Mitarbeitern zugeordnet sein, es können Dienstwagen zugewiesen werden die nicht existieren und wenn ich einen Dienstwagen lösche, bleibt er dem Mitarbeiter weiter zugewiesen.
Das kann man mit Constraints reparieren:
Durch den Constraint "unique_dienstwagenid" (gut, dass wir ihn beim Namen referenzieren können!) sorgen wir dafür, dass ein Dienstwagen nur einem Mitarbeiter gleichzeitig zugewiesen ist.
Mit dem Constraint "fk_dienstwagen" sorgen wir dafür, dass der Dienstwagen nicht gelöscht werden kann, wenn noch ein Datensatz auf ihn referenziert.
Wenn du jetzt versuchst einen Dienstwagen zu löschen, wird dir der SQL-Server sagen dass es eine Constraint Violation gibt und "fk_dienstwagen" dich daran hindert, Datensätze zu löschen.
Und dafür brauchst du die eindeutigen Namen
Der andere Grund: Du kannst, abhängig von der eingesetzten Software, auch Trigger oder Functions haben, die explizit durch eine Constraint Violation getriggert werden. Auch hier musst du dann natürlich eindeutig den Constraint benennen können, der den Trigger auslösen soll.
Das genannte Beispiel ist ehrlich gesagt auch ein bisschen dämlich. Ein Primärschlüssel ist ja nunmal prinzipbedingt eindeutig und immer vorhanden, da kann ein Constraint wenig verbessern.
Ein besseres Beispiel für Constraints wäre IMHO:
Wir nehmen jetzt eine weitere Tabelle, in der wir Mitarbeiter verwalten und ggf. einen Dienstwagen zuordnen.
Das wäre dann:
CREATE TABLE mitarbeiter(
mitarbeiterid INT NOT NULL PRIMARY KEY,
name text NOT NULL,
dienstwagenid INT,
CONSTRAINT pk_mitarbeiterid PRIMARY KEY (mitarbeiterid)
);
Das gibt uns eine Reihe von Problemen:
Ein Dienstwagen kann mehreren Mitarbeitern zugeordnet sein, es können Dienstwagen zugewiesen werden die nicht existieren und wenn ich einen Dienstwagen lösche, bleibt er dem Mitarbeiter weiter zugewiesen.
Das kann man mit Constraints reparieren:
ALTER TABLE mitarbeiter
ADD CONSTRAINT unique_dienstwagenid UNIQUE KEY (dienstwagenid),
ADD CONSTRAINT fk_dienstwagen FOREIGN KEY (dienstwagenid) REFERENCES dienstwagen(dienstwagenid) ON DELETE RESTRICT;
Durch den Constraint "unique_dienstwagenid" (gut, dass wir ihn beim Namen referenzieren können!) sorgen wir dafür, dass ein Dienstwagen nur einem Mitarbeiter gleichzeitig zugewiesen ist.
Mit dem Constraint "fk_dienstwagen" sorgen wir dafür, dass der Dienstwagen nicht gelöscht werden kann, wenn noch ein Datensatz auf ihn referenziert.
Wenn du jetzt versuchst einen Dienstwagen zu löschen, wird dir der SQL-Server sagen dass es eine Constraint Violation gibt und "fk_dienstwagen" dich daran hindert, Datensätze zu löschen.
Und dafür brauchst du die eindeutigen Namen
Dein CREATE-Statement ist nicht korrekt. Tatsächlich versuchst du zwei Primary Keys zu definieren, es handelt sich nur um unterschiedliche Schreibweisen. Im ersten Fall wird ein zufälliger Name generiert, da kein Name spezifiziert wurde. In Zeile 5 versuchst du dann nochmal einen PRIMARY KEY zu erstellen, diesmal mit einem spezifischen Namen. MSSQL wirft hier z.B. folgende Meldung:
Msg 8110, Level 16, State 0, Line 1
Der mitarbeiter-Tabelle können nicht mehrere PRIMARY KEY-Einschränkungen hinzugefügt werden.
Die gesammte Tabelle wird nicht erstellt da es sich um ein Statement handelt. Du kannst aber auch CONSTRAINTs nachträglich per ADD hinzufügen, auch hier ist das Ergebnis aber gleich, es gibt maximal einen PK und wie der ursprünglich erzeugt wurde spielt keine Rolle, die Funktion ist die selbe.
Msg 8110, Level 16, State 0, Line 1
Der mitarbeiter-Tabelle können nicht mehrere PRIMARY KEY-Einschränkungen hinzugefügt werden.
Die gesammte Tabelle wird nicht erstellt da es sich um ein Statement handelt. Du kannst aber auch CONSTRAINTs nachträglich per ADD hinzufügen, auch hier ist das Ergebnis aber gleich, es gibt maximal einen PK und wie der ursprünglich erzeugt wurde spielt keine Rolle, die Funktion ist die selbe.