Ich habe eine Tabelle, auf die von Fremdschlüsseln an vielen anderen Tabellen verwiesen wird. In meinem Programm, wenn ich eine dieser Zeilen löschen möchte, muss ich zuerst nach Abhängigkeiten suchen und sie dem Benutzer präsentieren - "Dieses Objekt hängt von x aus Tabelle y, z von Tabelle q, etc" ab. Ich erwarte auch, dass die Anzahl der Tabellen, die Fremdschlüssel für diese Tabelle haben, im Laufe der Zeit erheblich zunimmt.
Ist die Datenbank "information_schema" eine gute Möglichkeit, alle Abhängigkeiten zu suchen? Ich habe versucht, sie abzufragen, um eine Liste aller Tabellen mit Fremdschlüsseln für meine Tabelle abzurufen, dann über das Ergebnis zu iterieren und alle Einträge aus jeder Tabelle auszuwählen, in denen der Fremdschlüsselwert mit dem Wert übereinstimmt, den der Benutzer löschen möchte. Die Abfrage, die ich habe, ist wie folgt:
%Vor%Das funktioniert perfekt, um die Tabellen zu bestimmen, die ich durchsuchen muss, aber es ist sehr langsam. Die Abfrage dauert bestenfalls etwa 1 bis 2 Sekunden, um auf meinem Entwicklungscomputer ausgeführt zu werden, was bei der Ausführung auf meinem Produktionsserver erheblich reduziert wird, aber immer noch ziemlich langsam ist.
Ich muss wissen, ob es eine schlechte Idee ist, information_schema auf diese Weise zu verwenden. Wenn nicht, wie kann ich bessere Leistung aus der Abfrage extrahieren. Ist die Abfrage, die ich verwende, solide oder gibt es einen besseren Weg? Wenn ja, wie sollte ich dieses Problem aus Sicht der Wartbarkeit angehen?
Dvorak hat Recht, INFORMATION_SCHEMA ist dafür gedacht.
In Bezug auf Ihre Leistungsbedenken gibt es mehrere Möglichkeiten, wie Sie die Leistung verbessern können
Einfacher Weg, aber nicht viel Verbesserung wird daraus entstehen: Speichern Sie die Informationen in einer statischen Variablen. Zumindest die Abfrage wird nur einmal pro Seite auftreten
Persistentes Caching verwenden: Der alternative PHP-Cache kann Ihnen helfen (siehe Ссылка ) ). Die Informationen, die Sie aus dem Informationsschema erhalten, sind ein guter Kandidat für die Speicherung in einem persistenten Cache.
Verwenden Sie eine ORM-Bibliothek, z. B. Doktrin ( Ссылка ) Ein Blick auf die Datei lib / Doctrine / Import / Mysql.php zeigt, dass es genau das tut, was Sie brauchen, und vieles mehr.
Die Verwendung von INFORMATION_SCHEMA ist für statische oder administrative Systeme OK, wird aber für eine transaktionale Anwendungsfunktion nicht empfohlen, da INFORMATION_SCHEMA wahrscheinlich als Ansichten über dem nativen Systemdatenverzeichnis implementiert ist.
Dies wäre eine ziemlich ineffiziente Art, eine generische D-Operation für eine CRUD-Bibliothek durchzuführen. Auch auf vielen Systemen (Oracle kommt mir in den Sinn) wird das Systemdatenwörterbuch tatsächlich als Ansichten auf einer untergeordneten Datenstruktur implementiert. Dies bedeutet, dass das native Systemdatenwörterbuch möglicherweise auch nicht dafür geeignet ist. Das Systemdatenwörterbuch kann sich auch von Version zu Version ändern.
Es sollte relativ wenige Fälle geben, in denen ein geradliniges "Löschen" eines Datensatzes und aller seiner Kinder der richtige Weg ist. Dies als generische Funktion zu tun, kann Ihnen wenig praktischen Nutzen bringen. Auch wenn die Fremdschlüssel nicht in der Datenbank vorhanden sind, werden verwaiste Kinder herumliegen, da diese Vorgehensweise davon abhängt, dass die FK vorhanden ist, um zu wissen, welche Kinder gelöscht werden sollen.
Verlangsamt meine Anwendungen zu einem Crawl, aber ich brauche die Fremdschlüssel-Constraint-Daten, um alles richtig miteinander zu verknüpfen.
Die Verzögerungen sind bei der Abfrage des Informationsschemas sehr groß und machen eine Seite, die zuvor sofort geladen wurde, in 3-4 Sekunden geladen.
Nun, in MySQL 5 gibt es zumindest Fremdschlüsselbeschränkungen, die eine robustere Anwendungsentwicklung ermöglichen, aber natürlich kostenpflichtig sind.
Seit 2006 beschweren sich die Leute über dieses Problem aufgrund meiner Google-Suchanfragen, und das Problem bleibt - es muss keine einfache Lösung sein - (
Falls dies jemals bei Google gefunden wird, ist es auch erwähnenswert, dass das information_schema gelegentlich von dem, was von show create table
zurückgegeben wird, abweicht.
Es gibt ein gutes Beispiel dafür in DBA-Stack-Exchange-Thread . Nach dem Ausführen dieses Befehls:
%Vor%Überprüfen Sie die Ergebnisse:
%Vor%Tags und Links mysql