Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [php]Ograniczenie zapytań do bazy - buforowanie wyników
Forum PHP.pl > Forum > PHP
Jarod
Mam następujący problem. Mam skrypt, który pobiera z bazy rekordy (około 50) i wyświetla je wiersz pod wierszem. Po lewej stronie jest link - po jego naciśnięciu strona się przeładowuje i jest formularz edycji. Jak damy zapisz, dane się aktualizują w bazie i jesteśmy przekierowywani na stronę główną (pobierane jest znowu 50 rekordów i wyświetlane wiersz pod wierszem). Muszę zrobić bez przeładowywania (żeby nie pobierać za każdym razem 50 rekordów). Do głowy wpadło mi takie rozwiązanie:

Pobierać z bazy do tablicy dane tylko jeden raz (przy pierwszym ładowaniu strony). A przy edycji wybranego wiersza, update do bazy i edytowanych danych w tablicy a następnie powrót na stronę główną i wyświetlanie danych już z tablicy (bez ponownego pobierania z bazy).

Problem w tym, że nie wiem jak najlepiej taką tablicę przechowywać, żeby jej nie stracić przy przejściu na inną stronę? Umieścić w sesji danego użytkownika? Inny problem to jeszcze będę musiał sprawdzić czy inny użytkownik czegoś nie edytował a jeśli tak to pobranie tych nowych (zmienionych) danych z bazy..

Czy to dobry pomysł?
Cysiaczek
1. Możesz trzymać dane zserializowane np w sesji (nikoniecznie jest to jednak bezpieczne)
2. Jełśi chodzi o ewentualne zmiany w bazie, to utwórz sobie na dysku plik o unikalnej nazwie. Pamietaj go w sesji użytkownika. Za każdym razem, gdy ktoś coś zmieni w bazie - niech jednocześnie zmienia nazwe pliku. Ty z kolei sprawdzaj, czy nazwa pliku w sesji uzytkownika jest taka sama jak tego na dysku. Jeśli nie, to pobieraj dane.

Może być?

Pozdrawiam
kossa
Moim zdaniem zapytanie na 50 rekordach jeśli serwer jest dobry, baza jest zindeksowana to wogóle nie jest odczuwalne. Za dużo zachodu z kombinowaniem Cysiaczek :-)


Pozdrawiam,
Łukasz
nospor
Ja ostatnio jakis monotematyczne jestem, ale do tego dobrze nadaje sie cache smile.gif

Zapisujesz tablice do cache'u raz a potem pobierasz juz tylko z cache a nie z bazy. Przy jakiejkolwiek modyfikacji tabeli czyscisz cache, wymuszajac w ten sposob odswierzenie danych.

proszę poprawić tytuł o znacznik zgodnie z zasadami forum Przedszkole:
Temat: Tematyka i zasady panujace na forum Przedszkole
Jarod
Cytat(Cysiaczek @ 27.07.2006, 11:37 ) *
1. Możesz trzymać dane zserializowane np w sesji (nikoniecznie jest to jednak bezpieczne)


Mógłbyś podpowiedzieć jak wykonać taką serializację? Weźmy pod uwagę że jeden wiersz może zawierać do 500 znaków tekstowych. Czy to nie obciążą?

Cytat(Cysiaczek @ 27.07.2006, 11:37 ) *
2. Jełśi chodzi o ewentualne zmiany w bazie, to utwórz sobie na dysku plik o unikalnej nazwie. Pamietaj go w sesji użytkownika. Za każdym razem, gdy ktoś coś zmieni w bazie - niech jednocześnie zmienia nazwe pliku. Ty z kolei sprawdzaj, czy nazwa pliku w sesji uzytkownika jest taka sama jak tego na dysku. Jeśli nie, to pobieraj dane.


Czy nie lepiej dodać do bazy pole update które będzie przyjmowało wartość true dla wiersza edytowanego i false dla wiersza, którego nie zmieniano? Pozatym edycja będzie odbywać się przez kilku użytkowników.. I chciałbym, żeby pobierane były z bazy tylko rekordy zmienione a reszta (tych nie edytowanych) wczytywana z pamięci. Czy to ma sens? Czy algorytm nie będzie na tyle skomplikowany, że bardziej będzie się opłacało wczytywać wszystko za każdym razem?


Cytat(Cysiaczek @ 27.07.2006, 11:37 ) *
Za każdym razem, gdy ktoś coś zmieni w bazie - niech jednocześnie zmienia nazwe pliku. Ty z kolei sprawdzaj, czy nazwa pliku w sesji uzytkownika jest taka sama jak tego na dysku. Jeśli nie, to pobieraj dane.


Nie sprawdzisz czy nazwa pliku jest taka sama. Co najwyżej czy plik istnieje.


Cytat(nospor @ 27.07.2006, 11:39 ) *
Ja ostatnio jakis monotematyczne jestem, ale do tego dobrze nadaje sie cache smile.gif

Zapisujesz tablice do cache'u raz a potem pobierasz juz tylko z cache a nie z bazy. Przy jakiejkolwiek modyfikacji tabeli czyscisz cache, wymuszajac w ten sposob odswierzenie danych.

proszę poprawić tytuł o znacznik zgodnie z zasadami forum Przedszkole:
Temat: Tematyka i zasady panujace na forum Przedszkole


Czy trudno jest wykonać cachowanie danych? (zależy mi na nieobiektowości, ponieważ projekt jest pisany strukturalnie i nie chcę mieszać.

Pozatym też nie do końca mi o to chodzi. Chciałbym pobierać z bazy tylko te rekordy, które się zmieniły. A resztę z "cachea"..
Cysiaczek
1. W manualu sa funkcje serialize() i unserialize() - poczytaj - zastanów się jak najlepiej zorganizowac te dane i je zserializuj. Oczywiście @nospor pisał o użyciu jakiejś klasy cashe. To jest najlepsze rozwiaznie.

2 i 3. Nie ważne ilu użytkowników updatuje dane. Chodzi o to tylko, aby zasygmalizować, że taki update wogóle miał miejsce. Tak masz rację - sprawdzasz, czy plik istnieje tongue.gif
nospor
Cytat
Czy trudno jest wykonać cachowanie danych? (zależy mi na nieobiektowości, ponieważ projekt jest pisany strukturalnie i nie chcę mieszać.
nie. w najprostrzym razie zapisujesz tablice do pliku i juz masz cache smile.gif
Mozesz uzywac gotowych klas, ktore includujesz do swego skryptu i tez nie ma problemu.

Cytat
Pozatym też nie do końca mi o to chodzi. Chciałbym pobierać z bazy tylko te rekordy, które się zmieniły. A resztę z "cachea"..
Kombinujesz teraz. jak czesto bedziesz modyfikowal dane? Wplynie to az tak na wydajnosc? A tak masz latwosc obslugi bez kombinowania.
Ale jesli sie uprzesz to mozesz zmodyfikowac rekord, pobrac dane z cache, wstawic zmiany (zmiany znasz bo przeciez modyfikowales) i wstawic spowrotem do cache
Jarod
Cytat(nospor @ 27.07.2006, 11:56 ) *
Ale jesli sie uprzesz to mozesz zmodyfikowac rekord, pobrac dane z cache, wstawic zmiany (zmiany znasz bo przeciez modyfikowales) i wstawic spowrotem do cache


W sumie masz rację. Ale czy to nie bedzię dłużej trwało niż pobranie 50 rekordów naraz, obróbka w pętli i wyświetlenie? Teraz przy przeładowywaniu stronu można doliczyć się 3 sekund :/
nospor
Cytat
W sumie masz rację. Ale czy to nie bedzię dłużej trwało niż pobranie 50

  1. <?php
  2. $ar = GetFromCache();
  3. $ar['idzmienioengorekordu'] = $zmienionatablicarekordu;
  4. PutInCache($ar);
  5. ?>

Nie, mysle ze to nie bedzie dlugo trwalo smile.gif

Cytat
Teraz przy przeładowywaniu stronu można doliczyć się 3 sekund :/
Nie sadze by pobranie 50 rekordow trwalo 3 sek. Problem moze masz na laczu, inne dane moze ci opoźniają, a moze masz zapytanie nieefektywne
Jarod
Cytat(nospor @ 27.07.2006, 12:10 ) *
Nie sadze by pobranie 50 rekordow trwalo 3 sek. Problem moze masz na laczu, inne dane moze ci opoźniają, a moze masz zapytanie nieefektywne


Sprawdzałem na localhost. Całość będzie chodzić po lanie. Wklejam poniżej kod. Wiem, że początek mogę zoptymalizować (konkretnie pobranie date i sprawdzanie. Mogę zastąpić sprawdznie tablic POST i GET jedną). Całość prezentuje się tak:

Skrypt
nospor
"podoba" mi sie ten kawalek. jest bardzo "optymalny"
  1. <?php
  2. $query = 'SELECT gracz.rejs_id, rejs.numer_rejsu, DATE_FORMAT(godzina, '%H:%i'), book, '.
  3.  'cat, lid, age, ga, radio, radio2, skrzynia, sam, nic, nfc, '.
  4.  'nopi, ilos, lista_uc, lista, sq, asysta, uwagi, gracz_id_powiazanie FROM rejs, g
    racz '
    .
  5.  'WHERE data=''.$biezacaData.'' AND kierunek='o' AND rejs.rejs_id=gracz.rejs_id ORDER BY godzina';
  6. $result = mysql_query($query) or die ('Zapytanie nieudane!');
  7.  
  8.  
  9.  //Pobranie rejs_id_powiazanie - sortowane po godzinie
  10. $query2 = 'SELECT godzina, gracz_id_powiazanie FROM rejs WHERE data=''.$biezacaData.'' AND kierunek='o' ORDER BY godzina';
  11. $result2 = mysql_query($query2) or die ('Zapytanie nieudane!');
  12.  
  13. while ( $query_data2 = mysql_fetch_row($result2) )
  14. {
  15. $powiazania[] .= intval($query_data2[1]);
  16. }
  17.  
  18. //Zmienna iteracyjna
  19. $licznik = 0;
  20. //Wyświetlenie rozkładu
  21. while ($query_data = mysql_fetch_row($result))
  22. {
  23. //Pobranie godziny przylotu dla odpowiedniego dnia (data przylotu może być <> daty odlotu! )
  24. $query3 = 'SELECT DATE_FORMAT(godzina, '%H:%i') FROM rejs WHERE rejs_id = '.$powiazania[$licznik];
  25. //....
  26. }
  27. ?>

robisz zapytania w petli dla innego zapytania, na dodatek wszystkie te zapytania operują na tej samej tabeli. Nie mozna tego uproscic? Bo taka konstrukcja nie sluzy zbytnio czasowi
Jarod
Cytat(nospor @ 27.07.2006, 13:13 ) *
"podoba" mi sie ten kawalek. jest bardzo "optymalny"
  1. <?php
  2. $query = 'SELECT gracz.rejs_id, rejs.numer_rejsu, DATE_FORMAT(godzina, '%H:%i'), book, '.
  3.  'cat, lid, age, ga, radio, radio2, skrzynia, sam, nic, nfc, '.
  4.  'nopi, ilos, lista_uc, lista, sq, asysta, uwagi, gracz_id_powiazanie FROM rejs, g
    racz '
    .
  5.  'WHERE data=''.$biezacaData.'' AND kierunek='o' AND rejs.rejs_id=gracz.rejs_id ORDER BY godzina';
  6. $result = mysql_query($query) or die ('Zapytanie nieudane!');
  7.  //Pobranie rejs_id_powiazanie - sortowane po godzinie
  8. $query2 = 'SELECT godzina, gracz_id_powiazanie FROM rejs WHERE data=''.$biezacaData.'' AND kierunek='o' ORDER BY godzina';
  9. $result2 = mysql_query($query2) or die ('Zapytanie nieudane!');
  10.  
  11. while ( $query_data2 = mysql_fetch_row($result2) )
  12. {
  13. $powiazania[] .= intval($query_data2[1]);
  14. }
  15.  
  16. //Zmienna iteracyjna
  17. $licznik = 0;
  18. //Wyświetlenie rozkładu
  19. while ($query_data = mysql_fetch_row($result))
  20. {
  21. //Pobranie godziny przylotu dla odpowiedniego dnia (data przylotu może być <> daty odlotu! )
  22. $query3 = 'SELECT DATE_FORMAT(godzina, '%H:%i') FROM rejs WHERE rejs_id = '.$powiazania[$licznik];
  23. //....
  24. }
  25. ?>

robisz zapytania w petli dla innego zapytania, na dodatek wszystkie te zapytania operują na tej samej tabeli. Nie mozna tego uproscic? Bo taka konstrukcja nie sluzy zbytnio czasowi



Właśnie nie mogę. Powodem jest "genialność" aplikacji pisanych przez comarch.. Nie mogę wyciągnąć godziny przylotu bez pętli..
cadavre
A zwyczajnie JSem?
  1. <a href="java script:history.go(-1)">Wróc</a>
W Twoim przypadku będzie -2 chyba. Tylko, że wtedy zmieniona wartość wyświetlona zostanie ze starą wartością (wyświetloną, bo z bazie będzie już update).
Jarod
Cytat(cadavre @ 27.07.2006, 22:43 ) *
A zwyczajnie JSem?
  1. <a href="java script:history.go(-1)">Wróc</a>
W Twoim przypadku będzie -2 chyba. Tylko, że wtedy zmieniona wartość wyświetlona zostanie ze starą wartością (wyświetloną, bo z bazie będzie już update).

Ale co to da? Bo nie łapie o co Ci chodzi..


I jeszcze pytanie z innej beczki. Skoro sprawdzanie czy ktoś coś edytował w bazie ma się sprowadzać do sprawdzenia czy istnieje plik, to czy trzeba się jakoś zabezpieczyć?
Chodzi mi o sytuacje, że dwóch pracowników edytuje ten sam rekord (albo inny) i jednocześnie przesyłają nowe dane do zapisu. Skrypt aktualizuje dane w bazie, kasuje plik z cachem i następuje powrót na stronę główną. Na stronie głównej sprawdzane jest czy plik istnieje (ponieważ już nie istnieje) następuje odczyt z bazy nowych danych i zapis do chache. Możemy zablokować na czas zapisu plik ale gdzieś czytałem, że tego typu operacje nie są bezpieczne. Jak się zabezpieczyć przed sytuacją, gdy dwóch użytkownik w tym samym czasie zapisuje chache do pliku, albo gdy jeden edytował rekord i usuwa cache a drugi właśnie chce zapisać chace..?

Mam nadzieje, że nie zamotałem..
nospor
Cytat
Chodzi mi o sytuacje, że dwóch pracowników edytuje ten sam rekord (albo inny) i jednocześnie przesyłają nowe dane do zapisu. Skrypt aktualizuje dane w bazie, kasuje plik z cachem i następuje powrót na stronę główną. Na stronie głównej sprawdzane jest czy plik istnieje (ponieważ już nie istnieje) następuje odczyt z bazy nowych danych i zapis do chache. Możemy zablokować na czas zapisu plik ale gdzieś czytałem, że tego typu operacje nie są bezpieczne. Jak się zabezpieczyć przed sytuacją, gdy dwóch użytkownik w tym samym czasie zapisuje chache do pliku, albo gdy jeden edytował rekord i usuwa cache a drugi właśnie chce zapisać chace..?
Opisana przez Ciebie sytuacja jest troche "nieteges"* smile.gif
Edytujesz rekord, czyscisz cache. Na stronie glownej ktos go odswierza i cache juz jest. W tym samym czasie ktos edytuje rekord, czysci dopiero co odswierzony cache (i bardzo dobrze) i na stronie glownej ktos go znowu odswierzy. Wszystko ok. A jesli chodzi ci o trafienie zapisu do pliku w tym samym czasie... hmmm, a w totka trafiles kiedys szostke? smile.gif

ps: przenosze na php

---------------------
nieteges* - to znaczy, ze jest nieteges
Jarod
Cytat(nospor @ 28.07.2006, 07:23 ) *
Opisana przez Ciebie sytuacja jest troche "nieteges"* smile.gif
Edytujesz rekord, czyscisz cache. Na stronie glownej ktos go odswierza i cache juz jest. W tym samym czasie ktos edytuje rekord, czysci dopiero co odswierzony cache (i bardzo dobrze) i na stronie glownej ktos go znowu odswierzy. Wszystko ok.


Taka sytuacja jest bardzo możliwa. Przykład: Na stronie masz np. 10 rekordów. Ty edytujesz pierwszy a ja drugi. Dajesz zapisz, skrypt kasuje plik z chacem i tworzy na nowo, zapisujeąc nowego cachea. Dosłownie w tej samej chwili robię to ja. Po sprawdzeniu czy plik istnieje, po moim updajcie próbuje kasować plik, który Ty już skasowałeś. Wystąpi błąd. Czyli mamy cache bez aktualizacji jednego wiersza.

Inna przykład. Bez kasowania pliku z cachem. W tym samym momencie próbujemy zapisać cache do pliku. Tylko jedna osoba może to w danym momencie zrobić..

Cytat(nospor @ 28.07.2006, 07:23 ) *
A jesli chodzi ci o trafienie zapisu do pliku w tym samym czasie... hmmm, a w totka trafiles kiedys szostke? smile.gif


Zdziwiłbyś się winksmiley.jpg
nospor
Cytat
Ty edytujesz pierwszy a ja drugi. Dajesz zapisz, skrypt kasuje plik z chacem i tworzy na nowo, zapisujeąc nowego cachea. Dosłownie w tej samej chwili robię to ja. Po sprawdzeniu czy plik istnieje, po moim updajcie próbuje kasować plik, który Ty już skasowałeś. Wystąpi błąd. Czyli mamy cache bez aktualizacji jednego wiersza.
Jaki blad? Wywali noticem tudziez Warningiem ze nie ma pliku. Co to ma do blednego dzialania aplikacji? Chciales skasowac plik, ktorego nie ma, w rezultacie pliku nadal nie bedzie. i oto chodzi. Gdzie tu blad?

Cytat
W tym samym momencie próbujemy zapisać cache do pliku. Tylko jedna osoba może to w danym momencie zrobić..
System plikow jakos se z tym poradzi. Pozatym naprawde zycze szcześcia zeby sie wstrzelic w taką sytuacje smile.gif
Jarod
Czy przy zapisie do pliku należy blokować do niego dostęp?
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.