PHP / MySQL OOP: SQL karmaşık nesneler yükleme

5 Cevap php

Yani bir emlak için bir proje üzerinde çalışıyorum. Benim tasarım aşağıdaki nesneler / MySQL tablolar var:

Complexes
Units
Amenities
Pictures
Links
Documents
Events
Agents

Bunlar, yukarıda nesneler arasındaki ilişkileri vardır.

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

Tesisler, Resimler, Bağlantılar, Belgeler ve Olaylar bütün ait oldukları birim / karmaşık belirtmek için veritabanında gerekli yabancı tuşları var.

Ben projemde bunları kullanmak, böylece PHP içine veritabanından gerekli nesneleri yüklemek gerekir.

Ben SOL KATILDI kullanarak, 1 sorguda tablo dışında tüm verileri seçmek için çalışırsanız, en azından (bağlantıları #) * (resim #) * (belgelerin #) benzersiz her birim için satırlar alırsınız. Buna olanaklar ve olaylar ekleyin ve * tüm bu alırsınız aktivite # * olayların içinde her karmaşık ... Ben PHP bir nesne içine yükleme ile başa çıkmak için denemek istiyorum emin değilim.

Diğer bir olasılık, her karmaşık / birim için, 1 ayrı bir SQL deyimini yürütmek her bağlantılar, resimler, belgeler, olaylar ve olanaklar

Aşağıda benim sorular şunlardır:

Ben düzgün bir dizin tüm tabloları varsa, bu gerçekten her karmaşık / birim için 3-5 ekstra sorguları yürütmek için kötü bir fikirdir?

Eğer değilse, nasıl başka bir PHP nesnesine yüklemek için gereken verileri alabilirsiniz. Birimler için aşağıdaki İdeal olarak, bir nesne olurdu:

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
                (
                )
        )    
)

HER ZAMAN bazen sadece kompleksinin birincil anahtarı gerekir bazen sadece ajan, vb birincil anahtarı gerekir Ama bu tüm yükü olacaktır yapmak için doğru yolu düşündüm, bu bilgilerin TÜM gerekmez Bunu örneğini her zaman nesne.

Ben OO PHP üzerinde çok araştırma yaptığını, ancak (tüm okuma) en çok online örnekler sadece 1 masa kullanın. Ben üzerinde çalışıyorum proje birçok karmaşık ilişkileri olduğu gibi tabii ki yardımcı olmuyor. Herhangi bir fikir? Ben burada tamamen kapalı işareti miyim?

Teşekkürler

[GÜNCELLEME]

Diğer taraftan, genellikle herkes görecek ön uç üzerinde, ben TÜM bilgi mi OLACAKTIR. Birisi, belirli bir kompleks hakkında bilgi istediği zaman Örneğin, ben bu komplekse ait tüm birimleri, tüm resim, belge, bağlantılar, karmaşık olayları yanı sıra tüm resim, belge ve birim için bağlantıları göstermek gerekir.

Ne önlemek için umuyordum ihtiyacım karmaşık almak için bir sorgu yürütülürken, bir sayfa yükleme sırasında oldu. Daha sonra başka bir sorgu kompleksle ilişkilidir 20 birimleri alır. Sonra belgeler için resim için bir sorgu, başka bir yürütme 20 adet, ben veritabanı sayesinde bir gezi ile, tek seferde hepsini almak istedim vb bağlantılar için, başka biri için.

[EDIT 2] Also, note that the queries to select the pictures, documents, links, events, and agent from the database are pretty simple. Just basic SELECT [list of columns] FROM [table] WHERE [primary_key] = [value] with the occasional INNER JOIN. I'm not doing any complex computations or subqueries, just basic stuff.

[BENCHMARK] So after reading all the answers to my question, I decided to run a benchmark on what I decided to do. What I do is load all the units that I need. Then as I need to display pictures, document, blah blah, I load them at that time. I created 30,000 test units, each with 100 pictures, 100 documents, and 100 links. Then I loaded a certain number of units (I started with 1000, then 100, then the more realistic 10), looped through them, then loaded all pictures, documents and links associated to the unit. With 1000 units, it took approximately 30 seconds. With 100 units, it took about 3 seconds. With 10 units, it took about .5 seconds. There was a lot of variance with the results. Sometimes, with 10 units, it would take .12 seconds. Then it would take .8. Then maybe .5. Then .78. It was really all over the place. However, it seemed to average around half a second. In reality, though, I might only need 6 units at a time, and they each might only have 10 pictures, 5 links and 5 documents associated with them...so I think the "grab the data when you need it" approach is the best bet in a situation like this. If you needed to get all this data at once though, it would be worthwhile to come up with a single SQL statement to load all the data you need so you are only looping through the data one time (6700 units at a time took 217 seconds while the full 30,000 made PHP run out of memory).

5 Cevap

Ben düzgün bir dizin tüm tabloları varsa, bu gerçekten her karmaşık / birim için 3-5 ekstra sorguları yürütmek için kötü bir fikirdir?

Kısacası, hayır. İlgili tablolarının her biri için, muhtemelen ayrı bir sorgu çalıştırmak gerekir. Yani çoğu ORM (Object-Relational Mapping / Modelleme) sistemleri böyle yapardı.

Performansı gerçekten bir sorun varsa (sen ne söylediğim dayalı ve, bu olmayacak) o zaman APC, memcache veya XCache gibi bir şey kullanarak sonuçlarını önbelleğe alma düşünebilirsiniz.

ORM nokta tüm nesneleri her zaman yük değildir. nokta kolay ve şeffaf app nesneye erişmek için yapmaktır.

Eğer birim nesne gerekiyorsa söyleniyor, daha sonra birim nesne yüklemek ve sadece birim nesne. Eğer ajan nesne gerekiyorsa, o zaman ihtiyacınız olduğunda, size birim nesne yüklenemedi zaman o yük.

Belki bu kadar kesiliyor düşünmek gerekir.

Eğer nesneyi başlatmak zaman, işlevine bu nesne için gereken ne sadece ayrıntıları olsun. Daha ayrıntılı bilgiye ihtiyaç olduğunda ve eğer, o zaman gidin ve onları almak. Sen yükünü dağıtmak ve bu şekilde işleme: nesne yalnızca yükü ve çalışması için gereken işleme alır ve daha fazla ihtiyaç olduğu zaman, o zaman onu alır.

Yani, sizin örnekte - ilk kompleksi yaratmak. Eğer bir birim erişmek için gereken zaman, o, siz, vb ajan gerektiğinde, o ajan olsun, bu birimi oluşturmak

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

Ben bir deneme olarak benim kendi MVC framework uydurulmuş zaman bir süre önce bu sorunu çözmesi gerekiyordu. DB yüklenen veri katmanları sınırlamak için, ben yapıcı bir tamsayı geçti. Her yapıcı onu örneği nesnelerinin yapıcıları geçirmeden önce bu tamsayı azaltma olacaktır. Bu 0'a var, artık alt nesneler örneği olacaktır. Bunun anlamı, temelde, geçti int yüklenen katmanların sayısı oldu.

Ben sadece birim nesnenin niteliğini istedim Yani, ben bunu yapmak istiyorum:

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

Eğer önbellek onları anlamına gelen "store" nesneleri, isterseniz sadece bir PHP diziye onlara yük ve serialize. Sonra memcache veya başka bir yerde, veritabanına geri saklayabilirsiniz. Eğer (yani yenilenmesi gerekiyor) kaç yaşında olduğunu biliyorum buna bir etiket takılması bunu almak ve bir zaman damgası eklemek için izin verecek.

Veri seyrek değiştirmek veya değişiklik yoksa, gerçekten birden çok karmaşık sorgular her zaman çalıştırmak için hiçbir neden yoktur. Basit olanlar, bir ilköğretim alma gibi, siz de sadece doğrudan veritabanı vurmak olabilir.