Ankündigung

Einklappen
Keine Ankündigung bisher.

Zusammenspiel zwischen Datenbankabfrage und Objekten schöner gestalten?

Einklappen

Neue Werbung 2019

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • Zusammenspiel zwischen Datenbankabfrage und Objekten schöner gestalten?

    Hallo zusammen,

    ich würde gerne meinen Code ein wenig optimieren bzw. wissen, ob meine Abläufe so sinnvoll sind, oder ob man es besser machen könnte.

    Ich habe folgendes Szenario:

    mySQL-Datenbank gefüllt mit Usern, diese möchte ich jetzt in einer Liste mit mehreren weiteren Infos darstellen. Ich bin dabei bisher immer wie folgt vorgegangen:

    1) mysqli-Statement liest alle IDs der User aus der Tabelle aus (ggf. durch bestimmte Bedinungen begrenzt).

    2) Die auswertende While-Schleife erstellt jeweils das entsprechende User-Objekt mit der ID.

    3) Die User-Klasse, aus der die Objekte erstellt werden, ruft im Konstruktor erneut eine Datenbankabfrage auf, und liest mittels der übermittelten User-ID die entsprechenden Daten aus.

    4) Nun habe ich also das erstellte Userobjekt bei jedem Schleifendurchlauf, und kann so die Infos vom Objekt abrufen.

    => Problem welches ich sehe: Zu viele Datenbankabfragen, welche jedes mal alle Daten der User (es ist nicht absehbar welche Daten davon letztendlich benötigt werden) ausliest. Ich arbeite bereits mit prepared Statements, welche scheinbar bei häufigen Aufrufen effizienter sein sollen, bin mir dennoch nicht sicher, ob der Ablauf so sinnvoll bzw. effizient ist.

    Eine alternative Idee die ich hatte, alle Funktionen die Daten des Users auslesen als Statement an die Datenbank. Wenn ich also getName() vom Userobjekt aufrufe, ruft die Methode die Daten per Statement von der Datenbank ab und gibt sie zurück. Bei vielen benötigten Informationen würde dies jedoch eine Menge Abfragen bedeuten, oder doppelte Abfragen falls Daten mehrfach benötigt werden.

    Wie kann mans besser machen bzw. wie löst man es generell am schönsten?


    Viele Grüße
    Viele Grüße

  • #2
    Ah, verdammt. Der zweite Post soll hier gar nicht sein hoppla!

    Kommentar


    • #3
      Normalerweise mache ich das nicht gerne, dir empfehle ich jedoch die Verwendung eines ORM, z.B. Doctrine.
      [URL="https://github.com/chrisandchris"]GitHub.com - ChrisAndChris[/URL] - [URL="https://github.com/chrisandchris/symfony-rowmapper"]RowMapper und QueryBuilder für MySQL-Datenbanken[/URL]

      Kommentar


      • #4
        Hallo, sowas ungefähr? arbeite mit medoo mysql framework

        PHP-Code:
          // Hole User Infos
          
        public function getUser($id$params = array('groups','friends')) {
          
            global 
        $group_names// Definiert in data.php
          
            
        $user parent::get('user','*',array('id'=>$id));
            
            
        // User on oder off?
            
        if($user['last_seen'] > time()-60) {
              
        $user['status'] = 'on';  
            } else {
              
        $user['status'] = 'off';
            }
            
            
        $user['groups'] = array();
            
        $user['friends'] = array();

            if(
        in_array('groups',$params)) {
              
        $groups parent::select('user_groups','*',array('id_user'=>$id));
              foreach(
        $groups as $v){$user['groups'][] = $group_names[$v['id_group']];}
            }
            
            if(
        in_array('friends',$params)) {
              
        $where = array('AND'=>array('accepted'=>1,'OR'=>array('id_user'=>$id,'id_sender'=>$id)));
              
        $list parent::select('friends','*',$where);
              foreach(
        $list as $k => $v) {
                if(
        $v['id_sender'] == $id) {
                  
        $user['friends'][] = $v['id_user'];
                } else {
                  
        $user['friends'][] = $v['id_sender'];
                }
              }
            }

            
        //print_r($user);
            
            
        return $user;
            
          } 
        :cookie: ?

        Kommentar


        • #5
          Nein. Globals sind schlechtes Design. Parent:: in dem Falle auch. Zu Doctrine gibt es gute Tutorials/How-To's im Internet.
          [URL="https://github.com/chrisandchris"]GitHub.com - ChrisAndChris[/URL] - [URL="https://github.com/chrisandchris/symfony-rowmapper"]RowMapper und QueryBuilder für MySQL-Datenbanken[/URL]

          Kommentar


          • #6
            Ein User, ein Datensatz.
            Ich seh keinen Sinn mal diese Info, mal jene Info auszulesen.
            Und erst recht nicht, erst IDs auszulesen um dann die zugehörigen Daten auf die denkbar ineffiziensteste Art nachzuladen.
            Ergo: Lade alle Daten, die für ein valides User-Objekt nötig sind, auch wenn du sie nicht direkt verwenden willst und vor allem lade alle notwendigen User in einem Query.
            VokeIT GmbH & Co. KG - VokeIT-oss @ github

            Kommentar


            • #7
              Zitat von G.Schuster Beitrag anzeigen
              Ein User, ein Datensatz.
              Ich seh keinen Sinn mal diese Info, mal jene Info auszulesen.
              Und erst recht nicht, erst IDs auszulesen um dann die zugehörigen Daten auf die denkbar ineffiziensteste Art nachzuladen.
              Ergo: Lade alle Daten, die für ein valides User-Objekt nötig sind, auch wenn du sie nicht direkt verwenden willst und vor allem lade alle notwendigen User in einem Query.
              Du meinst also, ich solle alle Daten der User vorher auslesen, und anschließend dann entsprechend rausfiltern bzw. darstellen. Mal angenommen das Szenario ändert sich, und ich möchte nur zwei gezielte User darstellen (habe von beiden die ID), dann sehe ich das vollständige auslesen aller User als ineffizienter.

              Habe mich mit solchen Dingen ehrlich gesagt nie beschäftigt, sondern es im Prinzip immer wie oben beschrieben gelöst. Wird also Zeit, dass sich da etwas ändert.

              Grüße

              Kommentar


              • #8
                Hallöchen,

                Zitat von Lucke Beitrag anzeigen
                Du meinst also, ich solle alle Daten der User vorher auslesen, und anschließend dann entsprechend rausfiltern bzw. darstellen. Mal angenommen das Szenario ändert sich, und ich möchte nur zwei gezielte User darstellen (habe von beiden die ID), dann sehe ich das vollständige auslesen aller User als ineffizienter.
                Nein, das hast du wohl falsch verstanden. Was du weiter oben beschrieben hast (User-Ids holen, anschließend jeden User-Datensatz separat abrufen) ist ineffizient und lässt sich mit einem Query abbilden. Ich denke darauf wollte G.Schuster hinaus.

                PHP-Code:
                // Achtung: Pseudo-Code
                $rows $db->execute('SELECT firstname, lastname, username, .. FROM users');
                $users = [];
                foreach(
                $rows as $row){
                    
                $users[] = $userFactory->fromArray($row);

                Das Limitieren der Datensätze ist wieder eine andere Baustelle. Generell ist es allerdings sinnvoll die Datenbank-Zugriff so weit als möglich zu reduzieren.

                Viele Grüße,
                lotti
                [SIZE="1"]Atwood's Law: any application that can be written in JavaScript, will eventually be written in JavaScript.[/SIZE]

                Kommentar


                • #9
                  Zitat von lottikarotti Beitrag anzeigen
                  Hallöchen,


                  Nein, das hast du wohl falsch verstanden. Was du weiter oben beschrieben hast (User-Ids holen, anschließend jeden User-Datensatz separat abrufen) ist ineffizient und lässt sich mit einem Query abbilden. Ich denke darauf wollte G.Schuster hinaus.

                  PHP-Code:
                  // Achtung: Pseudo-Code
                  $rows $db->execute('SELECT firstname, lastname, username, .. FROM users');
                  $users = [];
                  foreach(
                  $rows as $row){
                      
                  $users[] = $userFactory->fromArray($row);

                  Das Limitieren der Datensätze ist wieder eine andere Baustelle. Generell ist es allerdings sinnvoll die Datenbank-Zugriff so weit als möglich zu reduzieren.

                  Viele Grüße,
                  lotti
                  Danke für das Beispiel, wie wäre eine generelle Verbindung zwischen User-Objekt und Datenbank denn am sinnvollsten? bzw. welche Methode nutzt man "im allgemeinen".

                  Ähnlich wie in deinem Code-Beispiel könnte ich dann Methoden verwenden wie: ladeVonId($id) oder ladeVonArray($array) um die Daten des Users effizienter bzw. je nach Situation zu laden.

                  Kommentar


                  • #10
                    Push! Würde mich freuen, wenn mir jemand zu meiner kleinen Frage Auskunft geben könnte:

                    wie wäre eine generelle Verbindung zwischen User-Objekt und Datenbank denn am sinnvollsten? bzw. wie lade ich Daten von Usern am sinnvollsten in meine User-Objekte?

                    Kommentar


                    • #11
                      Ich bin ein großer Freund von php-Frameworks geworden, und alle bieten dir neben vielen anderen tollen Sachen und (meist) einer gut strukturierten Application ein ORM.
                      Wenn du das nicht willst, ich würde mir ein Users Objekt definieren mit einer statischen funktion find, die ein Resultset von Users-Objekten zurückgibt, so wie es die meisten ORMs tun.
                      Fatal Error: Windows wird gestartet

                      Wie administriert man ein Netzwerk: Beispiel

                      Kommentar


                      • #12
                        wie wäre eine generelle Verbindung zwischen User-Objekt und Datenbank denn am sinnvollsten? bzw. wie lade ich Daten von Usern am sinnvollsten in meine User-Objekte?

                        Es gibt hierbei keine generell „sinnvollste Vorgehensweise“. Grundsätzlich gibt es allerdings einige bekanntere Lösungsansätze die sich mit der Problematik befassen, z.B.:

                        Active Record http://de.wikipedia.org/wiki/Active_Record (z.B. https://github.com/jpfuentes2/php-activerecord) und
                        Data Mapper http://en.wikipedia.org/wiki/Data_mapper_pattern (kommt z.B. in Doctrine 2 ORM zum Einsatz)

                        vg
                        jack
                        -

                        Kommentar


                        • #13
                          Genau sowas hab ich gesucht! Danke werde wohl die Active Record Variante verwenden, dafür gibts ja bereits ein passendes Framework!

                          Kommentar

                          Lädt...
                          X