2012-05-15 12 views
6

Ich speichere Dateisystemhierarchien von Verzeichnissen und Dateien.Kaskadisches Löschen von Datentabelle und Suchtabelle gleichzeitig

In einer innodb-Tabelle speichere ich die Details jedes Verzeichnisses/Datei und behalte die Eltern-Kind-Beziehung mit einer Fremdschlüsselbedingung, die beim Löschen kaskadieren wird.

Eine Myisam-Tabelle wird verwendet, um diese Verzeichnisse/Dateien mit einer Volltextsuche zu durchsuchen. Es enthält die Namen und IDs jeder Zeile.

Alle Zeilen in der Datentabelle (innodb-Tabelle) haben eine entsprechende Zeile in der Suchtabelle (myisam-Tabelle) und das Hinzufügen oder Entfernen von Zeilen aus der Datentabelle muss in der Suchtabelle enthalten sein.

Ich versuche, die beste Lösung zu finden, um die Datenkonsistenz zwischen den beiden Tabellen beim Löschen eines übergeordneten Verzeichnisses zu erhalten. Der Innodb Tisch ist in Ordnung. Ich lösche die Eltern, die Löschkaskaden durch die Kinder, bis sie alle gelöscht sind. Das Löschen der entsprechenden Zeilen aus der Myisam-Tabelle ist schwieriger.

Mein erster Gedanke war die Verwendung eines On-Delete-Triggers auf der Innodb-Tabelle. Wenn eine Zeile gelöscht wird, löscht sie die entsprechende Zeile aus der Myisam-Tabelle. Da MySQL jedoch keine Auslöser während eines Kaskaden-Löschvorgangs aktiviert (ein seit 7 Jahren bekannter Fehler, der durch die fehlende Unterstützung im Handbuch behoben wurde), ist dies keine Option.

Mein zweiter Gedanke war eine Eltern-Kind-Beziehung in der Suchtabelle, aber es ist eine Myisam-Tabelle, um die Volltextsuchfunktionalität zu unterstützen, und so unterstützt es keine Fremdschlüsseleinschränkungen.

Ich hatte gehört, dass innodb jetzt Volltextsuchen unterstützt, also dachte ich vielleicht, ich könnte die Suchmaschine ändern, aber es ist nur in der Laborversion verfügbar.

Mein letzter Gedanke war es, Fremdschlüssel Einschränkungen aufzugeben und nur Trigger zu verwenden, um die Datenkonsistenz zu erhalten. Löschen Sie aus delete sowohl innodb als auch myisam table, wobei parent = OLD.id. Um jedoch Endlosschleifen zu verhindern, die alle Daten in der Tabelle beschädigen könnten, unterstützt MySQL nicht die Manipulation der Daten in derselben Tabelle, die den Trigger aktiviert hat.

Ich habe programmgesteuert alle Kinder unter dem übergeordneten Verzeichnis durch eine Schleife von Anfragen abgerufen, aber ich denke, es muss eine bessere Option sein. Gibt es noch andere Arbeiten, die effizienter wären? An dieser Stelle warten nur zwei Möglichkeiten darauf, dass einer der oben genannten Ansätze behoben oder auf ein anderes RDBMS wie PostgreSQL umgestellt wird, das das Auslösen von Triggern aus einem Kaskaden-Löschen unterstützt.

Alle anderen Ideen würden sehr geschätzt werden.

+0

Ich bin mir nicht sicher, ob ich es verstehe, ich bin ziemlich verwirrt über Ihre Beziehung zwischen zwei Tabellen, was ich bekomme, ist eine Beziehung zwischen zwei Tabellen definieren, die einen anderen Typ hat. Ich habe dies schon einmal versucht und Probleme bei der Aufrechterhaltung der Datenkonsistenz festgestellt, wenn Sie die Datenkonsistenz durch Tabellenbeziehung mit dem Benutzer von Fremd- und Primärschlüsseln erhalten möchten, verwenden Sie innodb für alle Tabellen, in denen Sie Ihre Beziehung definieren. –

+0

Die Suchtabelle (myisam) wird als meine Suchmaschine für die Datentabelle (innodb) verwendet. Da Verzeichnisse mit Unterverzeichnissen und Dateien gelöscht werden, müssen sich die Änderungen sowohl in der Datentabelle als auch in der Suchtabelle widerspiegeln. Ich kann innodb nicht für die Suchmaschine verwenden, da die Unterstützung für Volltextsuche fehlte (zumindest zu der Zeit). Die Beziehung ist in der Datentabelle gut definiert, Löschvorgänge werden jedoch nicht in der Suchtabelle wiedergegeben. – JayceTDE

+0

+1 für eine gut geschriebene Frage; Leider sehe ich keine Alternativen zu deinem derzeitigen Ansatz, aber vielleicht wird jemand anderes etwas einfallen lassen – Daan

Antwort

1

Diese Art von Kopfschmerzen sind genau das, was mich von mysql wegbewegte, wo es möglich war.

... Ich fühle mich hat es bekam eine bessere Option sein ...

Leider gibt nicht ist. Das einfache Problem ist, dass Sie Kaskade nicht löschen können und mysql wissen, was es gerade gelöscht hat. Daher ist Ihre einzige Option, herauszufinden, was zu löschen ist, bevor dies der Fall ist (das ist der Algorithmus, den Sie am Ende vorgeschlagen haben).

Da die Daten durch die Kaskadierung beschädigt werden, sollten Sie keinen Schlüssel on update cascade verwenden, damit der Versuch, ein übergeordnetes Verzeichnis zu löschen, ohne das untergeordnete Element zu löschen, fehlschlägt.

Ich würde empfehlen, dass Sie ein Verfahren erstellen, um das schwere Heben (Löschen) für Sie zu tun. Dies verhindert eine große IO zwischen Ihrer App und der DB, wie es durch alle Verzeichnisse rezensiert. Iy wird auch einen allgemeinen Code dafür bereitstellen, wenn Sie jemals über eine andere App auf die gleiche db zugreifen (oder Sie wollen nur etwas manuell machen).

Wie ich zuerst gesagt habe, benutze ich postgresql meistens in diesen Tagen. Dies ist ein Beispiel dafür.

Verwandte Themen