Foreign Key on X restrict

Kampfgummibaerlie

Datenbank-Guru
Beiträge
743
Nachdem ich offenbar wieder voll am Eifern bin, hänge ich jetzt an dem im Titel genanntem Zwischenfall, dass ich den Prozess nicht verstehe...

Google Translator => restrict = beschränken

Nur wie funktioniert das ganze?

Danke, falls einer unter den wahren Gurus eine Erklärung dazu parat hat ;)

LG Baerlie :)
 
Werbung:
Bin ich hier im Gedanken richtig, dass man damit unter Umständen eine Art "Archiv" erstellen könnte? sprich das ganze funktioniert irgendwie so, dass ich zum Beispiel (ja, ich bleibe bei Mimoso, weil das hier schon bekannt ist) für Werbe-Zwecke bereits im Herbst so in 1/4 aller Werbungen die meistverkauften Produkte vom letzten Jahr auf der Homepage darstellen könnte um damit wiederum bereits im Herbst einen Anreiz für die Kunden geben, sich auch dieses Jahr die Weihnachtsprodukte anzusehen?

Klingt jetzt vl. kompliziert... aber ich hoffe, man weiß, wie ich denke...

weil exakt sowas würde ich simpel via Trigger lösen, aber wenn das mit einer bereits existenten, mir unbekannten Funktion möglich ist, würde ich mich liebend gerne damit auseinandersetzen!

Danke mr. Elephant für den Link ;)
 
Code:
postgres=# create table parent(id int primary key);
CREATE TABLE
postgres=# create table c1(parent_id int references parent(id) on delete no action deferrable);
CREATE TABLE
postgres=# insert into c1 values (1);
INSERT 0 1
postgres=# begin;
BEGIN
postgres=*# set constraints all deferred;
SET CONSTRAINTS
postgres=*# delete from parent where id = 1;
DELETE 1
postgres=*# commit;
ERROR:  update or delete on table "parent" violates foreign key constraint "c1_parent_id_fkey" on table "c1"
DETAIL:  Key (id)=(1) is still referenced from table "c1".
postgres=# drop table c1;
DROP TABLE
postgres=# create table c1(parent_id int references parent(id) on delete restrict deferrable);
CREATE TABLE
postgres=# insert into c1 values (1);
INSERT 0 1
postgres=# begin;
BEGIN
postgres=*# set constraints all deferred;
SET CONSTRAINTS
postgres=*# delete from parent where id = 1;
ERROR:  update or delete on table "parent" violates foreign key constraint "c1_parent_id_fkey" on table "c1"
DETAIL:  Key (id)=(1) is still referenced from table "c1".
postgres=!#


Der Unterschied ist, WANN der Fehler kommt. Entweder SOFORT, oder erst am ENDE der Transaktion.

So gesehen macht restrict deferrable auch wenig Sinn ...
 
Das ist also sozusagen für das abspeichern des Befehls, welcher zB den Fehler ausgelöst hat?
Oder kann man den Befehl, der fehl schlägt nicht irgendwie wieder ausgeben lassen? (pg_last_error($conn) bei php zum Beispiel...)

Ich habe mit Cursor und Commit schon gearbeitet in Python und eine knappe Bekanntschaft in Java gemacht, sprich man kann dort arbeiten, wie in einer "höherstufigen" programmiersprache?

Bin mal wieder voll buff, was ich alles nicht weiß *mich schäme*....

Mir ist es auch neu, dass man Constraints so einfach deaktivieren kann, man macht simpel 2 Zeilen mehr, und kann zur Probe gegen das eigentliche Ziel doch noch was eingeben (für evtl. Versuche oder sowas)...

Bekomme heute Besuch, freue mich aber schon auf heute Abend =D
 
macht womöglich auch sinn, sowas aufschiebbar zu machen, wenn ein Constraint sowas bewirken soll wie "Krankenstand"...
oder "ist jetzt auf urlaub"...

Da müsste man dann einen Not Constraint basteln mit einer boolschen Variable?

das mit der Urlaubszeit ist planbar, aber der Krankenstand nicht wirklich...
und ich denke sogar, der Befehl um den Constraint automatisch zu aktivieren ist via Cron-Job auch möglich...

Sprich ich müsste die Mitarbeiter auf der Homepage nur via "Ab datum" und "dauer" eintragen...
dann bräuchte ich 2 Cron-Jobs, die sich selbst nach dem erfolgreichen durchführen löschen? einer für aktivieren "auf urlaub" und der andere auf "wieder zurück" ?

das mit Krankenstand müsste ich dann eher direkt auf der Homepage angebbar machen können... (ist es hier sinnvoll, wenn ich pro Mitarbeiter eine boolsche Spalte mache, und diese einfach update oder via Constraint sinnvoller, praktischer oder sonstetwas?)

EDIT: -_- ich bin wieder voll im Datenbanken-Kreis, alles dreht sich um Datenbanken bei mir gerade xD
 
ich glaube, du hast das nicht so ganz verstanden. Das 'aufschieben' eines Constraints ist nur innerhalb der noch nicht abgeschlossenen Transaktion sichtbar, nirgends sonst. Mir fällt grad keine praktische Verwendung ein, aber stelle dir 2 Tabellen vor, die jeweils einen FK auf die andere Tabelle hat.
 
Mir ist es auch neu, dass man Constraints so einfach deaktivieren kann
sprich man kann dort arbeiten, wie in einer "höherstufigen" programmiersprache?
Ein Foreign Key Constraint und die Details wie restrict usw. haben nichts mit Programmierbarkeit direkt zu tun.

Foreign Key Constraint ist eine
Fremd Schlüssel Einschränkung

Es gibt viele Einschränkungsmöglichkeiten in RDBMS, hier eben die, das die eingetragenen Werte auf die Wertemenge beschränkt sind, auf die der Foreign Key verweißt (Primärschlüssel einer anderen Tabelle)

Constraints (Einschränkungen) können auch ganz andere Dinge vorschreiben:
der Wert muss größer 10 sein
darf nicht null sein
oder andere, kompliziertere Kriterien

Damit definierst Du neben den reinen Tabellenstrukturen die Spielregeln, die für Deine Daten zulässig sind.
Oft wird das (ohne Not) in Anwendungen gemacht, weil es keiner versteht oder was auch immer.
In schwierigen Fällen nimmt man auch Trigger. Das ist schon etwas näher an Programmierung, aber nicht so transparent wie Constraints.

Am Ende ergeben die Constraints zusammen mit der Tabellenstruktur Dein Datenmodell.
Und die DB übernimmt die grandiose Aufgabe, alle diese Spielregeln zu überwachen und falsche Daten abzulehnen. Dann wirft sie Fehler und darüber darf man sich freuen. Besonders wenn der Fehler nach dem 6 Millionsten Update auftritt und die DB brav alles wieder auf den Ausgangszustand zurückdreht, in dem sie die Transaction zurückrollt.

In einem guten Datenmodell ist es dann hoffentlich nicht möglich, krank zu sein und Stunden einzutragen. Allein mit Constraints und sowas wie Cascade, Restrict usw. geht das nicht.

Ich nutze bei FK Constraints eigentlich fast immer den Default. Gebe nicht Cascade und auch nicht Restrict an.
Die Operation schlägt dann einfach fehl und der Anwender / Programmierer muss überlegen, was übersehen wurde (und ggF. extra angeben, dass alles zu löschen ist > Cascade)
 
Arbeite mich weiter durch das Buch und habe unter anderem erfahren, dass Restrict so funktioniert (nur schnell ein Beispiel einfallen lassen):

Code:
create table a(b int primary key);
create table c(b int references a(b) on delete restrict, d int);
insert into a(b) values (1);
insert into c(b, d) values (1, 2);
insert into c(b, d) values (2, 2);

Tabellen mit werten erstellt...

Jetzt die Probe:
Code:
delete from a;
=> Fehler
Detail: Key (b)=(1) is still referenced from table "c".

Meine logische Schlussfolgerung nach meiner Erfahrung wäre, dass Restrict die "Default"-Einstellung ist bei einem Foreign Key mit "on delete"?
Weil ich lerne gerade, dass das praktisch wäre im Sinne, wenn ich eine Schule mittels einer Datenbank verwalten wollen würde, würde ich:

wenn lehrer krank ist, und man weiß wie lange, einfach den lehrer auf "null" setzen für die Kurse, und das Personal (oder die Datenbank) berechnet automatisch einen anderen Lehrer, der den kranken ersetzen könnte?

Nachdem das mit automatisch ersetzen nicht via Constraint geht, weil Constraints nichts einsetzen können denke ich müsste man dann einen Trigger bauen, der die entsprechende Tabelle updated...

das bedeutet, das ist recht praktisch, wenn man einen Constraint wieder auf den "Default"-Wert on delete umstellen möchte....

LG Baerlie ;D

edit: mein denkfehler, das ganze müsste dann mittels eines cron-jobs sein, der jeden Vormittag die Suplier-Stunden berechnet... :/
 
Werbung:
Das ist ein gutes Beispiel für Deinen Denkfehler.
Die DB überwacht nur, ob Datenänderungen zum Modell passen, also alle Regeln eingehalten werden, nichts weiter.
Erst wenn im Datenmodell Vertretungslehrer berücksichtigt sind (und das Modell zuvor dafür modelliert wurde), könnte die Datenbank auch das überwachen (immer noch nicht austauschen). Der Auslöser dafür wäre vielleicht die Krankmeldung, die irgendjemand für den regulären Lehrer einträgt. Dazu müssten auch Arbeitszeiten und Fächer / Unterrichtsplan im Datenmodell erfasst werden.

Es ist bei der Modellierung immer ein wichtiger Schritt, an welcher Stelle man den Cut macht. Es ist unrealistisch, die gesamte Realität abzubilden. Aber es ist realistisch, einen Ausschnitt mit den richtigen Konsistenzregeln zu versehen.

Möchte man aktive Datenänderungen durch die DB automatisieren, würde man idR Algorithmen dazu entwicklen und ausprogrammieren (Client oder Stored Procedures). Heute würde man vielleicht auch KI einsetzen, kommt auf das Problem an. In der Praxis sind es oft noch Menschen, die einen aktualisierten Istzustand in DB eintragen. Mittels Trendanalyse, Simulationsalgorithmen werden zukünftige Entwicklungen prognostiziert und z.B. Bestellvorschläge für die Lagerhaltung generiert, die Entscheidung was geschehen soll (in die DB eingetragen wird) trifft meistens noch der Mensch.

Es gibt dabei einen "lustigen" Effekt. Sozusagen die Bürokratie der Datenbanken. Wenn Du in einem großen Unternehmen ein Problem hast, weil irgendwas nicht zur Situation (aktuellen Misere) passt und versuchst, Produktionspläne oder was auch immer zu ändern, heißt es oft, geht nicht, weil kann man nicht eintragen(in die DB). Ich spare mir jetzt, Produktnamen zu nennen.
Modellierung kann sehr komplex sein. Am Ende ist es u.U. keine Frage mehr von Constraints, sondern geht weit darüber hinaus. Ist die Frage, ob es dann noch Modellierung genannt werden kann.

Wie auch immer, Du bist am Anfang, hast ein kleines Modell, eine Handvoll Tabellen und musst "nur" darauf achten, dass eingetragene Daten sinnvoll und redundanz- und widerspruchsfrei sind. In sich, nicht gegenüber der Realität.
 
Zurück
Oben