Autor Beitrag
Palladin007
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1282
Erhaltene Danke: 182

Windows 11 x64 Pro
C# (Visual Studio Preview)
BeitragVerfasst: So 03.02.13 00:04 
Guten Abend,

ich habe hier beispielhaft folgende Tabellen:
ausblenden Quelltext
1:
2:
3:
4:
Music     ([u]ID[/u], Name, InterpretID, AlbumID)
Interpret ([u]ID[/u], Name, CoverID)
Album     ([u]ID[/u], Name, CoverID)
Picture   ([u]ID[/u], Name)


Hier die Beziehungen:
ausblenden Quelltext
1:
2:
3:
4:
Music.InterpretID  ->  Interpret.ID
Music.AlbumID      ->  Album.ID
Interpret.CoverID  ->  Picture.ID
Album.CoverID      ->  Picture.ID


Die Fremdschlüsseleinschränkung habe ich immer wie folgt gewählt:
ausblenden Quelltext
1:
2:
ON UPDATE -> CASCADE 
ON DELETE -> SET NULL


Das gibt dann aber immer folgenden Fehler:
Zitat:
Die referenzielle Beziehung führt zu einem nicht zulässigen zyklischem Verweis.


Was das heißt, weiß ich, oder ich glaube zu wissen, was das heißt, daher erkläre ich erst einmal, was ich unter der Fremdschlüsseleinschränkung verstehe und warum ich die so gewählt habe, wie es oben steht, denn ich glaube, hier liegt bei mir ein Verständnisproblem vor.

ON DELETE:
Gibt an, was geschehen soll, wenn die Zeile gelöscht wird, deren Primärschlüssel in einer anderen Tabelle als Fremdschlüssel enthalten ist.
Wenn ich hier SET NULL setze, dann wird beispielsweise die Spalte Interpret.CoverID auf NULL gesetzt, wenn die entsprechende Zeile der Tabelle Picture gelöscht wird.

ON UPDATE:
Gibt an, was geschehen soll, wenn die Zeile geändert wird, deren Primärschlüssel in einer anderen Tabelle als Fremdschlüssel enthalten ist.
Wenn ich hier CASCADE setze, dann werden alle Änderungen, die beispielsweise in einer Zeile der Tabelle Interpret vor genommen wurden, auch auf alle Zeilen der Tabelle Music übernommen, welche die ID der geänderten Zeile der Tabelle Interpret als Fremdschlüssel in InterpretID enthalten.

Wenn ich nun also ein z.B. Bild lösche, dann werden alle Fremdschlüsselspalten in Interpret, Album und Music, die auf dieses Bild verweisen auf NULL gesetzt. Wenn die so geänderten Spalten nun wieder mittels 1:n Beziehung in einer weiteren Datenzeile "enthalten" sind (Interpret sowie Album in Music), dann wird das dort ebenfalls übernommen.
Aber wo gib es hier einen nicht zulässigen zyklischen Verweis, oder habe ich die Fremdschlüsseleinschränkungen falsch verstanden?

Ich hoffe auf gute Hilfe, auch wenn das Thema ja noch zu den Grundlagen gehört, aber ich finde irgendwie keine sonderlich gute Erklärung im Internet.


Gruß
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4798
Erhaltene Danke: 1059

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: So 03.02.13 10:16 
Hallo Palladin007,

benötigst du denn überhaupt "ON UPDATE CASCADE", d.h. können sich deine Primärschlüssel ändern?
Eine Einführung gibt es z.B. unter Einführung in SQL: Fremdschlüssel-Beziehungen
Palladin007 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1282
Erhaltene Danke: 182

Windows 11 x64 Pro
C# (Visual Studio Preview)
BeitragVerfasst: So 03.02.13 14:33 
Eigentlich nicht, aber auf die Idee bin ich dann auch erst gekommen, nachdem ich das hier geschrieben hatte.
Das zu ändern hat aber auch kein besseres Ergebnis gebracht, der Fehler kommt immer noch.
Ich verstehe einfach nicht, wo da ein zyklischer Verweis sein soll. Die ID von Picture ist in Album.CoverID und Interpret.CoverID hinterlegt, genauso ist Genre.ID in Album.GenreID und Interpret.GenreID hinterlegt und Album.ID sowie Interpret.ID sind beide in Music.InterpretID und Music.AlbumID hinterlegt. Wenn nun ein Cover gelöscht wird, dann wird diese ID in Interpret.CoverID und Album.CoverID auf NULL gesetzt und das war es dann auch. Wenn ein Album gelöscht wird, dann wird die entsprechende ID in Music.AlbumID auf NULL gesetzt und fertig, mehr passiert nicht.
Was ist da zyklisch?


Deinen Link werde ich mir auf jeden Fall mal durch lesen, ich kann ja eigentlich nur dazu lernen :D
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4708
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: So 03.02.13 15:14 
Der SQL Server mag es nicht wenn die gleiche Spalte (auch wenn nur theoretisch) über mehrere Wege gelöscht werden können. Zyklisch ist da sicher nicht ganz der richtige Begriff und andere DB's haben da weniger Probleme aber beim SQL Server ist es halt so.

Grundsätzlich würde ich dir eh von den DB internen Automatismen abraten. Die schaffen meist mehr Probleme als sie lösen beziehungsweise du tauscht nur die Art von Problemen gegen eine andere. Hier tauschst du das Problem selbst in der richtigen Reihenfolge zu löschen gegen das Problem deine In-Memory Darstellung der Daten mit dem was wirklich in der Datenbank ist synchron zu halten. Ersteres Problem ist in den allermeisten Fällen einfacher zu beherrschen als letzteres da ersteres relativ früh knallen wird wenn es nicht klappt. Letzteres Problem wird sich unter Umständen nur schleichend äußern und die Ursache schwieriger zu finden sein. Und wenn du an spätere Erweiterungen des Datenmodells denkst stehst du vor dem selben Problem. Selbst löschen wird wieder knallen wenn durch Modelländerungen löschen zu Problemen führt während Cascading Deletes möglicherweise Fehler verursachen die nicht sofort auffallen.
Palladin007 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1282
Erhaltene Danke: 182

Windows 11 x64 Pro
C# (Visual Studio Preview)
BeitragVerfasst: So 03.02.13 15:21 
Na toll, das erklärt so eine Menge Stress, weswegen ich auch ein älteres Projekt auf Eis gelegt habe -.-

Ist aber auf jeden Fall schon mal gut zu wissen, dass es kein Verständnisproblem ist.
Ich werd dann mal alle Fremdschlüsseleinschränkungen entfernen.


Danke für die Hilfe ^^