Datenbank von Müll bereinigen
lima-city → Forum → Programmiersprachen → PHP, MySQL & .htaccess
airbus
airport
bedingung
beispiel
bereinigung
code
datenbank
datum
definieren
eintrag
flughafen
problem
referenz
reinigung
tabelle
textdatei
url
verletzen
verweigern
zeitpunkt
-
Hi, ich habe folgendes Problem:
Ich habe eine relativ komplexe Datenbank, die über die Zeit gewachsen ist. Aktuell verwenden die meisten Tabellen MyISAM, wodurch sich keine Fremdschlüsselbeziehungen angeben lassen.
Ich möchte nun diese Datenbank möglichst effizient aufräumen (Datensätze löschen, die überflüssig geworden sind, weil die Referenz verloren gegangen ist u.ä.). Wie kann ich das am besten erreichen?
Ist es möglich, alle Tabellen gefahrlos von MyISAM in InnoDB umzuwandeln?
Kann ich dann Fremdschlüsselbeziehungen definieren, welche zu dem Zeitpunkt garnicht mehr erfüllt werden aufgrund des angesammelten Datenmülls? Und kann ich danach eine Reinigung manuell anstoßen? -
Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!
lima-city: Gratis werbefreier Webspace für deine eigene Homepage
-
vexi schrieb:
kann man dazu die kompletten db-strukturen ansehen (create)? ohne genue kenntnisse ist so etwas eher schwierig zu beantworten.
Hi, ich habe folgendes Problem:
Ich habe eine relativ komplexe Datenbank, die über die Zeit gewachsen ist. Aktuell verwenden die meisten Tabellen MyISAM, wodurch sich keine Fremdschlüsselbeziehungen angeben lassen.
Ich möchte nun diese Datenbank möglichst effizient aufräumen (Datensätze löschen, die überflüssig geworden sind, weil die Referenz verloren gegangen ist u.ä.). Wie kann ich das am besten erreichen?
Ist es möglich, alle Tabellen gefahrlos von MyISAM in InnoDB umzuwandeln?
Kann ich dann Fremdschlüsselbeziehungen definieren, welche zu dem Zeitpunkt garnicht mehr erfüllt werden aufgrund des angesammelten Datenmülls? Und kann ich danach eine Reinigung manuell anstoßen? -
Leider darf ich die nicht herausgeben aber ich denk mal das Grundprinzip sollte mit diesem Beispiel klar werden:
Nehmen wir mal die folgenden beiden Tabellen:
airports(id, city, coordinates)
airplanes(id, airport_id, type, max_num_of_passengers)
Nun gibt es in airplanes einen Eintrag der so aussieht: (1, 12, airbus, 250)
Der dazugehörige Flughafen mit der id 12 ist jedoch nicht mehr vorhanden. Ich möchte nun, dass das Flugzeug entsprechend gelöscht wird und es nicht mehr möglich ist, einen neuen Datensatz mit der airport_id = 12 anzulegen.
Ich hoffe, es ist nun etwas klarer geworden, wo mein Problem liegt. -
vexi schrieb:
was die lage natürlich nicht vereinfacht.
Leider darf ich die nicht herausgeben ...
Nun gibt es in airplanes einen Eintrag der so aussieht: (1, 12, airbus, 250)
ist dem nach noch immer nicht klar, ob die eintragung noch in der datenbank erhalten ist oder bereits entfernt wurde?¿
Der dazugehörige Flughafen mit der id 12 ist jedoch nicht mehr vorhanden...
(nach meinem geschmack gehört aus einer datenbank nichts entfernt, sondern als '[nicht]verfügbar / [in]valid' o. irgendwie so maskiert. [man könnte die vorhandenen daten eventuell später doch noch gebrauchen!]) -
Der Eintrag in airports mit der id 12 existiert nicht mehr in der Datenbank, wurde also entfernt.
Alle Daten in der DB zu belassen sorgt für geringere Performance. Außerdem gibt es in unserer Datenbank auch Daten, die Informationen über Nutzer enthalten und somit gelöscht werden müssen, wenn der Nutzer dies wünscht. (Wie auch immer, das soll hier nicht der Diskussionspunkt sein).
Ich möchte also erreichen, dass die Datenbank den Eintrag aus airplanes automatisch entfernt. Dazu möchte ich der Datenbank nur mitteilen, dass es sich bei der airplane_id um einen Fremdschlüssel handelt und die dabei definierten Restriktionen sollen dann automatisch eingehalten werden. -
Hallo vexi,
direkt in der MySQL-Dokumentation ist ein Beispiel, wie man sowas machen kann:
Für das Flugzeugbeispiel wäre das dann:DELETE t1 FROM t1 LEFT JOIN t2 ON t1.id=t2.id WHERE t2.id IS NULL;
Das musst Du dann halt hierarchisch absteigen mit allen betroffenen Tabellen machen.DELETE airplanes FROM airplanes LEFT JOIN airports ON airplanes.airport_id = airports.id WHERE airports.id IS NULL;
-
Danke für deine Antwort aber das ist mir schon klar, dass das ginge
- die Frage ist, ob man das auch einfacher machen kann.
Es geht hierbei um > 200 Tabellen... -
Hallo vexi,
das konvertieren der Tabellen nach InnoDB sollte eigentlich per 'ALTER TABLE' gehen
Aber das weißt Du wahrscheinlich auch schonALTER TABLE t1 ENGINE=InnoDB;
Das Problem ist also die automatische Erkennung von gewünschten Fremdschlüssel-Bedingungen und eine entsprechende Bereinigung der Daten.
Ich habe jetzt mal in der MySQL-Doku gesucht und leider nicht herausbekommen, was MySQL macht, wenn man einen Foreign-Key-Constraint einfügt, obwohl die Bestandsdaten diese Bedingung verletzen. Wenn MySQL eine anständige Datenbank ist, dann sollte sie diese Änderung verweigern.
Auf jedenfall denke ich, dass die Bereinigung vor dem hinzufügen der Fremdschlüssel stattfinden sollte um Probleme zu vermeiden.
Eine Chance zur Automatisierung sehe ich eigentlich nur dann, wenn die Fremdschlüsselfelder einer festgelegten Syntax folgen. Als Beispiel:
D.h. jedes Feld, dass mit 'id' endet und nicht nur 'id' heißt stellt einen Fremdschlüssel dar. In Tabellen- und Feldnamen, welche in Fremdschlüsseln verwendet werden, kommen keine Unterstriche vor.<Tabelle>_id -> <Tabelle>.id <Tabelle>_<Feld>_id -> <Tabelle>.<Feld>
Dann könnte man die Datenbank automatisch Durchsuchen und aus den Namen die Tabellenhierarchie konstruieren. Anhand dieser Hierarchie könnte man die Datenbank dann bereinigen und anschließen die Foreign-Key-Constraints einfügen.
Man sollte nach der Analyse und Erstellung des Hierarchiebaumes die Daten in eine Textdatei schreiben um das Ergebnis zu konrollieren und evtl. manuelle Änderungen vornehmen zu können. Die Bereinigung und das Hinzufügen der Foreign-Key-Constraints sollte dann auf Basis dieser Textdatei vorgenommen werden.
-
Grundsätzlich eine sehr gute Idee aber leider ist da keine einheitliche Syntax bei der Benamung verwendet worden
Ich habe jetzt mal in der MySQL-Doku gesucht und leider nicht herausbekommen, was MySQL macht, wenn man einen Foreign-Key-Constraint einfügt, obwohl die Bestandsdaten diese Bedingung verletzen. Wenn MySQL eine anständige Datenbank ist, dann sollte sie diese Änderung verweigern.
Genau das vermute ich auch, was grundsätzlich ja eine wünschenswerte Eigenschaft wäre, jedoch in diesem speziellen Fall leider etwas ungünstig ist.
Naja, ich fürchte, wir müssen wohl in den sauren Apfel beißen und das ganze per Hand machen bzw. vermutlich werde ich die Schlüsselbeziehungen in einem PHP-Script festlegen und mir dann entsprechende Delete-Queries generieren. Ich denke, das wird wohl die beste Möglichkeit sein.
Vielen Dank an alle, die sich beteiligt haben -
Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!
lima-city: Gratis werbefreier Webspace für deine eigene Homepage