Michael Schröpl: MySQL: Workaround für NEXT und PREVIOUS gesucht

Beitrag lesen

Hi Tom,

Das interessiert mich auch nochmal. Ist das resultset unter MySQL ein
Dynaset oder ist es ein Snapshot?

könnte das nicht massiv vom verwendeten Tabellentreiber (und dessen
Transaktionssicherheit) abhängen?

Bei solchen Fragen antworte ich eigentlich mechanisch: "mySQL existiert
gar nicht wirklich - was existiert, das ist eine Menge von Tabellen-
treibern, die alle unterschiedlich viel können".

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.
Genau das isses!

Dann muß der Trick darin bestehen, bei der nachfolgenden Anfrage nur
noch relevante Datensätze zu berücksichtigen (siehe unten).

Das bedeutet, daß ein "Blättern" natürlich nicht mehr so möglich
ist, daß man alle Datensätze erhält.

Eventuell schon ...

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.
Doppelte Namen sind durch die Verbindung mit der ID überhaupt kein
Problem mehr.

Genau. Und ein Primärschlüssel (oder überhaupt ein UNIQUE INDEX) darf
ja sehr wohl auf einer Liste von Spalten liegen (was die ID erspart).

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.

Doch - Du mußt nur eine entsprechende Buchführung machen (siehe unten).

Die einzige mir einleuchtende Lösung für solche Bearbeitungs-
schritte, 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)

Finde ich nicht. Eine separate Tabelle fände ich viel schlimmer (weil
Du dann JOINen mußt). Wenn ein Datensatz genau einen Zustand haben
kann, dann gehört dieser m. E. zwingend in die Tabelle selbst hinein
(wegen der sauberen relationalen Zerlegung).

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.

Genau.

Bisher haben wir immer das Blättern in beide Richtungen als Aufgaben-
stellung gesehen. Wenn es aber darum geht, sequentiell alle Datensätze
zu verarbeiten, dann sieht die Aufgabenstellung völlig anders aus.

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

Stell Dir mal folgendes vor:
1. Du hast eine Spalte mit einem Zustand (boolean-Flag reicht für unsere
   Zwecke).
2. Zu Beginn der allgemeinen Abbuchung wird dieses Flag für alle
   existierenden Datensätze gelöscht; für neu angelegte wird es per
   Default auf "gelöscht" gesetzt.
3. Niemand außer Deiner Anwendung ist befugt, dieses Flag zu verändern.
4. Es esistiert ein UNIQUE Index über das Tripel (!) aus Flag, Name
   und ID.
5. Jeder Zugriff auf einen Datensatz der Tabelle sucht denjenigen, der
   das Flag nicht gesetzt hat und für die beiden anderen Datensätze
   den kleinstmöglichen Wert enthält. Ein so bearbeiteter Datensatz
   wird aber mit verändertem Flag zurück geschrieben.
   Wir blättern also nicht dadurch, daß wir uns die Vorgängerposition
   merken - wir "verbrauchen" einfach alle Datensätze mit gelöschtem
   Flag! Dabei ist uns völlig egal, ob neue Datensätze hinzu kommen -
   wenn wir beispielsweise beim Buchstaben N sind und ein neuer Name
   mit A eingetragen wird, dann bekommt der Bearbeiter als nächsten
   Datensatz diesen angeboten, weil er ja nun der kleinste "ungeflagte"
   ist.
Auf diese Weise werden definitiv alle Datensätze sequentiell bearbeitet

  • zwar nicht zwingend in alphabetischer Reihenfolge ihrer Namen, aber
    so gut wir möglich.

Der Trick dabei ist, daß jeweils nur ein einziger, sehr performanter
Abstieg in den entsprechenden Indexbaum notwendig ist, um den nächsten
Datensatz zu finden - _wenn_ das Flag das _erste_ Feld des entsprechenden
Indexbaums ist! (Alle geflagten Datensätze werden gar nicht erst ange-
sehen, und von den ungeflagten eben wirklich nur der "ganz linke".)
Der Preis dafür ist natürlich, daß jede Änderung eines Datensatzes eine
Verschiebung innerhalb dieses Indexbaums kostet ... und daß der Index-
baum entsprechend schnell degenerieren wird. Aber den brauchen wir ja
nur für diese Bearbeitung und können ihn anschließend wegwerfen.

Natürlich darf niemand gleichzeitig einen solchen Datensatz ändern und
dabei unser Flag versehentlich zurücksetzen - das Verfahren verlangt
nach einem transaktionssicheren Tabellentreiber.

Viele Grüße
      Michael