2009-08-28 6 views
8

Also arbeite ich an einem Projekt für einen Makler. Ich habe die folgenden Objekte/MySQL-Tabellen in meinem Design:PHP/MySQL OOP: Laden komplexer Objekte aus SQL

Complexes 
Units 
Amenities 
Pictures 
Links 
Documents 
Events 
Agents 

Dies sind die Beziehungen zwischen den oben genannten Objekten.

Complexes have a single Agent. 
Complexes have multiple Units, Amenities, Pictures, Links, Documents, and Events. 
Units have multiple Pictures, Links, and Documents. 

Ausstattung, Bilder, Links, Dokumente und Veranstaltungen haben alle die notwendigen Fremdschlüssel in der Datenbank angeben, welche Einheit/komplex sie gehören.

Ich muss die notwendigen Objekte aus der Datenbank in PHP laden, damit ich sie in meinem Projekt verwenden kann.

Wenn ich versuche, alle Daten aus der Tabelle in 1 Abfrage mit LINKER VERBINDUNGEN auszuwählen, bekomme ich AT MINDESTENS (Anzahl der Verknüpfungen) * (Anzahl der Bilder) * (Anzahl der Dokumente) Zeilen für jeden einzigartige Einheit. Fügen Sie Annehmlichkeiten und Ereignisse dazu hinzu und ich werde all das bekommen * Anzahl der Annehmlichkeiten * Anzahl der Ereignisse für jeden Komplex ... Nicht sicher, dass ich versuchen möchte, mit dem Laden in ein Objekt in PHP umzugehen.

Die andere Möglichkeit ist für jeden Komplex/Einheit, führen 1 separate SQL-Anweisung jeweils für Links, Bilder, Dokumente, Veranstaltungen und Einrichtungen

Meine Fragen sind wie folgt:

Wenn ich richtig Index alle meine Tabellen, ist es wirklich eine schlechte Idee, 3-5 zusätzliche Abfragen für jeden Komplex/Einheit auszuführen?

Wenn nicht, wie sonst bekomme ich die Daten, die ich in ein PHP-Objekt laden muss. Idealerweise würde ich ein Objekt, wie für Einheiten folgt:

Unit Object 
(
    [id] 
    [mls_number] 
    [type] 
    [retail_price] 
    [investor_price] 
    [quantity] 
    [beds] 
    [baths] 
    [square_feet] 
    [description] 
    [featured] 
    [year_built] 
    [has_garage] 
    [stories] 
    [other_features] 
    [investor_notes] 
    [tour_link] 
    [complex] => Complex Object 
     (
      [id] 
      [name] 
      [description] 
      etc. 
     ) 
    [agent] => Agent Object 
     (
      [id] 
      [first_name] 
      [last_name] 
      [email] 
      [phone] 
      [phone2] 
      etc. 

     ) 
    [pictures] => Array 
     (
      [1] => Picture Object 
       (
       ) 
     ) 
    [links] => Array 
     (
      [1] => Link Object 
       (
       ) 
     ) 
    [documents] => Array 
     (
      [1] => Document Object 
       (
       ) 
     )  
) 

ich nicht immer alle diese Informationen benötigen, manchmal nur ich den Primärschlüssel des Komplexes müssen, manchmal nur ich den Primärschlüssel für die Notwendigkeit Agent, etc. Aber ich dachte, der richtige Weg wäre, das ganze Objekt jedes Mal zu laden, wenn ich es instanziiere.

Ich habe eine Menge Forschung über OO PHP gemacht, aber die meisten (lesen Sie alle) Online-Beispiele verwenden nur 1 Tabelle. Das hilft offensichtlich nicht, da das Projekt, an dem ich arbeite, viele komplexe Beziehungen hat. Irgendwelche Ideen? Bin ich hier völlig daneben?

Dank

[UPDATE]

Auf der anderen Seite, in der Regel auf dem Front-End, das jeder sehen wird, werde ich alle die Informationen benötigt. Will man zum Beispiel Informationen zu einem bestimmten Komplex, muss ich alle zu diesem Komplex gehörenden Einheiten, alle Bilder, Dokumente, Links, Ereignisse für den Komplex sowie alle Bilder, Dokumente und Links für die Einheit anzeigen.

Was ich vermeiden wollte, war, während einer Seite laden, eine Abfrage ausführen, um den Komplex, den ich brauche. Dann eine weitere Abfrage, um die 20 mit dem Komplex verbundenen Einheiten zu erhalten. Dann für jede der 20 Einheiten, eine Abfrage für Bild, eine andere für Dokumente, eine andere für Links, etc. Ich wollte sie alle auf einmal, mit einer Reise durch die Datenbank.

[EDIT 2] Beachten Sie auch, dass die Abfragen zum Auswählen der Bilder, Dokumente, Verknüpfungen, Ereignisse und Agenten aus der Datenbank ziemlich einfach sind. Nur grundlegende SELECT [Liste der Spalten] FROM [Tabelle] WHERE [primary_key] = [Wert] mit dem gelegentlichen INNER JOIN. Ich mache keine komplexen Berechnungen oder Unterabfragen, nur grundlegende Dinge.

[BENCHMARK] Nachdem ich alle Antworten auf meine Frage gelesen hatte, entschied ich mich, eine Benchmark zu machen, was ich tun wollte. Ich lade alle Einheiten, die ich brauche. Dann, wie ich Bilder anzeigen muss, Dokument, blah blah, lade ich sie zu dieser Zeit. Ich habe 30.000 Testeinheiten mit jeweils 100 Bildern, 100 Dokumenten und 100 Links erstellt. Dann lud ich eine bestimmte Anzahl von Einheiten (ich begann mit 1000, dann 100, dann die realistischere 10), schleuderte sie durch und lud dann alle Bilder, Dokumente und Links ein, die mit der Einheit verbunden waren. Bei 1000 Einheiten dauerte es ungefähr 30 Sekunden. Bei 100 Einheiten dauerte es ungefähr 3 Sekunden. Bei 10 Einheiten dauerte es etwa 0,5 Sekunden. Es gab eine große Abweichung von den Ergebnissen. Manchmal mit 10 Einheiten würde es 0,12 Sekunden dauern. Dann würde es .8. Dann vielleicht .5. Dann .78. Es war wirklich überall. Es schien jedoch durchschnittlich etwa eine halbe Sekunde zu dauern. In Wirklichkeit könnte ich nur 6 Einheiten gleichzeitig brauchen, und sie könnten nur 10 Bilder, 5 Links und 5 Dokumente mit ihnen verbunden haben ... so denke ich, dass die "greifen Sie die Daten, wenn Sie es brauchen" Ansatz ist die beste Wette in einer solchen Situation. Wenn Sie jedoch alle diese Daten auf einmal benötigen, wäre es sinnvoll, eine einzige SQL-Anweisung zu erstellen, um alle Daten zu laden, die Sie benötigen, sodass Sie die Daten nur einmal durchlaufen (6700 Einheiten pro Zeiteinheit benötigten 217 Sekunden) während die vollen 30.000 PHP keinen Speicher mehr hatten).

Antwort

4

Wenn ich alle meine Tabellen korrekt indexiere, ist es wirklich eine schlechte Idee, 3-5 zusätzliche Abfragen für jeden Komplex/Einheit auszuführen?

Kurz gesagt, nein. Für jede der verwandten Tabellen sollten Sie wahrscheinlich eine separate Abfrage ausführen. Das würden die meisten ORM-Systeme (Object-Relational Mapping/Modeling) tun.

Wenn die Leistung wirklich ein Problem ist (und basierend auf dem, was Sie gesagt haben, wird es nicht sein), dann könnten Sie die Ergebnisse mit etwas wie APC, Memcache oder Xcache zwischenspeichern.

0

der Punkt der ORM ist nicht ganze Objekte jedes Mal zu laden. Es geht darum, dass Ihre App einfach und transparent auf Objekte zugreifen kann.

, dass gesagt wird, wenn Sie das Gerät Objekt benötigen, dann das Gerät Objekt laden, und nur das Gerät Objekt. Wenn Sie das Agentenobjekt benötigen, laden Sie es bei Bedarf, nicht beim Laden des Einheitenobjekts.

+0

Das größte Problem ist, dass diese Teile für den Administrationsbereich segmentiert sind, um eine granulare Verwaltung zu ermöglichen. Aber am Front-End zeigt 1 Seite einen Komplex, alle seine Einheiten, alle zugehörigen Bilder, Dokumente, Ereignisse und Links sowie den zugewiesenen Agenten und Kontaktinformationen ... – SpaDusA

+0

an, da Sie auf Ihre Daten zugreifen werden über indizierte Spalten und tatsächlich alle verwenden, sollte dies kein Problem sein. Meine Antwort war darauf ausgerichtet, alle Daten zurückzuziehen, weil das ORM dies gesagt hat, anstatt es zu benutzen. – longneck

0

Vielleicht sollten Sie denken, dies zu zerbrechen.

Wenn Sie Ihr Objekt initiieren, bekommen nur das, was Sie für das Objekt Funktion benötigen Details. Wenn und wenn Sie mehr Details benötigen, dann gehen Sie und holen Sie sie. Sie verteilen Ihre Ladung und verarbeiten diese auf folgende Weise: Das Objekt erhält nur die Last und die Verarbeitung, die es benötigt, um zu funktionieren, und wenn mehr benötigt wird, erhält es es dann.

in Ihrem Beispiel also - den Komplex zuerst erstellen. Wenn Sie eine Einheit zugreifen müssen, erstellen Sie dann das Gerät, wenn Sie die Mittel benötigen, dann diese Mittel erhalten, usw.

$complexDetails = array('id' => $id, etc); 
$complexUnits = array(); 
......... 
$complexUnits[] = new unit(); 
......... 
$complexDetails['agent'] = new Agent(); 
0

ich eine Weile zurück, um dieses Problem zu lösen hatte, als ich meine eigenen MVC-Framework zusammengebraut als ein Experiment. Um die Datenschichten zu begrenzen, die aus der Datenbank geladen werden, habe ich eine Ganzzahl an den Konstruktor übergeben. Jeder Konstruktor dekrementiert diese Ganzzahl, bevor sie an die Konstruktoren der Objekte übergeben wird, die sie instanziiert hat. Wenn es zu 0 wurde, würden keine weiteren Unterobjekte instanziiert werden. Dies bedeutet, dass der int im Wesentlichen die Anzahl der geladenen Schichten war.

Also, wenn ich nur ein Attribut der Einheit Objekt wollte, würde ich dies tun:

 
$myUnit = new Unit($unitId,1); 
0

Wenn Sie die Objekte zu „speichern“ wollen, Cache ihnen Bedeutung, sie nur in eine PHP-Array laden und serialisieren es. Dann können Sie es in der Datenbank, in Memcache oder anderswo speichern. Wenn Sie ein Label anhängen, können Sie es abrufen und einen Zeitstempel einfügen, damit Sie wissen, wie alt es ist (d. H. Aktualisiert werden muss).

Wenn sich die Daten nicht oder nur selten ändern, gibt es keinen Grund, mehrere komplexe Abfragen jedes Mal auszuführen. Einfache, wie zum Beispiel eine primäre, Sie können auch nur direkt auf die Datenbank zugreifen.

+0

Ich möchte die Objekte nicht speichern, denke ich nicht. Ich versuche herauszufinden, wie man die Informationen in PHP effizient in die Datenbank lädt. – SpaDusA