Sven Rautenberg: MySQL: Workaround für NEXT und PREVIOUS gesucht

Beitrag lesen

Moin, Tom! :)

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.

So langsam verstehe ich, wo dein Problem liegt. Und in der Tat: Ja, das Geblättere von Blöcken hat ein Problem, wenn neue Daten dazukommen oder verschwinden. Solch ein Problem hast du aber immer, wenn du Seitenweise (und nicht einzeln) blätterst, auch bei deiner Methode. Es braucht ja nur ein Eintrag hinzuzukommen, der laut Sortierung eigentlich auf der derzeitigen Seite angezeigt werden müßte. Das kann man wirklich nur durch Einzelblätterung vermeiden.

Hm, muß ich noch mehr kommentieren? ... mal gucken.

$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.

Ein Zeiger ist etwas, was zeigt. In diesem Fall auf den ersten Datensatz der auszugebenden Liste, basierend auf den Daten zum Zeitpunkt der Abfrage. :) Etwas, was auf Datensätze zeigt, ist ein Datensatzzeiger. :) Das Problem ist nicht der Zeiger, sondern was man in der Zukunft damit macht.

Durch die Verarbeitsroutine der DBE rauschen alle Sätze durch und werden auf Erfüllung des Kriteriums untersucht.

Wobei anzumerken ist: Wenn du nach meiner Methode in der gesamten Datenmenge blättern willst, brauchst du gar kein Kriterium anzugeben.

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

Ich vermute, der Unterschied zwischen meinem Ansatz, alle Datensätze zu sortieren und nur einen Ausschnitt zu holen, und deinem Ansatz, nur die nachfolgenden/vorhergehenden Datensätze abzufragen, zu sortieren und einen Ausschnitt zu holen, dürften annähernd identisch performen. Dein Ansatz hat den Vorteil, daß die zu sortierende Menge kleiner sein kann (durchschnittlich nur 50% meiner Datenmenge), aber den Nachteil, daß ein Kriteriums verglichen werden muß.

b. brauchen der Auswahlprozedur keine Sätze zugeführt zu werden, die überhaupt nicht passen

Wenn man alle Datensätze haben will, kommt man nicht drum herum, alle Datensätze anzugucken. :)

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.)

Ähm???

Ich denke, es gibt für unsere beiden Ansätze ein ganz grundlegendes Problem: Die gedachte komplette Liste der Datensätze kann sich mittendrin ändern. Das bedeutet, daß ein "Blättern" natürlich nicht mehr so möglich ist, daß man alle Datensätze erhält. Dies ließe sich nur dadurch vermeiden, daß die eindeutige, bei jedem Datensatz incrementierte ID als einziges Sortierkriterium herangezogen wird - nur dann sind vorhergehender und folgender Datensatz eindeutig definiert: Es ist der nächste existierende Datensatz, dessen ID kleiner oder größer als die derzeitige ID ist. Neue Datensätze werden am Ende der Liste angefügt. Man könnte also solange den nächsten Datensatz anfordern, bis keiner mehr kommt. Und nach einer Wartezeit wäre vielleicht wieder einer da.

Basierend auf dieser Überlegung dürfte klar sein: Ein Blättern in einer Namensliste ist so unmöglich hinzukriegen, da es immer doppelte Namen geben wird. Und auch wenn du basierend auf dem Namen und der ID ein eindeutiges Sortierkriterium generierst, hast du immer noch das unlösbare Problem, daß neue Datensätze, wenn sie in der gewünschten Sortierung eingeordnet werden sollen, urplötzlich mitten in der Liste auftauchen.

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.

Die verwendete Datenbank löst allerhöchstens Performanceprobleme, nicht dieses logische Problem. :)

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.

Ja, die Gleichzeitigkeit ist ein Problem. Die Frage ist doch: Was soll per Blättern geschehen? Einen Datensatz bearbeiten? Das ist total unabhängig von anderen Datensätzen. Einem "Datensatz" eine Rechnung schicken? Auch kein Problem, wenn diese Aktion anderweitig ausgelöst wird, beispielsweise durch Vorliegen von Papier (Außendienstservicemeldung). Allen Datensätzen die Mitgliedsbeiträge abbuchen? Das wäre dann eher keine Aktion, die man per "Durchblättern" erledigen könnte.

Die einzige mir einleuchtende Lösung für solche Bearbeitungsschritte, die für alle Datensätze erledigt werden müssen, aber aus irgendwelchen Gründen nicht gleichzeitig erledigt werden können, wäre, daß man eine weitere Tabelle (oder Spalte - aber das könnte problematisch werden, weil zu starr) mit Statusmeldungen anlegt, in der genau verzeichnet wird, was mit welchen Datensätzen geschehen ist. Auf diese Weise findet man schnell heraus, welche Datensätze noch zu bearbeiten sind.

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

Weiß ich. War bei meiner Anwendung kein Problem.

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.

Tja, dein Leben ist schwer, und eine richtige Lösung ist garnicht machbar - die Welt ist ungerecht.

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.

Bleibt das oben erwähnte Problem: Was ist, wenn ein Datensatz, der auf diese Seite gehören würde, hinzukommt? ;)

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.

Flexibilität ist was feines.

- Sven Rautenberg