Sliding windows

hi,

kennt jemand einen algo. mit hilfe dessen man in datenbanken mit sql statements vor und zurückblättern kann.

der algo sollte auch unter jeder bedingung funktionieren, d.h. z.b. dass der aktuelle datensatz gelöscht wurde.

gruss tobias

Meinst Du sowas in der Art ?

http://www.spaceweb.ch/asp/db_navigation

Gruss

Christian

ja genau, nur mit sqlstatements und nicht mit move…
hast du das schon mal bei einer db mit 250.000 ds ausprobiert? geht es da auch noch schnell?

gruss tobias

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]

ja genau, nur mit sqlstatements und nicht mit move…
hast du das schon mal bei einer db mit 250.000 ds ausprobiert?
geht es da auch noch schnell?

Ne habe ich nid…aber ich werde mal schauen, dass ich so gegen 250’000 Einträge in ne DB reinbringe *g*

Ich schau mal, wenn ichs habe mache ich hier ein Posting *g*

wäre cool. danke!!!

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]

Guten Morgen…

Ich habe mir noch einwenig Gedanken über Dein Problem gemacht… folgendes ist dabei rausgekommen:

HINWEIS:
Alle Überlegungen sind REIN THEORETISCH und ich weiss nicht, ob und wie das in der Praxis funktionieren würde :smile:

Also…nehmen wir mal an Du hast ne DB mit 5 Einträgen:

Eintrag: Datum:
Eintrag1 Datum1
Eintrag2 Datum2
Eintrag3 Datum3
Eintrag4 Datum4

Wenn Du nun mit einem SQL-String die DB abfragst und die DB solange durchläufst bis Du bei Eintrag X bist, kann der Server ziemlich belastet werden (beispielsweise bei 1’000’000) Einträgen.

Also gilt es eine Möglichkeit zu finden, damit wir nicht ALLE Daten durchsuchen müssen. Dazu mach ich ne andere DB:

Counter: Eintrag: Datum:
1 Eintrag1 Datum1
2 Eintrag2 Datum2
3 Eintrag3 Datum3
4 Eintrag4 Datum4
5 Eintrag5 Datum5

Wie man sieht hat es nun noch eine Zahl als neues Feld. Ich weiss jetzt nicht genau was passiert wenn man das Feld „Zahl“ mit einem Autowert belegt. Falls es einfach die zahlen IMMER raufzählt (also auch wenn ein Eintrag gelöscht ist), dann könnte man das so machen…

Nunja… dann machen wir einen SQL-Request, welcher im Stil von „WHERE Zahl = X“ gehalten ist. Anschliessend wird geprüft, ob ein Resultat erziehlt wurde (if recordset.bof = false and recordset.eof = false then…). Falls ein Resultat erziehlt wurde, wird dieses ausgelesen. Andernfalls wird einfach der Wert X um eins erhöht und der Check wiederholt. Dies aus dem Grund, dass beispielsweise der dritte Eintrag gelöscht wurde und man nun vom zweiten zum nächsten (= vierten) springen möchte:

Counter: Eintrag: Datum:
1 Eintrag1 Datum1
2 Eintrag2 Datum2
4 Eintrag4 Datum4
5 Eintrag5 Datum5

Das Problem ist jetzt aber, dass wenn man beispielsweise 1’000’000 Einträge hat, dann 500’000 löscht und wieder 250’000 hinzufügt, dass man dann tatsächlich 750’000 Einträge hat. Die höchste Zahl wird dann aber 1’250’000 sein (1’000’000 + 250’000). Von diesen 1’250’000 Einträgen sind aber jetzt eben 500’000 gelöscht. Nehmen wir folgendes an:

VORHANDEN:
1 - 499'999, 1'000'001 - 1'250'000
GELOESCHT:
500'000 - 1'000'000

Jetzt angenommen der Benutzer befindet sich beim Eintrag 499’999 und springt zum nächsten. Dies würde bedeuten, dass 500’000 Checks durchgeführt würden bis BOF=False und EOF=False sind. Ist natürlich sehr aufwendig. Es gilt nun also, dass wir diese Lücke umgehen.

Die eine Variante ist, dass wir den Zähler nicht automatisch aufzählen, sondern dass wir die gelöschten Einträge (nehmen wir an Nr. 22) einfach wieder „überschreiben“. So würden die Löcher immer wieder „gestopft“. Ist aber meines erachtens relativ komplex.

Die andere Variante ist tatsächlich einfach alle Checks zu machen - ich weiss aber nicht wie zeitaufwendig dies tatsächlich ist.

Hmmm…was also tun ?

Nehmen wir mal folgende Tabelle:

Counter: Eintrag: Datum: Prev: Next:
1 Eintrag1 Datum1 0 2
2 Eintrag2 Datum2 1 3
3 Eintrag3 Datum3 2 4
4 Eintrag4 Datum4 3 5
5 Eintrag5 Datum5 4 0

Wir haben nun noch zwei zusätzliche Felder. Die beiden Felder geben an, welches das vorherige und das nächste Feld ist. Jetzt wird beispielsweise Eintrag 3 gelöscht. Dann müsste der vorherige und der folgende Eintrag geändert werden. Das Resultat würde wie folgt aussehen:

Counter: Eintrag: Datum: Prev: Next:
1 Eintrag1 Datum1 0 2
2 Eintrag2 Datum2 1 4
4 Eintrag4 Datum4 2 5
5 Eintrag5 Datum5 4 0

D.h. bei jeder Löschung müssten zwei andere Datensätze geändert werden (vorheriger & folgender), beim hinzufügen eines neuen Datensatzes müsste ein Datensatz geändert werden (vorheriger).

Das ändern der Datensätze müsste natürlich aufgrund der PREV und NEXT Einträge des aktiven Datensatzes erfolgen.

Letztendlich müsste dem Formular (oder auch der URL) der Wert von NEXT und/oder PREV mitgeteilt werden, damit dies dann beispielsweise beim Klick auf > verwendet werden kann.


Ich weiss, es ist ziemlich komplex und ich bin mir SICHER, dass es einfachere Lösungen gibt. Aber ich denke es ist eine Art Workaround und es sollte eigentlich machbar sein…

Bei Fragen einfach hier posten…

Viele Grüsse

Christian

2 Like

hi leute…

ich möchte mich aufs vorherige posting berufen.
also eins ist klar: wenn wir eine zusätzliche zahlen-spalte in der tabelle haben (nebst der autoID), welche auch ein autowert ist, so bringt das nichts mehr.
ein autowert geht immer um 1 rauf (in sql-server je nach seed), jedoch immer kontinuerlich.

wenn wir also die tabelle haben:

AutoID (AW/ID) Name (Text) Zahl (AW)
========================================
1 Rudolf 1
2 Hans 2
3 Pascal 3

usw…

löschen wir nun record 3, haben wir noch:

AutoID (AW/ID) Name (Text) Zahl (AW)
========================================
1 Rudolf 1
2 Hans 2

schon hier sehen wir, dass wir keine verfolgbare nummer mehr haben. fügen wir jetzt mal einen neuen datensatz hinzu, wird das so aussehen:

AutoID (AW/ID) Name (Text) Zahl (AW)
========================================
1 Rudolf 1
2 Hans 2
4 Testeintrag 4

autowerte steigern sich also immer mit 1, jedoch sind sie auch immer einmalig (jedenfalls, wenn’s ne id ist, bzw key)

bei mehr oder weniger statischen daten sollte dein vorhaben aber kein problem darstellen…

wenn du ne db hast, wo immer neue records dazukommen (jedoch nichts gelöscht wird), kannst du’s problemlos machen…

einfach ein query machen und das recordset desc nach der zahlen-spalte sortieren (ORDER BY Zahl DESC), so hast du die höchste zahl zuoberst.
nun zählst du zu dieser obersten zahl noch eins dazu und hast den wert, welchen du in die zahlen-spalte des neuen datensatzes setzen kannst, so kannst du „manuell“ eine fortlaufende nummer machen in der db…

bye dn

hi leute…
wenn du ne db hast, wo immer neue records dazukommen (jedoch
nichts gelöscht wird), kannst du’s problemlos machen…

einfach ein query machen und das recordset desc nach der
zahlen-spalte sortieren (ORDER BY Zahl DESC), so hast du die
höchste zahl zuoberst.
nun zählst du zu dieser obersten zahl noch eins dazu und hast
den wert, welchen du in die zahlen-spalte des neuen
datensatzes setzen kannst, so kannst du „manuell“ eine
fortlaufende nummer machen in der db…

Ist ja so ziemlich das gleiche wie ich gesagt habe. Das Problem ist aber, wenn es 1000 Einträge sind und Du die Einträge 250-750 löschst, dann hast Du ja noch 500 Einträge. Der erste hat die ID 1, der letzte die ID 1000…

Wenn Du nun aber die DB durchsuchst (per Webbrowser) und dazu einfach die Buttons [] verwendest und jedesmal die DB neu öffnest, hast Du ein Problem, da Du ja nicht weisst, was nach dem 250sten Eintrag kommt. Also zählst Du den Counter bis 750 rauf -> nimmt verdammt viel Zeit in Anspruch…

Ich denke Du hast das Problem nicht ganz verstanden. Lies nochmals meine Ausführung oben nach…

Viele Grüsse

Chris

hi

freut mich das dieses thema so viel interesse weckt.

ich hab mir die letzten wochen auch intensiv gedanken darüber gemacht. das problem ist nicht so einfach zu lösen. ich möchte noch zu bedenken geben, dass die liste nicht immer so aussehen muss wie sie in den vorherigen postings aussieht. folgende liste ist realistischer:

ID NAME VORNAME
1 Aberl Egon
5 Aberl Martin
8 Aberl Xaver
4 Maier Thomas
2 Xyver Adam

(sortiert nach name, vorname)

hat jemand ne idee wie es in einer solchen liste möglich sein soll zu blättern, wenn der aktuelle datensatz verloren geht.

eine möglichkeit, die ich zur zeit mit hochdruck verfolge ist das speichern der 10 vorherigen und der 10 nachfolgenden id’s. das ist zwar nicht superschön aber praktikabel.

was haltet ihr davon? oder hat jemand in der zwischenzeit ne bessere lösung?

vielen danke
tobias

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]

Guten Morgen…

Da steht man gemütlich auf, startet den Compi und checkt seine Mails. Und was muss man sehen ??? Ein Mail von w-w-w :smile:

Aber nein…es könnte ja nid ein „normaler“ Beitrag sein, es muss einer sein, der mir jetzt wieder das ganze Weekend keine Ruhe lässt :smile:))

Es kann doch wohl nicht sein, dass für solche simplen Sachen in heutigen Datenbanken KEINE, aber auch KEINE vernünftige Lösung existiert…

Dein Beitrag hat mir zu denken gegeben - ist ja logisch…wenn man ein anderes Sortierungskriterium verwendet, dann wird auch die Reihenfolge anders *snief*…

Ich überleg mir mal ob es noch eine andere Lösung gibt…

Bis dann dann

Chris

hi, freut mich das du auch am samstag mal in deinen briefkasten schaust,

hast du icq, damit wäre es wesentlich leichter zu kommunizieren.

gruss tobias

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]

Jo ich habe ICQ…

Meine UIN ist: 101393073

Schreib mir doch bitte im Request, dass Du von w-w-w bist, da ich nid einfach jeden Deppen adde :smile:

btw: Ich checke meine Mails im Schnitt so alle 1-2h, am Weekend meistens (wenn ich Zuhause bin) sogar dauernd… :smile:

Viele Grüsse

Chris

Guten Morgen :smile:

Nun…ich habe mir mal wieder einwenig Gedanken dazu gemacht. Das ganze wiederum nur rein theoretisch - ich weiss nid ob das dann auch wirklich so geht mit ASP :smile:

Also…
Zuerst mal zu Deiner (neuen) Lösung. Ich finde dies nicht so gut, da Du ja trotzdem bei jedem neuen Request die Liste der +/- 10 Einträge aktualisieren musst. Also hast Du genausoviel traffic (wenn nicht noch mehr)…

Hmmm… ich habe mal etwas gelesen von wegen Cursor in einem Recordset - ich muss mir echt mal ein ASP-Datenbankbuch kaufen und das weiterverfolgen… bin mir aber nicht sicher ob es wirklich so das ist :smile:

Also…nun aber zu meiner eigentlichen Lösung:

Hinweis
_Ich habe den Code möglichst klein gehalten, damit es nicht zu komplex wird. Jegliche Fehlerüberprüfung (beispielsweise ist die DB leer, verbunden, etc.) wird *NICHT* durchgeführt!!!

Ausserdem kann es sein, dass die Syntax teilweise nicht stimmt - ich mache das alles aus dem Kopf und habe es (noch) nicht ausprobiert…_

Nehmen wir an Du hast die folgende Tabelle:

ID (Autowert): Name: Vorname:
1 Stampfli christian
2 Müller peter
3 Red bull
4 Tele phon
5 Coca cola
6 Moni tor
7 Tasta tur
8 Mauro picotto

Oki… also… jetzt nehmen wir mal an der Besucher startet bei ID=1. Nun klickt der Besucher auf [>], will also zum nächsten Eintrag (in diesem Beispiel ID=2)!

Okay…dann machen wir was in der Art von:

recordset.movefirst // wir gehen zum ersten Eintrag
x = 1

while recordset("ID") request.querystring("ID") do
 x = x + 1
 recordset.movenext
loop

Wenn die ID gefunden wurde, hat x einen bestimmten wert… In unserem Fall wäre x = 1 (weil ja die aktive ID=1 ist!). Nun will der User zur nächsten. Also folgenden Code:

recordset.movefirst
y = 1
while y x+1 do
 y = y + 1
 recordset.movenext
loop

Die Schlaufe wird nun solange wiederholt bis y den Wert x+1 (=2) annimmt. Dann wird die Schlaufe beendet und man kann die Daten auslesen. Das ganze funktioniert natürlich auch umgekehrt mit x-1 etc…

Es ist meines Erachtes auf jeden Fall die Lösung, welche am wenigsten Ressourcen benötigt (von allen bisherigen Lösungen). Zudem ist es auch kein Problem bei Sortierungen, da es ja keine „statischen“ Werte wie NEXT_ID, PREV_ID oder so gibt. Es wird alles dynamisch gecheckt :smile:

Und das prüfen ob x = Recordset(„ID“) ist auch nicht so aufwendig, da es ja eh „nur“ zahlenwerte und nicht 200 zeichen lange strings sind :smile:

Angenommen User A lädt ID=4, schaut sie an. Während dieser Zeit löscht User B die ID=5. Wenn User A nun auf [>] klickt, kommt automatisch ID=6 dran… ist also auch kein Problem.

Ich weiss leider nicht wie das ganze bei 1’000’000 Datensätze funzt (zeitlich). Aber ich denke es sollte nicht soooo ein Riesending sein :smile:

Bitte Feedback dazu :smile:

Chris

1 Like

hi chris,

deine lösung geht, steigt jedoch linear mit der datenbank an.

wenn ich deine liste mal alphabetisch im feld name sortiere kommt folgendes raus:

ID NAME
5 Coca
8 Mauro
6 Moni
2 Müller
3 Red
1 Stampfli
7 Tasta
4 Tele

so, nun steigt man bei id=1 (x=1) ein. nach deinem schema käme jetzt als nächster datensatz id=2 (x+1=2). in wirklichkeit kommt aber id=7.

dies nur als beispiel für eine sortierung nach name. sortieren wir nun nach vorname oder jedem anderen noch in der db vorhandenen feld, dann kommt als nachfolgender datensatz zu id=1 immer ein anderer raus.

insofern funktioniert diese lösung nur wenn die db auch nach der id sortiert ist.

in realität will der anwender aber nach name, vorname, ort, plz sortieren. eventuell noch ineinander verschachtelt mit sortierungshirachie (z.b. 1. name, 2. vorname, 3. ort, 4. id).

ich hoffe du weisst auf was ich hinaus will.

sorry das ich so lange für die antwort gebraucht habe.

bis dann. würde mich freuen wenn du mir zu meiner meinung ein kommentar gibst.

gruss tobias

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]

tataaaaa… :smile:

ich habe mal ein bisschen gebastelt… einen ersten entwurf (hat aber nicht allzuviel fehlerkorrektur) findest du hier:

http://www.spaceweb.ch/asp/db_navigation2/db_navigat…

Der Quellcode:

http://www.spaceweb.ch/asp/db_navigation2/db_navigat…

Viel Spass

Chris

1 Like