Datenbank Anfängerfrage
Pauli
- datenbank
Hallo, ich habe eine grundsätzliche Frage zum Datenbankdesign.
Habe ich es richtig verstanden, dass man
(1) entweder die Tabellen in einer Datenbank in Beziehungen bringen kann (PK, FK) und Vorgaben macht, dass z.B. Felder nicht NULL sein dürfen. Und dann beim SQL Insert-Statement rumfummeln muss, bis alle Vorgaben der Datenbank erfüllt sind?
(2) oder die Tabellen ohne Vorgaben erstellt und dann z.B. mit PHP sicherstellt, dass die Daten so eingefügt werden wie man es braucht?
Danke, Pauli
Tipp: Nutze weitestgehend die Möglichkeiten welche das RDBMS bietet zur Sicherstellung Deiner Datenkonsistenz + referentieller Integrität. Also (1). MfG
danke dir.
danke dir.
Gut. Von daher noch ein praktisches Beispiel: Im laufenden Produktionsbetrieb soll eine Tabelle ein zusätzliches Feld bekommen. Was kann passieren, wenn kein Default gesetzt wurde?
Richtig: Insert Statements schlagen fehl, der Code wirft eine Exception, Kunden sind verärgert!
Zumindest solange bis der Code angepasst wurde.
MfG
Tach!
Habe ich es richtig verstanden, dass man
(1) entweder die Tabellen in einer Datenbank in Beziehungen bringen kann (PK, FK) und Vorgaben macht, dass z.B. Felder nicht NULL sein dürfen. Und dann beim SQL Insert-Statement rumfummeln muss, bis alle Vorgaben der Datenbank erfüllt sind?
(2) oder die Tabellen ohne Vorgaben erstellt und dann z.B. mit PHP sicherstellt, dass die Daten so eingefügt werden wie man es braucht?
Man kann die Möglichkeiten eines Systems nutzen oder sie weitgehend ignorieren, ja, aber dann stellt sich die Frage, warum man das System überhaupt nutzt.
Rumfummeln, bis es passt, ist aber auch nicht das Ziel, sondern man entwirft sein Datenmodell passend zu den Gegebenheiten des Anwendungsfalles. Die Restriktionen, die man dem Datenmodell verpasst, sollen keine Herausforderung darstellen, sondern Hilfen beim Einhalten der Integrität der Daten.
dedlfix.
Hallo Pauli,
(1) entweder (...) (2) oder
Ja.
Zu Variante (2) muss man folgendes sagen: Das einzige, was bei meinem Arbeitgeber heiliger ist als die Mittagspause, ist die Performance des Großrechners. MIPS kann man zwar kaufen, aber IBM hält dafür nicht nur die Hand auf, sondern stellt gleich einen ganzen Lastwagen zum Abtransport der dafür einzuwerfenden Münzen hin. Man bezahlt Host-Leistung monatlich entsprechend MIPS-Maximums, das man während dieses Monats hatte, und sei es auch nur für ein paar Sekunden. Es gibt Monitorprogramme, die gezielt das System drosseln, wenn die Last zu hoch geht. Deswegen war es uns immer verboten, in DB2 (der SQL-DB des Großrechners) Dinge zu nutzen die mehr taten als unbedingt nötig. Keine Trigger, keine Foreign Keys, ständiges Optimieren der Queries und des technischen Modells. Alle DB-Zusammenhänge hatten sich in Programmlogik wiederzufinden. Das führt dann zwar beim Test gelegentlich zu Inkon(tin|sist)enzen in der DB, aber dafür ist der Test ja da :)
Ein SQL Server dürfte nicht so hart an der Leistungsgrenze laufen, dass solche Maßnahmen nötig sind. Und wenn doch, kann man ihn clustern und die Leistungsgrenze hinausschieben. Auf dem Großrechner kann man das zwar auch (wir fahren bei uns einen Sysplex aus 6 fetten Z/OS Maschinen), aber es ist immens teuer. Es ist allerdings noch teurer, die Großrechnerwelt komplett in eine C/S Welt umzubauen, darum haben wir das Ding noch.
Deswegen: Nutze FKs und Kaskadierung. Das macht das Leben durchaus einfacher. Wenn Du dann allerdings bei DB-Operationen „rumfummeln“ musst, dann müsste die erste Aktion sein, das eigenen DB-Modell und die Funktionsweise der diversen Contraints besser zu verstehen. Wenn Du allerdings auf Situationen stößt, wo Du nicht mehr weißt wie Du mit deinen DB-Operationen um die Constraints herumkommst, musst Du den Sinn der Constraints in Frage stellen.
Manchmal gibt es auch einfach Fälle, wo MYSQL zu dumm ist. Z.B. steht im MYSQL Handbuch unter InnoDB, dass sich diese DB-Engine bei Massenänderungen nicht standardkonform verhält, sie prüft die Contraints zu früh. Dafür gibt's dann zur NOT noch die Option, die Checks abzuschalten, mit SET FOREIGN_KEY_CHECKS=X
, mit 0 oder 1 für X. In dem Moment hast Du die Verantwortung für die referenzielle Integrität selbst an der Backe.
Rolf
Tach!
Zu Variante (2) muss man folgendes sagen: Das einzige, was bei meinem Arbeitgeber heiliger ist als die Mittagspause, ist die Performance des Großrechners.
Das ist aber eine eher Einzelsituation. Wenn man diese hat, bekommt man das von den Kollegen, Chefs, Auftraggebern gesagt. Wenn so eine Situation nicht vorliegt, sollte man sich darüber keine Gedanken machen, denn ...
Alle DB-Zusammenhänge hatten sich in Programmlogik wiederzufinden. Das führt dann zwar beim Test gelegentlich zu Inkon(tin|sist)enzen in der DB, aber dafür ist der Test ja da :)
... Konsistenz ist auch ein hohes Gut. Diese in Programmlogik sicherzustellen, erfordert einen hohen Aufwand an Konzentration einerseits, dass man ja keine Vorgänge implementiert, die eine Prüfung unberücksichtigt lassen, oder eben zusätzlicher Maßnahmen wie Tests. Das wird dann schnell mehr Aufwand, als sich mit den Gegebenheiten des DBMS zu befassen. Besonders als Anfänger wird man damit auch so seine Herausforderungen haben.
Andererseites bekommt man das auch hin. Damals, als die InnoDB-Engine noch nicht Standard in MySQL war, sondern MyISAM, und damit die referenzielle Integrität nicht vom DBMS sichergestellt werden konnte, hat man auch Programme mit konsistenter Datenhaltung schreiben können. Das war aber eher aus der Not heraus, nicht etwa weil es vorteilhaft war.
Deswegen: Nutze FKs und Kaskadierung. Das macht das Leben durchaus einfacher. Wenn Du dann allerdings bei DB-Operationen „rumfummeln“ musst, dann müsste die erste Aktion sein, das eigenen DB-Modell und die Funktionsweise der diversen Contraints besser zu verstehen. Wenn Du allerdings auf Situationen stößt, wo Du nicht mehr weißt wie Du mit deinen DB-Operationen um die Constraints herumkommst, musst Du den Sinn der Constraints in Frage stellen.
Kann ich nur unterschreiben.
Manchmal gibt es auch einfach Fälle, wo MYSQL zu dumm ist. Z.B. steht im MYSQL Handbuch unter InnoDB, dass sich diese DB-Engine bei Massenänderungen nicht standardkonform verhält, sie prüft die Contraints zu früh. Dafür gibt's dann zur NOT noch die Option, die Checks abzuschalten, mit
SET FOREIGN_KEY_CHECKS=X
, mit 0 oder 1 für X. In dem Moment hast Du die Verantwortung für die referenzielle Integrität selbst an der Backe.
Naja, dafür hätte ich als Anwendungsfall nur, wenn man als einmalige administrative Aufgabe, aber nicht im Regelbetrieb, große Datenmengen aus der Datenbank löschen möchte. Zum Beispiel vorinstallierte Demo-Datensätze. Da ist es mitunter recht umständlich, genau die Reihenfolge einzuhalten, in der die Tabellen/Datensätze anzufassen sind, weil ja zuerst alle abhängigen Daten wegmüssen, bevor die Basisdaten gelöscht werden können. Also beispielsweise erst alle Rechnungsposten, dann die Rechnung (falls kein Cascade Delete konfiguriert wurde).
dedlfix.
hi @Rolf B
Alle DB-Zusammenhänge hatten sich in Programmlogik wiederzufinden. Das führt dann zwar beim Test gelegentlich zu Inkon(tin|sist)enzen in der DB, aber dafür ist der Test ja da :)
Ich kenne eine Firma die haben das ganz genauso gehandhabt (Oracle). So blieb mir mit meinem Perl nichts weiter übrig, als programmiertechnisch auf solche Dinge einzugehen.
Was dann allerdings passiert ist: Die haben meine Testprogramme hinter meinen Rücken produktiv geschaltet. Auf deutsch gesagt, die haben mich nur ausgenuzt. Von daher durften sie auch die Konsequenzen selber tragen.
MfG