MySQL DB-Struktur hashen

joschilein

Multitalent
ID: 9301
L
5 Mai 2006
1.393
151
Kann man eigentlich irgendwie zuverlässig und zeitsparsam eine Anfrage an MySQL stellen, um von der Strukturänderung mehrerer Tabellen bzw. derer Spalten zu erfahren? Also nicht die gesamte Information über die Struktur, sondern nur ob sich seit dem letzten Mal etwas an der Struktur geändert hat. Quasi ein Hash über die Tabellenstruktur.

Mir ist zwar gerade die Idee gekommen, dass man ja ggf. über das information_sheme abfragen könnte. Hier hat aber testweise die Darstellung der Columns-Tabelle weit über 10 Sekunden gedauert, da, wie ich vermute, dabei rechtemäßig erstmal alle Einträge des gesamten Servers geprüft werden müssen. Selbst mit WHERE auf meine Tabelle einschränke sind es immer noch über 0,6 Sekunden und damit viel zu viel.
 
Kann man ein Update Operator auf eine Alter Table Operation anwenden ?
Wenn ja sollte es gehen, wenn nicht, dann nur über schema

Wer ändert seine Struktur im laufenden Betrieb, wenn auf Tabellen funktionen liegen könnten. Wird wohl nicht so bei Dir sein, aber komisch find ich das schon
 
Huch, ich merke gerade, dass die zuerst fast abgeschickten zusätzlichen Absätze doch nicht unrelevant gewesen wären.

Kann man ein Update Operator auf eine Alter Table Operation anwenden ?
Werde ich mal probieren.

dann nur über schema
Dauert wie gesagt zu lange

Wer ändert seine Struktur im laufenden Betrieb, wenn auf Tabellen funktionen liegen könnten. Wird wohl nicht so bei Dir sein, aber komisch find ich das schon
War eher eine sehr nervenschonende Hilfe in der Entwicklungsphase. Da sind Spalten mal in ganz andere (ggf. neue) Tabellen gewandert und ich hatte mir selbst ein Ei mit Groß-/Kleinschreibung gelegt. So konnte ich dann einfach ein großes Array machen und das wurde mir automatisch auf die verschiedenen Tabellen aufgeteilt.

Mittlerweile habe ich zwar ein (hoffentlich) endgültige Form gefunden und alles direkt mit der Bestimmung zur Zieltabelle verknüpft, aber die letzten paar Baustellen bleiben noch. Beispielsweise möchte ich ganz am Ende eines Aufrufs eine Tabelle mit den Zwischenzeiten einzelner Klassen bzw. Operationen sammeln und da ggf. irgendwann mal eine weitere Spalte "einblenden" (Spalte einfügen) oder andere ausblenden (Spalte löschen). Eigentlich müsste die Tabelle die Form "(id), aufrufid, zeitname, zeit" haben, aber bevor ich da groß eine Auswertung draus bastel, würde ich das eben nur gerne im Viewer anschauen und da ist eine sichtbare Tabelle besser als viele Zeilen. Das ganze passiert aus Gründen der Zeitmessung erst wenn alles andere quasi schon abgeschaltet ist (z.B. eine ordentliche Fehlerbehandlung/-weiterverarbeitung) möchte ich hier DB-Exceptions vermeiden und vorher die tatsächlich vorhandenen Spalten sicher ermitteln.

SHOW COLUMNS sollte deine Lösung sein
Das war meine bisherige Lösung. Mit kleinem Overhead durch eine Query- und DB-Klasse und letzten kleinen Manipulationen (z.B. Ignorierung von autoincrement-Spalten) hat ein Aufruf dieser Funktion auf meinem Testsystem 20-50ms gedauert. Bei zunächst rund einem Dutzend Tabellen war das also schon ein ziemlich Zeitfaktor. Die meisten davon habe ich mittlerweile eliminiert. Mein Ziel ist die ganze Klasse in maximal 100ms abzuhandeln (bei einem Seitenaufruf passieren ja noch genügend andere Dinge), aber schon die verbleibende Vorbereitung für die Zeittabelle braucht eben schon ihre 50ms.

Aktuelle Überlegung: Ich programmiere die Vorbereitung hart und fange die DB-Exception im Fehlerfall (Spalte zu viel oder zu wenig) unausgegeben auf, lese erst dann die Spalten dynamisch aus und speichere erneut - und zusätzlich benachrichtige ich mich, dass die harte Programmierung geändert werden muss. Kostet alles Zeit, würde aber ansonsten ja eh nicht funktionieren.
 
Schau dir mal maatkit an das könnte das seien was du willst :)

insbesondere mt-table-checksum


bzw für dich wäre wahrscheinlich mysqldiff besser weil du willst ja nur die Tabellenstrucktur abgleichen.

Aradiv
 
Zuletzt bearbeitet:
Ich habe es jetzt mal wie angedeutet eingerichtet.
1. Es gibt Arrays für die momentane Tabellenstruktur. Zuerst werden nur diese bemüht.
2. Falls eine DB-Exception auftritt, weil eine Spalte angesprochen wird, die MySQL gar nicht (mehr) kennt, wird die Exception unterdrückt und wie bisher mit Show Coloumns der aktuelle Stand abgefragt. Der ganze Speicherversuch geht in die zweite Runde.
3. Gleichzeitig wird für das Backend rumgemeckert, da das kein Dauerzustand bleiben kann und gefälligst die Tabellenstruktur in PHP aktualisiert werden muss.

Ich denke das ist ein vernünftiger Kompromiss. Wenn was falsch läuft fliegt es mir weiterhin nicht sofort um die Ohren und wenn wie gewollt alles richtig läuft, wird keine dann unnötige Zeit verbraucht.