Thomas Schmieder: MySQL: Workaround für NEXT und PREVIOUS gesucht

Beitrag lesen

Hallo Sven,

danke, dass Du dir die Sache nun NOCHMAL angeschaut hast. Ich hatte Dich da aber doch schon richtig verstanden. Ich will auch mal versuchen zu erklären, MEN die Schwachstellen der Lösung liegen.

Ähm, hattest du nicht irgendwann mal Performancebedenken

Die habe ich auch immer noch. Da greife ich aber Deinen folgenden Vorschlag nochmal auf...

Da bin ich mir noch nicht sicher. Es liegt ein Index auf dem Feld Name und einer auf ID. Außerdem einer auf Name+ID. Kommt also darauf an, wie intelligent MySQL ist.

Hast du ein eigenes Feld "Name+ID" in der Datenbank angelegt, um darauf einen Index zu setzen? Warum dann noch concat() nehmen, sortiert doch dann einfach nach diesem Feld. Ist allerdings eine unnötige Redundanz.

Der Index ist ein Kombinationsindex NAME(20),ID Das Namensfeld kann bis zu 70 Zeichen enthalten. Das will ich noch untersuchen, wann MySQL den Index überhaupt einsetzt.

Ok, dann mal konkret in PHP, wie ich eine Suchmaschine in der Datenbank realisiert habe (gekürzt - und bitte keine Sicherheitsdiskussion über ungeprüfte Variablen :) ):

$sqlquery="SELECT * FROM tabelle WHERE textcontainer1 LIKE '%$suche%' ORDER BY artikelkey DESC LIMIT $show,".($resultperpage+1)."";

$suche enthält den Suchbegriff

$show enthält den Datensatzzeiger der ansagt, welcher Ausschnitt

Show enthält eben keinen Datensatzzeiger auf die Tabelle, sondern einen Offset für das neue Resultset, dass aus der Abfrage erstellt werden soll. Also auf die gerade in Vorbereitung befindliche Ergebnismenge. Durch die Verarbeitsroutine der DBE rauschen alle Sätze durch und werden auf Erfüllung des Kriteriums untersucht. Wenn Ein Index benutzt werden kann, und da bin ich mir in meiner Sache ziemlich sicher, dass die DBE das erkennen sollte, kann

a. der Aufsetzpunkt in der Tabelle geschickt wählen
b. brauchen der Auswahlprozedur keine Sätze zugeführt zu werden, die überhaupt nicht passen
c. wird erkannt, wann der zu untersuchende Bereich der Tabelle garantiert beendet ist, nämlich wenn des nächste Index-Item größer ist, als das Suchkriterium (Das geht bei Dir batürlich nicht, da Du %bla% suchst, also es kein "Größer" gibt.)

Ich mache aber eine Feldanfangsuche. Das sollte MySQL können. Wenn nicht, nehme ich eben Informix. Liegt schon über drei Jahre hier nutzlos im Haus rum. Update bekomme ich (hoffentlich) noch kostenlos.

der Tabelle geholt werden soll

$resultsperpage enthält die Anzahl der Ergebnisse pro Seite.

Den $sqlquery an die Datenbank senden.

$anz =  mysql_num_rows(...);

Anzahl der Ergebnisse feststellen.

for ($erg=0;$erg<$resultperpage;$erg++)
{

Datensätze ausgeben - man merke, daß in der SQL-Abfrage ein Datensatz

mehr angefordert wurde, als hier ausgegeben wird.

}

Der Trick ist ganz gut.
Das habe ich soweit verstanden.

Du benutzt immer den selben String $suche und da liegt der Haken. Deine Lösung berücksichtigt keine dynamisches Datenverhalten. Es können von Bearbeitungsschritt zu Bearbeitungsschritt Sätze hinzukommen oder welche wegfallen, weil wir ja in einem ziemlich großen Netzwerk arbeiten und viele Leute unterschiedlichste Zugriffsrechte auf die Tabellen haben.

Wenn Sätze in den eben von Dir bereits betrachteten Berich eingefügt werden, passiert folgendes:

$ShowPerPage=7   // damit das hier nicht so lang wird
$show = 7        // von 0 bis 6 haben wir gerade bearbeitet.

@1 bei A      @1+x bei B     @2 bei A        2>1+x = Zeit
0-7           seine 0-7      seine 8-15
------------- -------------- --------------
Adam          Adam           Hilde
Emil          Emil           Holger
Franz         Fritz          ...
Fritz         Fritz
Fritz         Günter
Fritz         Günther
Günter        Hans
Günther       Heinrich

Hans          Hilde
Heinrich      Holger
Hilde         ...
Holger
...

Hans und Heirich fallen also unter den Tisch und werden nicht bearbeitet. Das fällt auch nicht weiter auf. Sie wären aber nun an der Reihe gewesen... Der Fehler fällt nur dann auf, wenn man allen zur Bearbeitung anstehenden Datensätzen einen Timestemp verpasst, auch wenn gar nix geändert wurde. Dann kann man später diese Fehler finden. Genauso findet man ja auch dann die Datensätze, die während der Bearbeitung eingefügt worden sind. Die wären aber von der Bearbeitung her sowieso noch nicht dran gewesen (Beispiel Mahnfrist abgelaufen, Wiedervorlage beim Verkauf, usw).

Ich habe mir das Leben deshalb so schwer gemacht, weil ich eine Lösung für das Holen eines aktuell gültigen Resultsets gesucht habe. Das geht nur, wenn man die DATEN des aktuell angezeigten/bearbeiteten Datensatzes in die nächste Suche aufnimmt.

Ich denke aber, ich werde doch einen zweigeteilten Anzeigebildschirm aufbauen. Obereres Frame = Liste. Die kann ja sogar gescrollt werden. Unterer Teil Detaildatensatz zur Bearbeitung, Hinzufügen, Löschen etc. Die Liste bleibt solange stehen, bis der Benutzer eine neue anfordert, wird auch nicht Updatetd. Muss der Benutzer sich eben merken, wenn er einen Satz aus der Liste gelöscht hat. Wenn er den nochmal aufruft, bekommt er eben eine Warnung.

Insofern hat mich Deine Ausführung also wieder ein Stück weitergebracht. Ich war da sehr am Schwanken. Ist jetzt die Frage, ob ich das Einzelblättern überhaupt einbaue oder nur listenweise blättere.

Wahrscheinlich werde ich für verschiedene Anwendungsfälle beide Möglichkeiten brauchen.

Es hat etwas von Sandsackboxen gehabt bisher.

Ja, ich geb ja zu, dass ich etwas zu dick geworden bin :-)

Wie gut du in den Datensätzen blättern willst/kannst, hängt von dir ab. Es wäre ohne Probleme möglich, 20er-Blöcke in einen Frame zu laden und anhand der ID des Datensatzes dann den einzelnen Datensatz in einen anderen Frame. Oder die betroffenen, kompletten Datensätze schon gleich mitzuübertragen. Ich denke, mit meinem System bist du da ziemlich flexibel, was die Datensatzzahlen angeht. :)

Für meine Kundendaten-Bearbeitung werde ich diese Möglichkeit nehmen. Ist auch ergonomsich und relativ leicht zu verstehen für den Benutzer.

Bis denne.

Tom