Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Prośba o porade, sugectje przy tworzeniu pliku XML
Forum PHP.pl > Forum > XML, AJAX > XML
Sokrates
Witam,
niedawno tworzyłem generator pliku XML na podstawie danych z bazy w PHP
dla jednej z firm która wyświetla oferty wielu sklepów internetowych (format pliku xml był narzucony przez nich)

Wygląda miej więcej tak:
  1. <offer>
  2. <id>PDA-MIO A702</id>
  3. <name>Smartphone MIO Digiwalker A702</name>
  4. <price>1666</price>
  5. <url>link_do_produktu_w_sklepie_internetowym</url>
  6. <categoryId>Smartphony/MIO</categoryId>
  7. <description><p>
  8. Mio A702 to rewolucyjne urządzenie, które mimo niewielkich rozmiarów (57.5x110 mm, waga 148 g) łączy w sobie funkcje kilku urządzeń.
  9. </p>
  10. </description>
  11. <image>link_do_obrazka_na_serwerze_sklepu_internetowego</image>
  12. <attributes>
  13. <attribute>
  14. <name>Kod_producenta</name>
  15. <value>PDA-MIO A702</value>
  16. </attribute>
  17. <attribute>
  18. <name>Producent</name>
  19. <value>MIO</value>
  20. </attribute>
  21. </attributes>
  22. </offer>


obecnie stworzyłem generator pliku XML na podstawie danych z bazy w PHP dla nas, a bardziej dla sklepów,
firm które chcą umieszczać nasze oferty u siebie w sklepach internetowych (format pliku xml narzucam ja)

Wygląda miej więcej tak:
  1. <produkt>
  2. <producent>nazwa_producenta</producent>
  3. <kategoria>kategoria_produktu</kategoria>
  4. <model>model_produktu</model>
  5. <ktm>P170W5DD/T830/160/1,0S1/WF</ktm>
  6. <nazwa>nazwa_produktu</nazwa>
  7. <cenadetal>2849.00</cenadetal>
  8. <cenahurt>2599.00</cenahurt>
  9. <opisdodatkowy>Nowy model laptopa został zbudowany o Technologię procesorow.....</opisdodatkowy>
  10. <opisroz>Nowy model laptopa został zbudowany o Technologię procesorową IntelŽ Centrin.....</opisroz>
  11. <specyfikacja><div class="specyfikacja"><table class="specdetails"  width="100%...<specyfikacja>
  12. <image>obrazek_zakodowany_base64</image>
  13. <dostepnosc>33</dostepnosc>
  14. </produkt>

I teraz moje pytania i wątpliwości:
1) Rozmiar plik xml z zakodowanymi obrazkami base64 wzrasta prawie 45 krotnie (21MB) gdy plik xml z linkami do tych obrazków (http://www...i_tak_dalej) jest wielkości 500KB. Jesli wybiore kodowanie obrazków to mam wielki plik xml'owy i problem z zaciąganiem go przez innych z kolei jak wybiorę linki do tych obrazków to mam problem bo każdy kto wejdzie na stronę sklepu będzie łączył sie z moim serwerem i zaciągał te obrazki. Która metodę proponujecie zastosować?
2) Obrazków zakodowane metodą base64 nieraz wyrzucają zakodowany ciąg znaków z niedopuszczalnymi w xmlu znakami (&, <, >) i wtedy XML wyrzuca mi błąd parsowania. Można to jakość obejść? Ja osobiście pomyślałem aby przefiltrować taki zakodowany ciąg znaków i pozamieniać znaki (&, <, >) na (&, <, >)
3) To bardzie bazodanowe pytanie, bazę mam firebird. Staram sie jakoś zoptymalizować zapytanie bo obecnie trwa bardzo długo. Nie wiem czy to wina bazy (a słyszałem bardzo wiele złego o tej bazie jeśli idzie o używaną pamięci), czy może moje zapytanie SQL jest nie optymalne.

O to moje pytanie SQL w jednym wywołaniu:
  1. SELECT A.ktm, A1.wartosc AS liniawww, A4.wartosc AS kategoria, T.nazwa, T1.opispod, T1.opisroz,
  2. C.cenanet AS cenadetal, C1.cenanet AS cenahurt, TP.ref, B.ext
  3. FROM atrybuty A JOIN atrybuty A1 ON (A1.ktm = A.ktm AND A1.cecha = 'l' AND A1.wersjaref = A.wersjaref)
  4. JOIN atrybuty A2 ON (A2.ktm = A.ktm AND A2.cecha = 'r' AND A2.wartosc = '1' AND A2.wersjaref = A.wersjaref)
  5. JOIN atrybuty A3 ON ((A3.cecha = A1.cecha) AND (A3.wartosc = A1.wartosc) AND (A3.ktm containing('www_')))
  6. JOIN atrybuty A4 ON (A4.ktm = A3.ktm AND A4.cecha = 'gr')
  7. JOIN towary T ON (T.ktm = A.ktm AND T.witryna = '1' AND T.akt = '1')
  8. JOIN towary T1 ON (T1.ktm = A3.ktm AND T1.witryna = '1' AND T1.akt = '1')
  9. JOIN cennik C ON (C.ktm = A.ktm AND C.cennik = '62' AND C.wersja = '0')
  10. JOIN cennik C1 ON (C1.ktm = A.ktm AND C1.cennik = '63' AND C1.wersja = '0')
  11. JOIN towpliki TP ON (TP.ktm = A3.ktm AND TP.numer = '1')
  12. JOIN s_binary B ON (B.fileref = TP.ref)
  13. WHERE A.cecha = 'g' AND ((A.wartosc = 'AR') OR (A.wartosc = 'GPS') OR (A.wartosc = 'ARUM'))


Czas oczekiwania na wynik tego zapytania trwa od 5 do 12 min.exclamation.gif!

oraz zapytanie SQL w więcej niż dwóch zapytaniach:
  1. SELECT A.ktm, A.wartosc, A1.wartosc AS grupa, A2.wartosc AS nazwa,
  2. T.opispod, T.opisroz, TP.ref, B.ext
  3. FROM atrybuty A JOIN atrybuty A1 ON (A1.ktm = A.ktm AND A1.cecha = 'gr')
  4. JOIN atrybuty A2 ON (A2.ktm = A.ktm AND A2.cecha = 'l')
  5. JOIN atrybuty A3 ON (A3.ktm = A.ktm AND A3.cecha = 'podstawowy' AND A3.wartosc = '1')
  6. JOIN towary T ON (T.ktm = A.ktm AND T.witryna = '1')
  7. JOIN towpliki TP ON (TP.ktm = A.ktm AND TP.numer = '1')
  8. JOIN s_binary B ON (B.fileref = TP.ref)
  9. WHERE A.cecha = 'g' AND (A.wartosc = 'AR' OR A.wartosc = 'GPS' OR A.wartosc = 'ARUM')


wynik tego zapytania puszczam w pętli foreach
i dla każdego wiersza wywołuje kolejne zapytanie SQL:
  1. SELECT A.ktm, C.cenanet AS cenadetal, C1.cenanet AS cenahurt, T.nazwa
  2. FROM atrybuty A
  3. JOIN atrybuty A1 ON (A1.ktm = A.ktm AND A1.cecha = 'g' AND A1.wartosc = '".$a_grprod['wartosc']."')
  4. JOIN atrybuty A2 ON (A2.ktm = A.ktm AND A2.cecha = 'r' AND A2.wartosc = '1')
  5. JOIN towary T ON (T.ktm = A.ktm AND T.witryna = '1')
  6. JOIN cennik C ON (C.ktm = A.ktm AND C.cennik = '62' AND C.wersja = '0')
  7. JOIN cennik C1 ON (C1.ktm = A.ktm AND C1.cennik = '63' AND C1.wersja = '0')
  8. WHERE A.wartosc = '".$a_grprod['nazwa']."' AND A.cecha = 'l'


Czas oczekiwania na wynik tych dwóch powyższych zapytania (z czego drugie zapytanie jest wywołane w pętli jakieś 16 razy) trwa od 1 do 2 min.exclamation.gif!

Wyniki tych zapytań są identyczne.

I teraz pytanie, dlaczego tak sie dzieje...

Moze zapytania SQL są jakoś przeze mnie mało efektywnie stworzone..


Wielkie dzięki za jaka kolwiek pomoc, sugestie albo uwagi...
Pozdrawiam...
cbagov
A fotki czemu niby na twoim serwerze skoro plik xml nie ? Trzymanie w nim danych graficznych to pomylka.
Sokrates
Chyba coś źle zrozumiałeś i plik XML i pliki graficzne są u mnie na serwerze.
Różnica jest w tym że jeśli podam linki do zdjęć w pliku XML (który ma 500KB)
To ludzie którzy zaciągną takiego XML'a do siebie z moją oferta i potem pokazują
to na swoich strona, to przy każdym wejściu na taka stronę obrazki będą zaciągane
z mojego serwera (co i tak obciąży mój serwer, bo odnośniki do zdjęć będą wskazywać mój serwer).

Z kolei jak zakoduje całe zdjęcia i umieszczę zakodowany string obrazka w pliku XML
(który ma 21MB) to zaciąganie takiego pliku XML przez innych będzie uciążliwe ale potem jak
ktoś wejdzie do nich na stronę z moją ofertą będzie pobierał obrazki już od nich z serwera bo całe obrazki
znajdowały się w tym pliku XML taki obrazek wystarczyło rozkodować base64 i zapisać np w bazie albo na dysku
lokalnego serwera i do niego się odwoływać jak ktoś będzie przeglądał moja ofertę na ich witrynach sklepowych

I teraz nie wiem na którą metodę się zdecydować, która będzie wydajniejsza, lepsza....

Pozdrawiam...
cbagov
Dobrze zrozumialem bo nie przyszlo mi do glowy zeby ktos ssal xml z moimi grafikami i udostepnial u siebie, potem kazda edycja i problem, nie wspominajac o mega wielkosci.
Natomiast, base64 zwieksza o 1/3 rozmiar wiec dodatkowo sobie robisz naddatek.
Skoro nie chcesz zeby laczyli sie z twoim serwerem a i tak beda sciagac plik xml, to niech bedzie dodatkowy plik z zipowana grafika. Mozesz przygotowac skrypt zasysajacy i rozpakowujacy u chetnego.
Ale to tylko taka dywagacja na marginesie trzymania tych danych w pliku xml, choc w specyficznej sytuacji np. niewielka ilosc miniatur jest jak najbardziej stosowane.
PS. jesli szkoda ci tego serwera;) to mozna rozbudowac skrypt sciagajacy (wrecz nalezy) o cache i po pobraniu xml nastapi ewent. decyzja o dossaniu konkretnych obrazow.
Sokrates
Chodzi o to aby jak najmniej obciążyć serwer...

Poza tym nic nie ściągam tylko udostępnia plik xml, jeśli ktoś chce może go ściągnąć.

Jest też taka wersja aby skrypt który to generuje był wywoływany raz w nocy z crona i zapisywał wynik do pliku.
Wtedy ludzie mieli by adres właśnie do tego pliku XML a nie do pliku PHP który by to generował.

Co do zdjęć, to żadnej edycji zdjęć nie będzie. Zdjęcia są stałe i nie zmienne. Raz zaciągnięte nie będą podlegać modyfikacją.
Jedno zdjęcie do każdego produktu.

Jednak jeśli ktoś ma za każdym razem (raz dziennie) zaciągać te zdjęcia to też bez sensu bo jeśli zdjęcia sie nie zmieniają to po co ma ciągać
to samo? I tak sobie teraz wymyśliłem ze można by zrobić 2 pliki XML jeden z produktami i jeden ze zdjęciami. Plik XML można zaciągać raz dziennie, a pliki ze zdjęciami to można zaciągnąć tylko raz i nie ruszać go do momentu kiedy w pliku XML z produktami nie pojawi się nowy produkt , jak się pojawi nowy produkt to wtedy można znowu pociągnąć plik XML ze zdjęciami. No i następna kwestia to ja mam zdjęcia dużych rozmiarów, można by je przed zapisem do pliku XML z obrazkami pomniejszyć powiedzmy do rozmiarów 300px na 300px.

Można też umieścić w pliku XML tylko adresy (urle) do tych grafik i jak ktoś chce sobie je zapisać u siebie to sobie zapisze i koniec.
A jak nie to będzie się za każdym razem łączył z moim serwerem i pobierał te obrazki... (licząc że serwer wytrzyma, a jak nie wytrzyma to nie będzie miał obrazków)

Co o tym sądzisz....
cbagov
Zdjecia sa stale ale produkty nie, stad beda sie zmieniac i fotki (znikac) czyli dane xml i dane obrazow beda podlegac aktualizacji. Takze nalezy zadbac tak czy siak o usuwanie zbednych i pobieranie nowych.

Przez sciaganie mialem na mysli plik php jaki stworzysz dla chetnych, ktory sobie instaluja i dba on o sciaganie tylko nowych fotek.
Moglby operowac na generowanym przez np cron (lub jesli plik z danymi XML niewielki - to przez php raz dziennie w czasie niskich obciazen)
pliku xml.

Aczkolwiek lepsze rozwiazanie jakie osobiscie stosuje to generowanie tego pliku w czasie edycji danych, latwo sie domyslic, ze gdy edycji nie ma to nic sie nie musi generowac i caly czas oraz obsluga tego procesu przestaje istniec.

Aktualizacja fotek przez sciaganie calego 1 pliku lub wszystkich, jesli cos sie zmienilo -tez odpada.
Lepsze rozwiazanie to albo drugi plik z lista fotek, albo wyciagniecie listy z pliku glownego XML, odseparowanie tych, jakie juz klient ma na swoim serwerze i zassanie tylko nowych.

Ale jak pisalem wczesniej te wydajnosc osiagniesz jesli zaoferujesz ludziom odpowiedni plik z kodem bo czesc operacji musi wykonac serwer klienta (w koncu o to ci chodzi) a inaczej, oferujac czysty plik z danymi jestes wystawiony na ciagle sciaganie dublujacych sie danych z twojego serwera.

Czyli w skrocie:
- podczas edycji generuje sie plik xml-data i/lub dodatkowo xml-img
- klient zainstalowal twoj plik update.php
- plik update.php w okreslonych odcinkach czasu aktualizuje dane przez sciagniecie xml-data i/lub dodatkowo xml-img
- porownuje swoja liste fotek z lista z nowego pliku xml i ewentualnie sciaga roznice:

Mozna znaczyc tagi - linki obrazkow jakims ciagiem zwiazanym np. z data co wyeliminuje porownywanie linkow
Przykladowo:
- klient zassal juz xml-data (z linkami) - linki mialy oznaczenie np. przez TIMESTAMP (czas zapisany przy generowaniu pliku xml czy tez podczas edycji)
- sciagnal wszystkie fotki
- nastepnym razem sciaga plik xml i fotki te, ktore maja wiekszy TIMESTAMP

Ok koncze juz bo predzej bym kod napisal niz ten tekst winksmiley.jpg

To oczywiscie skrot bo w fazie produkcji tego rozwiazani na pewno cos nowego wyskoczy.
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.