Hallo Dominik,
Zitat von
dominik.boehm:
Simples Beispiel: man hat eine Artikeldatenbank, wobei jedem Artikel eine Artikelgruppe zugeordnet ist. Jetzt soll eine Artikelgruppe gelöscht werden, zu der Artikel vorhanden sind. Da könnte man ja vorher alle Artikel so abändern, dass zu der Artikelgruppe keine Artikel mehr existieren und gut.
ich unterscheide streng zwischen referential integrity (RI) constraints und business rules, wobei die Mittel zur Umsetzung von business rules auch constraints (ON DELETE CASCADE) sein können. Der Typ der Beziehung entscheidet letztlich, welche Auswirkung ein Löschvorgang auf einen foreign key hat. In deinem Beispiel liegt eine weak relationship vor, keine existenzielle Beziehung. In der problem domain ist völlig klar, dass die Artikelgruppe eine Kategorie darstellt, während ein Artikel ein physisches Objekt repräsentiert. Da der Artikel auch ohne das mentale Konstrukt Kategorie existieren kann, würde hier ON DELETE NULLIFY oder ON DELETE DEFAULT greifen, je nachdem was das RDBMS unterstützt. Zur Not muss ein Trigger herhalten.
Selbstverständlich kann es eine legitime Anforderung sein, alle Artikel einer bestimmten Artikelgruppe aus dem Katalog zu entfernen, aber das kann meine Entscheidung gegen ON DELETE CASCADE nicht umstoßen.
Zitat von
dominik.boehm:
Oder man hat Aufträge, in denen zu einem Artikel auch die Artikelgruppe gespeichert wird und möchte nun die Artikelgruppe löschen. Für zukünftige Aufträge kein Problem, aber was ist mit alten Aufträgen?! Sollte man in solchen Fällen die Daten in der Datenbank einfach als gelöscht markieren und nicht mehr anzeigen, wodurch man nicht inkonsistent wird, oder hart löschen und nicht komplett relational arbeiten?!
Es gibt Entscheidungen technischer Natur, wie weiter oben, bei denen ich als erfahrener Entwickler keinen Dialog mit dem Auftraggeber führen muss. Dieses Beispiel ist anders gelagert. Ich erwarte eine BR, die das Löschen einer Artikelgruppe verbietet, solange noch abhängige Aufträge (live orders) existieren. Diese BR stammt aus der problem domain und kann nicht von mir alleine festgeschrieben werden, obwohl der Auftraggeber in der Realität meinem Rat folgen wird.
Zitat von
dominik.boehm:
Oder sollte man immer die Möglichkeit geben, bestehende Datensätze anzupassen? (z.B. eine Abfrage, in welche Artikelgruppe die Artikel stattdessen einsortiert werden sollen)
Bitte nicht so. Der Benutzer will mal eben einen Karton ins Lager stellen und wird verhaftet um das Lager aufzuräumen - bildlich gesprochen. Der Benutzer darf eigentlich immer nur solche Aktionen starten, die er auch zu einem guten Ende bringen kann - ohne mit Zusatzarbeiten konfrontiert zu werden.
Zitat von
dominik.boehm:
Denn wenn ich in jeder Tabelle mit einem "Gelöscht"-Flag arbeite, werden evtl. einige Abfragen (leicht) komplizierter und man vertut sich evtl. schneller.
Nicht jede Tabelle braucht ein delete flag. Wichtig ist das nur bei solchen Tabellen, die esentielle Entities aus der problem domain abbilden. Das sind regelmäßig die Entities, die der Benutzer später an prominenter Stelle in der Benutzerschnittstelle der Anwendung wiederfindet, über die er Zugang zu seinen Daten erhält. Davon "abhängige" Daten benötigen kein delete flag, da sie unsichtbar bleiben, wenn der master record ausgeblendet wird.
Der Vorteil eines undo features überwiegt in der Regel die aufgrund eines delete flags geringfügig höhere Komplexität der
SQL-Statements.
Es gab einmal ein wunderbares Buch zu diesem Thema, von zwei tollen Frauen geschrieben. Ich habe viel daraus gelernt:
Code:
Fleming, Candace C., Barbara von Halle "Handbook of relational database design" Raeding, MA: Addison-Wesley Publishing Company, 1989.
Freundliche Grüße vom marabu