German Content richtig aus Datenbank laden

Alexander Stolte

Expert
Licensed User
Longtime User
Guten Tag,

Ich habe folgendes Problem und benötige ein paar Tipps von jemanden der mehr Erfahrung in dieser Thematik hat wie ich. Meine aktuelle Technik ist folgende, ich hole meinen Content aus der Datenbank via RDC, aktuell hole ich alles auf einmal, dass kann schon einmal länger dauern wenn die Internetverbindung langsam ist und Daten-schonend ist diese Variante auch nicht.

Daher meine Frage, wie ist die Technik bei anderen Apps, diese holen ja auch nicht den gesamten content auf einmal, sondern nach und nach.

Ist es die bessere Variante wenn ich zuerst nur einen Datensatz aus der Datenbank hole und dann per schleife alles nach und nach zusammen mit dem Timestamp? bzw wenn ich am ende der Liste bin, dass er dann erst weiteren content laden soll? Was das angeht bin ich noch sehr blau hinter den Ohren.
 

pucki

Active Member
Licensed User
Naja da der Speicher auf mobilen Geräten immer noch sehr niedrig ist (es gibt tatsächlich Geräte mit unter 2 GB freien "Festplattenspeicher") würde ich persönlich nur sql-Abfragen an die Datenbank senden, die Info verarbeiten und dann killen. Je genauer die Abfrage ist, je weniger Daten muss ich übertragen.

Nur mal so als Beispiel. Wenn du www.xxxx.yyy in dein Browser eingibst wird NICHT die ganze Seite auf einmal geladen. Es wird ein kleiner Text (HTML-Datei) geladen, und dort stehen dann teilweise bis zu 100 und mehr Anfragen drin (mit eigenen http Adressen). Und die werden dann gemütlich und blitzschnell nachgeladen. Je nach Einstellung des Browsers werden dann gewisse Infos auch übersprungen.

Davon abgesehen haben hohe Datenmenge riesige Nachteile. (Datentraffic / Zeit / Speicher)

Die App's die ich kenne fragen Pakete an Daten an (via SQL-Abfragen) und mit einer gewissen Voraussicht sofern das möglich ist. Davon abgesehen sind kleine Abfragen für ein Server einfacher zu handeln.

Also mach es wie dein Browser. Schick jede Menge kleine Anfragen an die Datenbank. Die kann das ab ;) Aber nicht übertreiben. Die Anfrage soll logisch und klug aufgebaut sein und nur PERFEKT die Infos liefern die und JETZT brauchst und NICHT die Infos die du möglicherweise in einigen Minuten brauchst.

Soweit ich dein Problem verstanden habe, schickst du einfach eine Anfrage die sagen wir 20 Datensätze liefert und wenn mehr gebraucht werden im Päckchen zu wieder 20 nachladen. Du siehst das oft wenn du in Listenmodulen bist, du scrollst nach unten und plötzlich hängt das Teil. Da zieht er sich neue Daten nach einfach die Abfrage wiederholen mit den Zusatz where Index > index_letzter_datensatz_im_Speicher .

Und bitte nicht böse sein, aber kauf dir mal ein kleines Buch mit den Befehlssätzen von SQL. Hab ich auch gemacht, und hat mir riesig geholfen. Dadurch habe ich viel Programmcode an die Sql-Datenbank ausgelagert in den ich die Analyse von Datensätzen in die Abfrage gepackt habe.

Gruß

Pucki
 
Last edited:

rboeck

Well-Known Member
Licensed User
Longtime User
Kann nur zustimmen - für mich die dümmsten Anfragen sind immer die, wo jemand im Ernst fordert, dass er 20.000 Kundendatensätze auf einmal lesen will. Welcher Anwender kann am Mobilgerät 20.000 Adressen lesen? Daher analysieren, was wirklich in diesem Moment benötigt wird und eventuell im Hintergrund weitere Daten nachladen. Der Benutzer muss auf seine Anfrage sofort beschäftig sein, danach ist wieder Zeit...
 

rboeck

Well-Known Member
Licensed User
Longtime User
Meine Antwort war nicht auf dich bezogen - du machst Dir ja Gedanken, wie man es optimiert darstellen kann, sondern auf jene, die "mit Gewalt" Unmengen von Daten anfordern, die ohnehin nicht gelesen werden können.
 

pucki

Active Member
Licensed User
Genau, Gedanken machen ist immer gut. Leider tuen das die für die ich manchmal arbeite nicht. Dann kommt es zum "das merkt man erst wenn der Programmierer fertig ist" Effekt.

Und was die Technik angeht. Genau DIE hab ich dir beschrieben. Es gibt keine Super-Libary mit der man alles regeln kann. Das Zauberwort heißt halt Codeoptimierung. Und ein Tipp dazu. Codeoptimierung ist nur solange Sinnvoll in den man sich nicht selbst verfranst. Was im Klartext heißt Notfalls die ein oder andere Sub komplett neu schreiben.

Gelehrt wird so was mit Ablaufdiagrammen und die Optimierung dieser Diagramme. Zwar hat man im einen modernen PC !!! Speicherplatz und auch Arbeitsplatz ohne Ende. Allerdings liegt das daran das OS wie Windows Speicher künstlich erzeugen (Auslagerungsdatei). Da du auf einen Mobilen Gerät halt kein Speicher "zaubern" kannst, bleibt dir nur meine oben beschriebene Möglichkeit.

Ich meine mit kleinen Päckchen die durch optimale Datenabfragen erzeugt werden die Infos zu bekommen. Wichtig ist dabei auch die Reihenfolge in der die Daten geliefert werden. Ich versuch es mal an einen Beispiel.

Hier mal eine Abfrage mit ein Limit von 20

ERSTE ABFRAGE !!!

Select from my_tabelle limit 20 where Name = like '%Pete%' order by Name, ID

Jede weiter Abfrage
Alt_index = letzter Wert des Indexes(ID)

Select from my_tabelle limit 20 where Name = like '%Pete%' and Index > alt_index order by Name, ID


Hinweis : ID = die von der SQL-Datenbank automatische primäre Datensatznummerierung. Diese ist i.d.R. nicht zu löschen, und ist die perfekte Möglichkeit ein Datensatz IMMER zu identifiziern.

Fields Angaben würden möglicherweise die Größe der Datenmenge (und damit den Traffic weiter begrenzen), Index Felder beschleunigten die Abfrage

Hier mal ein Link den ich auf die Schnelle gegoogle habe. http://www.winkelb.com/index.php?id=mysql-select-limit

Es kann sein das die Sql-Abfrage von mir oben syntax mäßig nicht funktioniert da es kleiner Unterschiede bei den Versionen gibt, aber ich hoffe das Grundprinzip ist klar.

Leider schreibst du nicht wofür die Anwendung ist. Ich habe in mein letzten Beitrag geschrieben was von "in die Zukunft sehen". Also bei einen Listobjekt zeigt du 20 mit der ersten Anfrage an, und schickst schon mal die nächste Anfrage zum Server. Scrollt er hat er die nächsten 20 wenn nicht dann halt nicht. ;)

Wie schon geschrieben. Ich weiß nicht was du willst mit deiner App. Aber versuche soviel wie möglich auf den Server zu machen. Er ist größer, meist schneller und ein Profi.

Auch eine Expertenmöglichkeit wäre : Du schickst eine Script (was du von deiner App erstellen lässt) an den Server, lässt es dort ausführen und wartest auf das Ergebnis.

Gruß

Pucki
 

Alexander Stolte

Expert
Licensed User
Longtime User
Die App die ich schreibe ist ein Soziales Netzwerk. Der user kann schreiben was er will (Richtlinien konform natürlich) das kann ein Satz sein, aber auch eine Geschichte oder ein Bild. Das ist dann ein Post, zusammen mit dem Post wird die aktuelle Stadt getrackt wo sich der user befindet und in die Datenbank geschrieben, weil es ein lokales Soziales Netzwerk ist. Meine Daten die ich in der Datenbank pro Post habe sind folgende: Text, Zeitstempel, Post_ID, isPic, picture, city, comments, points, r, g, b

Das sind die Datenmengen die Pro Post zustande kommen. Sichtbar auf dem Screen für den User sind vielleicht 2 Postings bis er scrollen muss. Ab da kann man nach und nach weiteren content laden.
 

Alexander Stolte

Expert
Licensed User
Longtime User
Die App's die ich kenne fragen Pakete an Daten an (via SQL-Abfragen) und mit einer gewissen Voraussicht sofern das möglich ist. Davon abgesehen sind kleine Abfragen für ein Server einfacher zu handeln.

Ich habe dazu noch eine Frage, was ist aber wenn ich eine Grenze habe, zum Beispiel soll die App Maximal 50 Datensätze anzeigen, normalerweise würde ich nur eine Einzelne Anfrage machen, dort kann ich ja ein LIMIT setzen, dass würde ja wegfallen wenn ich kleine Anfragen an den Server sende. Wie kann man dies Handhaben? Mit einer schleife stelle ich es mir schwierig vor, da es auch sein kann, dass weniger als 50 Datensätze schon vorhanden sind.
 

rboeck

Well-Known Member
Licensed User
Longtime User
Bei kritischen Abfragen mache ich zuerst ein 'select count(.. ' mit den Bedingungen, die die kommende Abfrage erfüllen soll; damit kannst Du fix einplanen und entscheiden, da Du die Anzahl der Datensätze schon kennst, aber kaum einen Zeitaufwand hast, da Du nur die Anzahl als Ergebnis überträgst.
 

Alexander Stolte

Expert
Licensed User
Longtime User
Darüber habe ich auch schon mal nachgedacht. Man setzt ein Limit von 50, holt sich dann die ID von dem 50sten Item und dann holt man sich nach und nach bis zu dieser ID die restlichen Items.
 

pucki

Active Member
Licensed User
Nein. nicht ganz

Man fragt einen kleinen block ab. Im Beispiel unten 50 (durch LIMIT Anweisung angegeben)

Select from TABELLE Field (Feld_1,Feld_2, ID) limit 50 where Name = 1 Limit 50 order by ID ' <- so ähnlich wird das erste Packet übertragen

Die ORDER Anweisung sorgt dafür das du immer eine saubere Reihenfolge hast.

im Code (einlesen in schleife) folgende Zeile einfügen

neue_such_id = ID

in der nächste Abfrage machst du die selbe mit einer ZUSATZBEDINGUNG

Select from TABELLE Fields (Feld_1,Feld_2, ID) limit 50 where Name = 1 and ID > neue_such_id Limit 50 order by ID ' <- so ähnlich wird dann das nächste Paket
AUF ANFORDERUNG übertragen.

Tipp: Ich habe im Beispiel den Befehl FIELDS benutzt, der ist auch eine gute Möglichkeit die Datenmenge klein zu halten, weil man in der Regel sehr selten ALLE Felder des Datensatzes braucht, für die angeforderte Bedienung. Sehr beliebt sind Datenfelder im Satz die man nur mit Admin-Rechten lesen tun, wie z.B. "Zeitstempel der letzten Änderung" Für den Benutzer werden diese Felder nicht benötigt, also brauch man sie auch nicht übertragen.

Auf Anforderung z.B. in den ein Scrollfeld nach unten gescrollt wird. Dabei musst du nur das richtige Ereignis abfragen und wichtig das Limit GRÖßER setzen, als das Scrollfeld Einträge hat, damit es ausgelöst wird. ;)

Das ist alles.

Hinweis : die Befehle die ich getippt habe, sollten so ODER SO ÄHNLICH funktionieren. Ich kann nicht alles SQL-Dialekte auswendig :(

Gruß

Pucki
 

DonManfred

Expert
Licensed User
Longtime User
Select from TABELLE Field (Feld_1,Feld_2, ID) limit 50 where Name = 1 Limit 50 order by ID ' <- so ähnlich wird das erste Packet übertragen
Die Syntax ist falsch!
B4X:
select field1, field2, field3 from tabelle where fieldx='Y' ORDER BY orderfield ASC LIMIT 0,50

Der nächste Block dann

B4X:
select field1, field2, field3 from tabelle where fieldx='Y' ORDER BY orderfield ASC LIMIT 49,50
oder so...
 

pucki

Active Member
Licensed User
Die Syntax ist falsch!.

War mir schon klar. Ich benutze die Befehle so wenig das ich die Syntax oft nachschlagen muss. ;)

Zitat von mir :"Hinweis : die Befehle die ich getippt habe, sollten so ODER SO ÄHNLICH funktionieren. Ich kann nicht alles SQL-Dialekte auswendig :(

Aber DANKE das du ihm die richtigen Befehle gegeben hast, hilft ihm sicher weiter.

Meine "Rechtschreibung" ist zwar beim Programmieren besser, als bei posten, aber perfekt ist sie nicht. Aber solange ich in der Lage bin, ein Code halbwegs optimiert zu schreiben bin ich mit mir und mein Pc zufrieden ;)

Gruß

Pucki
 

OliverA

Expert
Licensed User
Longtime User
LIMIT 49,50
Hinweis: Jede Datenbank macht dass ein bisschen anders

PostgreSQL: LIMIT 50 OFFSET 49
SQLite: LIMIT 50 OFFSET 49

OFFSET: Die Zahl der Datensaetze zu ueberspringen
LIMIT: Die Zahl der Datensaetze to holen

MySQL hat zwei versionen:
1) LIMIT 50 OFFSET 49
2) LIMIT 49, 50

I'm zweiten Fall fuer MySQL ist die erste Zahl der OFFSET!
 

pucki

Active Member
Licensed User
Ich gestehe es. ;)

Ich liebe dieses Buch https://www.amazon.de/SQL-GE-PACKT-Meinhardt-Schmidt/dp/3826606868
Es löst meine Probleme wie man eine passende SQL-Abfrage macht. Ist ein reines Nachschlagewerk für SQL-syntax und so. Wenn du nicht weiß wie SQL funktioniert, ist das Buch für dich ein Buch ohne 7 Siegel ;)

Aber der Herr hat Alexander Stolte hat es auch so hinbekommen ;) Ergo alles fein, und fast alle glücklich. Ich nur fast, weil mir fehlt noch der Sack mit der Million Euro ;)

Gruß

Pucki
 

Alexander Stolte

Expert
Licensed User
Longtime User
Beim Laden weitere geordneter Timestamps, war alles kein Problem, da ich den ältesten Timestamp nehmen konnte und noch ältere dann lade konnte, da der Timestamp sich nicht mehr verändert. Meine Schwierigkeit besteht jetzt das ich das gleiche realisieren muss mit Zahlen die kleiner werden, dort besteht aber das Problem das sich die Zahlen verändern können wenn der user zu lang braucht, dann kann es passieren das ich doppelte Einträge hole. Ich habe eine Liste die, die am meisten gevotesten Einträge vom größten Wert zum kleinen sortiert. Die Zahlen können sich verändern oder es können auch viele gleiche Werte da sein. Wie gehe ich da vor?

Ich liebe dieses Buch
und ich liebe W3Schools :p
 

pucki

Active Member
Licensed User
Die Zahlen sind egal. Benutzt doch die ID als Hilfmittel.

Where ID > alte_ID and zeitstempel > xx.xx.xxxx <- Abfrage schnipsel.

Zum Thema ID.

Die Ident ist ein Super-Schlüsselfeld. Mit folgenden Eigenschaften.

1.) Sie ist nummerisch.
2.) Sie wird EINMAL vergeben vom der Datenbank selbst.
3.) Sie ist NIEMALS Doppelt.
4.) Sie kann so gut wie NICHT geändert werden.
5.) Sie ist ein Index-Feld
6.) Egal was du mit der Datenbank machst, das ID - Feld wird nicht geändert.

Hinweis : Der Name des Feldes kann in SQL geändert werden. Die Eigenschaften nicht. Access z.b. fragt nach einen Primär-Schlüssel und bei JA heißt das Feld dann automatisch ID, auch beliebte Namen sind "Schluessel". NIEMALS SONDERZEICHEN IN FELDNAMEN selbst wenn irgend ein komischer Dialekt das erlaubt.

Dies ID identifiziert den Datensatz und ist gleichzeitig ein Pointer auf den Datensatz. Dadurch das du die ID in die Abfrage rein haust, hast du immer die Position wo du bist.
Neue Datensätze haben IMMER eine höhere ID.

Also einfach die ID in fast jede deiner Abfragen mit rein und du verlierst nie die Kontrolle. Der Passus ORDER BY ID sorgt dafür das die Daten in der richtigen Reihenfolge eintreffen.
Der Zusatz ASC bzw. DESC Bestimmt ob Auf-/absteigend sortiert wird.

Mit Hilfe des ID-Feld kannst du auch EIN Datensatz ändern.

UPDATE ....................................... Where ID = aktuelle_datensatz_nr

Gruß

Pucki
 
Last edited:
Top