php.de

Zurück   php.de > Webentwicklung > PHP-Fortgeschrittene

PHP-Fortgeschrittene Arbeiten mit PHP ohne Einschränkungen

Antwort
 
LinkBack Themen-Optionen Thema bewerten
Alt 17.08.2011, 13:13  
Benutzer
 
Registriert seit: 05.06.2008
Beiträge: 78
Normalo befindet sich auf einem aufstrebenden Ast
Normalo eine Nachricht über ICQ schicken
Standard MVC, Modelbeziehungen

Hallo zusammen,

ich stehe hier vor einem Strukturproblem innerhalb einer MVC-Architektur und möchte gerne wissen, wie ihr folgende Anforderung lösen würdet.

Mein Model besteht aus einem ORM (Eigenentwicklung) auf der Persistenzschicht vom Zend Framework. Das ORM ist eine Ansammlung von Datenobjekten, die die Datenbankstruktur widerspiegeln. Beziehungen werden per Lazy-Loading über die entsprechenden Getter geladen. Und das ist der Knackpunkt.

Ich habe einen komplexen Query, der mir am Ende eine Liste eines bestimmten Objekts zurückliefert. Zu den einzelnen Objekten möchte ich aber noch Zusatzformationen holen, die pro Objekt über eine Beziehungstiefe von 2 oder mehr abbildbar sind. Diese Infos will ich jedesmal holen, wenn dieses Objekt - sei es als Liste oder einzeln - geladen wird. Hier Lazy-Loading einzusetzen wäre natürlich Unsinn. Also bleibt meiner Meinung nach nur Preloading. Natürlich kann ich in jedem formulierten Query für das Hauptobjekt einfach Joins dranhängen und am Ende in eine Objektstruktur bringen, aber es soll transparent geschehen, damit der Programmierer das nur einmal definieren muss.

Wie könnte eine Lösung dafür aussehen?

Ein weiteres Problem dabei ist, diese Zusatzinfos zu verpacken und an die View weiterzureichen. Eine Möglichkeit wäre, Transferobjekte zwischen Model und View bzw. Controller einzuführen, die dann die Struktur für die View abbilden. Dazu bräuchte man wieder ein Mapping und muss mehrere Schichten pflegen. Man könnte auch die komplette Beziehungstiefe in den Datenobjekten beibehalten, damit wäre das Auslesen der Daten in der View etwas aufwändiger.

Wie macht ihr das? Ist es valide, an die Datenobjekte Propertys dranzuhängen, die nichts mit dem Objekt direkt zu tun haben?

Ich hoffe, ich habe mich klar ausgedrückt. Ansonsten einfach nachfragen.

Vielen Dank!

Da noch niemand von den rund 55 Besuchern geantwortet hat, versuche ich es mal mit meinem theoretischen Ansatz für das erste Problem:

Es existieren folgende Datenbanktabellen:
Code:
CREATE TABLE `translation` (
  `translation_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `source_word_id` int(10) unsigned NOT NULL,
  `target_word_id` int(10) unsigned NOT NULL,
  PRIMARY KEY (`translation_id`),
  UNIQUE KEY `unique_translation` (`source_word_id`,`target_word_id`),
  KEY `translation_target_word_id_word_word_id` (`target_word_id`),
  CONSTRAINT `translation_source_word_id_word_word_id` FOREIGN KEY (`source_word_id`) REFERENCES `word` (`word_id`) ON DELETE CASCADE ON UPDATE CASCADE,
  CONSTRAINT `translation_target_word_id_word_word_id` FOREIGN KEY (`target_word_id`) REFERENCES `word` (`word_id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=3412849 DEFAULT CHARSET=utf8;

CREATE TABLE `word` (
  `word_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `word` varchar(255) NOT NULL,
  `language_id` int(10) unsigned NOT NULL,
  PRIMARY KEY (`word_id`),
  UNIQUE KEY `word_2` (`word`,`language_id`),
  KEY `language_id` (`language_id`),
  CONSTRAINT `word_ibfk_2` FOREIGN KEY (`language_id`) REFERENCES `language` (`language_id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=574117 DEFAULT CHARSET=utf8;
Man beachte die beiden Fremdschlüssel der Tabelle translation auf die Tabelle word. Für jede dieser Tabellen gibt es ein entsprechendes Datenobjekt. Per magischer Getter kann ich in einem Translation-Objekt auf Source-Word und Target-Word zugreifen, die dann nachgeladen werden.

Problem dabei: Beim Zugriff auf diese Beziehungen im Falle einer großen Liste von Translation-Objekten habe ich zuviele einzelne Datenbankabfragen.

Das möchte ich optimieren, indem das ORM automatisch (konfigurierbar) sämtliche Beziehungen in das Query reinjoint und anschließend die Objekte zusammenbastelt. In diesem Fall würde ich also zweimal die Tabelle word joinen. Das wiederum ergibt ein Resultset, in dem sich die gleichnamigen Spaltennamen überschreiben, d.h. ich bekomme entweder nur die Daten für das Source-Word oder das Target-Word. Leider gibt es (in mysql) keine Namespaces dafür.

Wenn man das ganze weiterspinnt und automatisch eine beliebige Tiefe von Beziehungen laden will, z.b. noch die Language im Word-Objekt, wird's noch ekliger. Um es noch schlimmer zu machen, könnte man auch gleich noch die 1:n-Beziehungen holen, z.b.
Code:
Translation
    ->Source-Word
        ->Alle Translations mit diesem Source-Word
. Wie man sieht, könnte das zu Rekursionen führen.

Mir fällt da nichts schöneres ein, als die Joins mit kryptischen Aliasen zu versehen und eine Art Mapping mitzuschleifen, damit ich nachher die Daten den Objekten zuordnen kann. Das ist jedoch nicht einfach umzusetzen, außerdem kann so ein Query dann ziemlich groß werden. Evtl. gibt es sogar performantere Lösungen.

Hat damit jemand Erfahrung?

Geändert von Normalo (18.08.2011 um 15:04 Uhr).
Normalo ist offline   Mit Zitat antworten
Sponsor Mitteilung
PHP Code Flüsterer

Registriert seit: 21.08.2005
Beiträge: 4682
PHP-Kenntnisse:
Fortgeschritten

Alt 18.08.2011, 15:06  
Benutzer
 
Registriert seit: 05.06.2008
Beiträge: 78
Normalo befindet sich auf einem aufstrebenden Ast
Normalo eine Nachricht über ICQ schicken
Standard

Update, s.o.
Normalo ist offline   Mit Zitat antworten
Alt 18.08.2011, 15:14  
Erfahrener Benutzer
 
Registriert seit: 26.11.2008
Beiträge: 264
dsentker befindet sich auf einem aufstrebenden Ast
Standard

Zitat:
Ich habe einen komplexen Query, der mir am Ende eine Liste eines bestimmten Objekts zurückliefert. Zu den einzelnen Objekten möchte ich aber noch Zusatzformationen holen, die pro Objekt über eine Beziehungstiefe von 2 oder mehr abbildbar sind. Diese Infos will ich jedesmal holen, wenn dieses Objekt - sei es als Liste oder einzeln - geladen wird. Hier Lazy-Loading einzusetzen wäre natürlich Unsinn. Also bleibt meiner Meinung nach nur Preloading. Natürlich kann ich in jedem formulierten Query für das Hauptobjekt einfach Joins dranhängen und am Ende in eine Objektstruktur bringen, aber es soll transparent geschehen, damit der Programmierer das nur einmal definieren muss.

Wir kennen natürlich dein ORM nicht. Aber ich verstehe darunter, dass du sicher einen Entity Manager oder konkrete Repositories hast, die dann Models zurückgeben. Wenn du nun weisst, dass bei Abfrage X für das Model Y immer wieder die gleiche Beziehungstiefe (gibt es das Wort?) angefordert wird, dann führe doch diese Abfrage doch schon im Konstruktur durch.

Den Rest deiner Frage(n) verstehe ich nicht. Was hat das "preloading" mit der View zu tun? Es sollte der View egal sein, wie die Daten aufbereitet wurden oder wo sie herkommen.
__________________
dsentker ist offline   Mit Zitat antworten
Alt 18.08.2011, 17:04  
Benutzer
 
Registriert seit: 05.06.2008
Beiträge: 78
Normalo befindet sich auf einem aufstrebenden Ast
Normalo eine Nachricht über ICQ schicken
Standard

Zitat:
Zitat von dsentker Beitrag anzeigen
Wenn du nun weisst, dass bei Abfrage X für das Model Y immer wieder die gleiche Beziehungstiefe (gibt es das Wort?) angefordert wird, dann führe doch diese Abfrage doch schon im Konstruktur durch.
Von welchem Konstruktor sprichst du?
Und wie löst es das Problem mit den Joins?

Zitat:
Zitat von dsentker Beitrag anzeigen
Den Rest deiner Frage(n) verstehe ich nicht. Was hat das "preloading" mit der View zu tun? Es sollte der View egal sein, wie die Daten aufbereitet wurden oder wo sie herkommen.
Die zweite Frage zielt darauf ab, wie die Daten zwischengespeichert werden. Wenn du aus deinem Datenbankmodell irgendwelche Daten rausaggregierst, wie übergibst du sie an den Controller, wenn es sich dabei um mehr als einen Wert handelt? Man könnte natürlich mit einer Hashmap arbeiten, aber das ist nicht objektorientiert.

Geändert von Normalo (18.08.2011 um 17:13 Uhr).
Normalo ist offline   Mit Zitat antworten
Alt 19.08.2011, 14:39  
moderatives Dielektrikum
 
Benutzerbild von nikosch
 
Registriert seit: 21.05.2008
Beiträge: 35.987
PHP-Kenntnisse:
Fortgeschritten
nikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunft
Standard

Ich verstehe kaum was. Ich würde Dir empfehlen, die Frage in kleinere Teilfragen aufzuteilen.
__________________
--
One pixel is still too big. Please make it smaller. ASAP.

Initiative Mittelstand.
Die wichtigste Gestaltungsregel im Screendesign ist Pi mal Daumen des Arbeitgebers.
--
nikosch ist offline   Mit Zitat antworten
Alt 19.08.2011, 16:22  
Erfahrener Benutzer
 
Registriert seit: 30.07.2008
Beiträge: 1.167
PHP-Kenntnisse:
Fortgeschritten
xm22 sorgt für eine eindrucksvolle Atmosphärexm22 sorgt für eine eindrucksvolle Atmosphärexm22 sorgt für eine eindrucksvolle Atmosphäre
Standard

Zitat:
Man könnte natürlich mit einer Hashmap arbeiten, aber das ist nicht objektorientiert.
Zwar verstehe ich nicht genau den Kontext, aber Arrays/Hashmaps widersprechen doch nicht dem OOP-Gedanken.
xm22 ist offline   Mit Zitat antworten
Antwort


Themen-Optionen
Thema bewerten
Thema bewerten:

Forumregeln
Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are an
Gehe zu

Besucher kamen über folgende Suchanfragen bei Google auf diese Seite
mvc beziehungen, daten models normalos?

Alle Zeitangaben in WEZ +2. Es ist jetzt 01:05 Uhr.




Powered by vBulletin® Version 3.7.2 (Deutsch)
Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.2.0
Aprilia-Forum, Aquaristik-Forum, Liebeskummer-Forum, Zierfisch-Forum, Geizkragen-Forum