Abfrageergebnisse in Array oder Objekt zurückgeben lassen?
Christian Wermelinger
- php
Hallo zusammen
Kann mir jemand den Unterschied zwischen der MySQL-Funktion (PHP) mysql_fetch_assoc() und mysql_fetch_object() erklären? Ich weiss dass mysql_fetch_assoc() ein assoziatives Array zurückgibt, während mysql_fetch_object() ein Objekt zurückliefert. Die Datensätze lassen sich ja mit beiden Funktionen ausgeben, einzig die Syntax ist etwas unterschiedlich. Gibt es Vorteile wenn ich die Resultate in ein Objekt schreibe (mysql_fetch_object())? Falls ja welche? Wie sieht es mit der Performance aus? Welche Funktion ist empfehlenswerter? Danke für jeden Hinweis!
Gruss
Christian
Halihallo Christian
Kann mir jemand den Unterschied zwischen der MySQL-Funktion (PHP) mysql_fetch_assoc() und mysql_fetch_object() erklären? Ich weiss dass mysql_fetch_assoc() ein assoziatives Array zurückgibt, während mysql_fetch_object() ein Objekt zurückliefert. Die Datensätze lassen sich ja mit beiden Funktionen ausgeben, einzig die Syntax ist etwas unterschiedlich. Gibt es Vorteile wenn ich die Resultate in ein Objekt schreibe (mysql_fetch_object())? Falls ja welche? Wie sieht es mit der Performance aus? Welche Funktion ist empfehlenswerter? Danke für jeden Hinweis!
Nun, das schnellste wird wohl immer noch ein mysql_fetch_array mit MYSQL_NUM sein, denn
dies entspricht am besten dem, was zwischen Server und Client kommuniziert wird. Alles
andere, ob nun mysql_fetch_assoc oder -object, bedingt eine grössere PHP interne
Konvertierung und geht eigentlich immer mit einer Speicherplatzverschwendung einher, da
die Attributnamen bei jedem Datensatz mitgeliefert werden.
Zu assoc bzw. MYSQL_ASSOC / MYSQL_BOTH : Bei jedem Datensatz werden die Attributnamen
mitgeliefert, das braucht a) Speicher und b) Performance. Bei _object werden alle
Attributwerte als Funktionen repräsentiert, welche auch zuerst im Object referenziert
werden müssen; sprich: holst du einen Wert aus einer _object-Rückgabe, rufst du in
wirklichkeit jedesmal eine Funktion auf, die als Rückgabewert den Attributwert enthält.
Also: mysql_fetch_array mit MYSQL_NUM ist IMO das speicher- und performanceschonendste.
Zumindest halte ich dies für sehr wahrscheinlich, gebenchmarked habe ich dies noch nie.
Aber: Einen sehr grossen Unterschied ist zwischen diesen, ist wohl kaum feststellbar.
Viele Grüsse
Philipp
Moin!
Also: mysql_fetch_array mit MYSQL_NUM ist IMO das speicher- und performanceschonendste.
Zumindest halte ich dies für sehr wahrscheinlich, gebenchmarked habe ich dies noch nie.
Das solltest du dann vielleicht mal tun. Laut Doku gibt es keinen meßbaren Unterschied zwischen numerischen und assoziativen Arrays.
Viel wichtiger aber ist: Der assoziative Zugriff auf die DB-Ergebnisse ist im Code viel selbstdokumentierender, als wenn man über einen numerischen Index zugreifen muß.
Du gewinnst also, wenn überhaupt, nur einen winzigsten Vorteil in der Performance, und kaufst diesen durch den extremen Nachteil von unübersichtlicherem Code.
Aber: Einen sehr grossen Unterschied ist zwischen diesen, ist wohl kaum feststellbar.
- Sven Rautenberg
Halihallo Sven
Also: mysql_fetch_array mit MYSQL_NUM ist IMO das speicher- und performanceschonendste.
Zumindest halte ich dies für sehr wahrscheinlich, gebenchmarked habe ich dies noch nie.
Das solltest du dann vielleicht mal tun.
Wieso, wenn's doch in der Doku steht, glaube ich das ;)
Laut Doku gibt es keinen meßbaren Unterschied zwischen numerischen und assoziativen Arrays.
Unterschied in was? - Performance? - Speicher? - Glaube kaum, dass ein assoziatives
Array weniger oder gleich viel Speicher verbraucht, als ein Nummerisches. Bei der
Performance ist es gut möglich, dass der Unterschied nicht messbar ist.
Natürlich ist dies noch lange kein Grund auf die selbsterklärenden assoziativen
Indexe zu verzichten, da gebe ich dir recht.
Viel wichtiger aber ist: Der assoziative Zugriff auf die DB-Ergebnisse ist im Code viel selbstdokumentierender, als wenn man über einen numerischen Index zugreifen muß.
Du gewinnst also, wenn überhaupt, nur einen winzigsten Vorteil in der Performance, und kaufst diesen durch den extremen Nachteil von unübersichtlicherem Code.
Full ACK.
Viele Grüsse
Philipp
Moin!
Laut Doku gibt es keinen meßbaren Unterschied zwischen numerischen und assoziativen Arrays.
Wie ich gerade nachgelesen habe, bezieht sich diese Aussage auf den Unterschied zwischen fetch_row und fetch_array.
Unterschied in was? - Performance? - Speicher? - Glaube kaum, dass ein assoziatives Array weniger oder gleich viel Speicher verbraucht, als ein Nummerisches.
Nein, sicherlich wird es mehr Speicher verbrauchen. Aber da in PHP das Handling von numerischen und assoziativen Arrays gleich ist, ist es für die Zugriffsgeschwindigkeit egal, ob ein Zugriff auf einen numerischen Index 2 oder einen String-Index "name" geschieht. Der Unterschied ist hierbei lediglich, dass mal mehr, mal weniger Bytes für den Index gespeichert werden müssen.
Bedenke nämlich, dass es, im Gegensatz zu Perl, problemlos möglich ist, beide Indextypen in einem Array zu mischen. Allein das kann nur funktionieren, wenn intern kein großer Unterschied gemacht wird (und ich vermute, die numerischen Indices werden einfach zu Strings gemacht).
Bei der Performance ist es gut möglich, dass der Unterschied nicht messbar ist. Natürlich ist dies noch lange kein Grund auf die selbsterklärenden assoziativen Indexe zu verzichten, da gebe ich dir recht.
Du wirst bei der Abfrage einer Datenbank doch bitte nicht mit Speicherauslastung argumentieren wollen! Da hat ein einzelnes mysql_fetch_assoc oder mysql_fetch_row nämlich den geringsten Anteil dran, denn es wird ja nur ein Datensatz aus dem Abfrageergebnis geholt. Zuvor jedoch werden gewöhnlich _alle_ abgefragten Datensätze in einen Puffer kopiert. _Das_ kostet im Zweifel den Speicher (und wer je nur einen einzigen Datensatz abfragt, der mehrere Gigabyte Daten ergibt, weil ein ungünstiges BLOB darunter ist, der hat andere Probleme, und insbesondere dann keine _zusätzlichen_ Probleme, weil der Arrayindex zu groß ist).
- Sven Rautenberg
Halihallo Sven
Bedenke nämlich, dass es, im Gegensatz zu Perl, problemlos möglich ist, beide Indextypen in einem Array zu mischen. Allein das kann nur funktionieren, wenn intern kein großer Unterschied gemacht wird (und ich vermute, die numerischen Indices werden einfach zu Strings gemacht).
Ich nehme es so auch an.
Bei der Performance ist es gut möglich, dass der Unterschied nicht messbar ist. Natürlich ist dies noch lange kein Grund auf die selbsterklärenden assoziativen Indexe zu verzichten, da gebe ich dir recht.
Du wirst bei der Abfrage einer Datenbank doch bitte nicht mit Speicherauslastung argumentieren wollen!
Touché! :-)
Da hat ein einzelnes mysql_fetch_assoc oder mysql_fetch_row nämlich den geringsten Anteil dran, denn es wird ja nur ein Datensatz aus dem Abfrageergebnis geholt. Zuvor jedoch werden gewöhnlich _alle_ abgefragten Datensätze in einen Puffer kopiert.
OK, das ist in den meisten Fällen richtig. In Perl zumindest ist mysql_store_result der
default, will heissen, dass das ganze Result-Set in einem wisch auf den Client übertragen
wird und so den Client-Speicher frisst. Jedenfalls unterstützt MySQL auch
mysql_use_result, wo die Daten nur auf Anfrage vom Server übertragen werden und somit
den Speicherverbrauch beim Server liegt (natürlich ist es oft der Fall, dass beide
Systeme auf demselben Rechner liegen). Äm, hm, das ändert eigentlich dennoch nicht viel
an der Sache... ;)
_Das_ kostet im Zweifel den Speicher (und wer je nur einen einzigen Datensatz abfragt, der mehrere Gigabyte Daten ergibt, weil ein ungünstiges BLOB darunter ist, der hat andere Probleme, und insbesondere dann keine _zusätzlichen_ Probleme, weil der Arrayindex zu groß ist).
Wohl wahr...
Viele Grüsse
Philipp
Hallo,
mysql_fetch_assoc() vs. mysql_fetch_object()
Ich benuetze meistens
$zeile=mysql_fetch_array($ergebnis,MYSQL_ASSOC);
Dann kann ich mit
extract($zeile,EXTR_OVERWRITE);
das Array in einzelne Variablen umwandeln.
Beispiel: In der DB heissen die Felder "id" und "name".
Nach extract() kann ich die Werte nun mit $id und $name
direkt verwenden (anstatt $zeile->name bzw. $zeile["name"]).
Du musst natuerlich schauen, dass die Variablennamen
nur einmal vorkommen.
Gruesse,
Thomas
Ich würde immer mit mysql_fetch_assoc() arbeiten. Der Grund ist dafür, dass ich die Werte des assoziativen Arrays mit foreach durchlaufen lassen kann, während ich bei einem Objekt die Member dieses Objektes von vorneherein wissen muss. Darüber hinaus ist das Objekt in mysql_fetch_object() das Objekt ohne Klassennamen und kann daher nicht vererbt werden.
Grüße,
Wolfram
Moin!
Ich würde immer mit mysql_fetch_assoc() arbeiten. Der Grund ist dafür, dass ich die Werte des assoziativen Arrays mit foreach durchlaufen lassen kann, während ich bei einem Objekt die Member dieses Objektes von vorneherein wissen muss.
Das stimmt so nicht. Es gibt die wunderbare Funktion get_object_vars(), die dir die Eigenschaften eines Objektes liefert.http://de.php.net/manual/de/function.get-object-vars.php
Allerdings - und das ist die Ironie daran: Diese Lieferung geschieht als assoziatives Array. :)
Man kann sich diesen Umweg über das Objekt also gerne sparen.
- Sven Rautenberg