Seite 1 von 2

Datenbank

Verfasst: 22. Juli 2011 12:12
von janmerkschien
Hey,
ich habe einen Datenbankzugriff programmiert.
Jetzt habe ich die Aufgabe bekommen, dass immer nur ein Teil der Datenbank geladen werden soll.
Es sollen immer nur die Datensätze geladen werden die auch angezeigt werden.
So das wenn ein Datensatz nach unten gescrollt wird der nächste geladen wird und der oberste verschwindet.

Ist das i-wie realiesierbar ??
Müsste ich dafür den Scrollbalken neu Programmieren??

Hoffe mir kann jemand helfen :)

schonmal danke im vorraus Jan

Re: Datenbank

Verfasst: 22. Juli 2011 12:21
von upsala
Verwendest du ein Model? Event. sogar ein selbstgeschriebenes?

Re: Datenbank

Verfasst: 22. Juli 2011 12:24
von RHBaum
die QSqlModels in Verbindung mit nem QT View sollten eigentlich schon genau das tun ^^
Aber zum selber programmieren :

Erst mal paar Randbedingungen klären:
was verstehst du unter datenbank ?
Nen richtiges RDBMS ?
SQLite ?
BerkleyDB ?
Was eigenes ?

Bei SQL musst du dich auf die Cursors quasi verlassen, weil du nicht angeben kannst, meine Abfrage heisst soundso, nun zeig mir die datenstaetze 200-300 ... (zumindest nicht im Standard SQL)
Du kannst eigentlich immer nur die abfragemenge iterativ durchlaufen, und hoffen,das der cursor serverseitig war, das heisst immer nur die datensaetze abekommst, die auch abrufst, und nicht alles in einem rutsch uebertragen wurde ^^

Und ja, viele Wege fuehren nach ROM, mit Scrollbalken selber ausrichten, kann man schon sowas abfangen ...

Also erklaer mal wie deine GUI aussehen/funktionieren soll !
Ich nehm an, Du willst sowas wie in MS Access, diese Datensatzforumlare, die man durchscrollen kann, programmieren ...

Ciao ...

Re: Datenbank

Verfasst: 22. Juli 2011 13:58
von janmerkschien
Ich benutze Mysql mit Xampp.
Ich will ein Fenster haben wo man die Datenbank drinne sieht, dort sollen dann je nachdem wie groß das Fenster gezogen wird eine bestimmte anzhal datensätze angezeigt werden.
Da ich auf eine Datenbank zugreife die mehr als 50000 einträge hat kann man die Datenbank ja nicht immer neu runterladen deshalb sollen halt beim start die ersten 20 geladen werden und wenn man dann zb 2 spalten runterscrollt sollen die datensätzer 2-22 geladen werden.

ich hoffe ich habe deine frage beantwortet

Re: Datenbank

Verfasst: 22. Juli 2011 14:23
von RHBaum
ich hoffe ich habe deine frage beantwortet
Ich will ein Fenster haben wo man die Datenbank drinne sieht

:twisted:
Kannst du im Designer was zusammenklicken und nen Screenshot machen ?
Also mit deiner Textuellen beschreibung kann man ned viel anfangen, was das Widget betrifft, zumindest.

Wenn du mit einer Tabellarischen Ansicht Deiner Datensaetze Aehnlich wie in Excel leben kannst
also sowas:
http://doc.qt.nokia.com/latest/itemview ... egate.html
http://doc.qt.nokia.com/latest/qtableview.html


... dann sollte ein QSQlModel und bissi Magie mit Proxy/FilterModels und nen geeigneten fertigen View volkommen reichen.

Ciao ...

Re: Datenbank

Verfasst: 23. Juli 2011 22:10
von Troll.Soft
Hallo,
Du suchst möglicherweise die mysql-funktion limit. Wird von allen WebProgrammierern verwendet, die die ersten 10, dann die nächsten 10 etc Datensätze anzeigen lassen wollen. Ob Du mit Model oder frei Schnauze programmierst ist hierfür egal.
tschüß
Trolll.Soft

Re: Datenbank

Verfasst: 25. Juli 2011 09:17
von janmerkschien
Also, ich kann gut mit einer Ansicht wie bei bei Excel leben.
Im Anhang ist mein momentaner Code um die Datenbank auszugeben.
Was meinst du mit "Proxy/FilterModels" das sagt mit garnichts.

@Troll.Soft, danke ich werde das mal ausprobieren ;)
aber läd man damit auch immer z.B. nur die 10 Datensätze vom server, die auch angezeigt werden?

Re: Datenbank

Verfasst: 25. Juli 2011 10:01
von RHBaum
mysql-funktion limit.
Ist in diesem Zusammenhang eine mächtige Funktion.
Und ja, damit kann man genau das machen was ich oben beschrieben .... Ob das serverseitig einigermassen performant ist, keine ahnung, so genau kenn ich mich ned aus ^^
Iss halt nur leider mysql spezifisch.

DU verwendest ja schon nen QSqlTableModel ....
Und das ding ist zu lahm .. das fetcht alle Zellen aufs mal ?

Ciao ...

Re: Datenbank

Verfasst: 25. Juli 2011 10:09
von janmerkschien
Ja genau . . . wenn ich jetzt mit einer größeren Db verbinde, dauert das zu lange . . .
gibt es da nicht eine funktion die dem model sagt lade nur die daten die es gerade braucht?

Re: Datenbank

Verfasst: 25. Juli 2011 10:56
von RHBaum
Normal sollte das Model das machen ....

Ich befuerchte aber, das das Model nur mit standard SQL arbeitet, und dir den kompletten connect absetzt ... und limit nicht verwenden wird/kann.

Auf der anderen seite, bist sicher das dein Model allein die Bremse ist ?

Kannst du die Query einmal ohne Model und view absetzen, über nen ganz normales QSqlQuery auf deiner DB und mal die Zeit messen ?
Dann ein 2tes mal, nur bei der query die Limit funktion nutzen ? und zeit noch mal messen ?
http://dev.mysql.com/doc/refman/5.1/de/ ... ation.html

Lauft deine DB schon in nem eigenen Thread ? Oder Blockiert noch den mainthread mit der ?
Oft langt es, die GUI zu entblocken ... dann fuehlt sich das ganze scho viel schneller an, ohne das es wirklich schneller ist ...

Prinzipiell:
Das Model-View Konzept hat schon funktionalitaet, wo das Model nur den im View sichtbaren bereich abfragt und updatet ...
Wenn das SQL Model das ned unterstützt, kann man das selber implementieren, in dem man ein Model selber baut durch implementieren von QAbstractItemModel ... gar ned sooo schwer.
Scrollbars und so haendelt eh dein View, das geht dich also nix an, du arbeitest auf abstrakterer Ebene dann ...

Aber erst mal testen ob wirklich das SQLModel der Übeltäter ist ....

Ciao ...

Re: Datenbank

Verfasst: 25. Juli 2011 11:41
von janmerkschien
Damit die Zeitmessung einen Sinn macht muss ich das ergebnis von dem Query doch auch ausgeben oder?
weil wenn ich nur die select abfrage an den Server sende, muss mein Programm ja nix mehr mit dem Daten machen.
Und da habe ich eine frage wie bekomme ich die Daten einer Select abfrage in ein QSqlTableModel??

Re: Datenbank

Verfasst: 25. Juli 2011 13:15
von RHBaum
Damit die Zeitmessung einen Sinn macht muss ich das ergebnis von dem Query doch auch ausgeben oder?
Nein ....
Der SQL server bereitet deine Daten auf ...
Das heisst , wenn er die Abfrage bekommt, gibts 2 möglichkeiten was er tun koennt.

Er baut ne komplette Struktur im Speicher auf, und gibt dir nen Zeiger, in der SQL-Welt Cursor genannt, zurueck.
Mitt dem Rutschst du dann ueber die daten, wie mit nem Iterator. Der client holt fragt dann also staendig die Daten ab von server ab, je nachdem wie weit du mit der Recordset abfrage weiterkommst.
Das ist ein sogenannter serverside-cursor.
Ob der Server hier optimieren kann, und trotz millionen Zeilen Ergebniss nur paar wenige am anfang holt und spaeter "nachlaed" haengt von der Implementierung ab.
Die meisten server holen aber alles, legens aber nicht unbedingt im speicher ab, sondern temporaer auf der Platte ... und rutschen darauf herum.

Oder aber er streamt quasi den Kompletten Inhalt deiner Abfrage gleich an den Client. Der Client selber haelt die Kompletten Daten im Speicher, solange wie du das Recordset benutzt. und du rutschst darauf herum. client-side cursor.

Das er (der Server) das so machen muss, iss auch klar ....
Wenn deine Abfrage durch ist ... also dein SQL Statement zu ende, iss das eigentlich fuer den Server erledigt ... und dein ergebniss steht fest.
Wenn nachtraeglich jemand die Tabelle aendert, solange du den Recordset auswertest, darf sich Dein Recordset netürlich nicht ändern ... sonst haettest du unerwartete ergebnisse ....
Auf der anderen seite solange du die ergebnisse durcharbeitest, weiss der server ja ned, wenn du damit fertig bist ... ausser du schliesst das recordset, das koennte der Treiber schon übermitteln. Aber solange die Tabelle sperren per default wäre unkooperativ :-)
Es gibt Fälle wo man das machen muss ... das muss man aber selber bauen (Lock Table .... ) , nen "normales Select" sollte das nie selber machen ...

mysql sollte serverside cursor koennen. was der qt treiber nutzt, keine Ahnung.

Was ich mit dem test sehen will :
Wenn deine Abfrage ohne das den Recordset auswertest, schon minuten braucht ... dann brauchst ned am Model Optimieren.
Optimieren kannst recht einfach ueber die limit Geschichte ... um zu sehen was die bringt, sollst das 2te testen ....

Wenn deine Abfrage selber in millisekunden zurueckkommt mit deinem Generischen Test, aber dein View minuten braucht zum anzeigen, dann ist klar das man am Model ansetzen muss ...
Wenn die Abfrage aufm server aber scho minuten braucht ... dann muss man an der Abfrage Optimieren ...

Ich kenn mich mit Mysql ned sooo aus, aber ich hab mal in grauen Vorzeiten viel mit oracle machen mü ... eh dürfen :-)

Ciao ...

Re: Datenbank

Verfasst: 25. Juli 2011 14:15
von janmerkschien
Also das query ohne limit wird sehr schnell ausgeführt das geht so schnell das ich keine zeit messen kann.
allerdings gibt ein query ja auch nur einen bool wert zurück und nicht die daten die die abfrage erstellt hat.
Und das ist das wo ich glaube das alles so langsam macht das lesen der ganzen einträge.

Re: Datenbank

Verfasst: 26. Juli 2011 13:56
von RHBaum
Noe, normal hasst die ergebnissmenge schon auch ....

Code: Alles auswählen

QSqlQuery query("SELECT country FROM artist");
while (query.next()) {
     QString country = query.value(0).toString();
     doSomething(country);
}
exec und valid check ned vergessen ...

Testweisse kannst ja mal alle Werte nem string zuweissen, und checken wie lange er braucht alle datensaetze mal durchzunudeln
und ja, abfragen sollte auch der transport uebers netzwerk sein ...

Aber wenn die abfrage selber in bruchteilen von ner sekunde geht, dann ist super ...

wieviel spalten hasst du in deiner Abfrage ...
und wieviel recordsets hasst du so ca, ?

Hasst du am View irgend eine Sortierung der Daten eingeschalten ?

Ciao ...

Re: Datenbank

Verfasst: 26. Juli 2011 14:13
von janmerkschien
aber dann wird doch trotzdem noch die ganze tabelle geladen und dann auf dem pc gefiltert oder??