Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: PHP operacje na Plikach
Forum PHP.pl > Forum > PHP
koneser69
Witam

Muszę napisać aplikację w php która odbiera dane i zapisuje do pliku.
Danych jest bardzo dużo - powstają pliki po około 1MB.
Problem jest w tym, że odbierane dane nie są wysyłane w sortowanej kolejności. Jak zapisuję to co odbieram to otrzymuję.

  1. TIME:154459
  2. TIME:002225
  3. TIME:154458
  4. TIME:002254
  5. TIME:002354
  6. TIME:002324

Chciałbym aby podczas zapisu od razu dane zostały posortowane.
  1. TIME:154459
  2. TIME:154458
  3. TIME:002354
  4. TIME:002324
  5. TIME:002255
  6. TIME:002224

Czy ktoś zna wydajny a zarazem bezpieczny sposób na rozwiązanie mojego problemu?
Blackhole
Jak są te dane odbierane? Przed wysłaniem ich (jakim sposobem) przechowujesz je tymczasowo?
YourFrog
Muszą być pliki czy może być np baza danych ? Tam tego problemu by nie było.


Jeżeli zaś chodzi o pliki. To jedyne rozwiązanie jakie mi się nasuwa to za każdym razem przy zapisie poszukiwać odpowiedniego wiersza w którym należy wstawić. Biorąc pod uwagę że będzie to plik uporządkowany to można użyć algorytmu dziel i zwyciężaj.

Co to bezpieczeństwa. Gdy będziesz blokował plik przy otwarciu i zdejmował blokadę przy zapisie to nic się nie stanie.
koneser69
Dane odbieram z portu socketami. Nie przechowuję ich tymczasowo. Odbieram i zapisuję.
Bazy danych odpadają nie wytrzymią tego.

YourFrog czy masz gdzieś przykład kodu który będę mógł wykorzystać.
Crozin
Cytat
Bazy danych odpadają nie wytrzymią tego.
Ciekawi mnie skąd taki wniosek, szczególnie w kontekście tematu dot. zwykłego pliku tekstowego.
Wazniak96
Jeśli odbierasz dane jako jedna zmienna, i każda wartość jedna pod drugą to:
  1. $array = explode(PHP_EOL, $data);
  2.  
  3. rsort($array);
  4.  
  5. $data = implode(PHP_EOL, $data);


Jak nie to sobie przerób smile.gif

PS: Zastanów się rzeczywiście czy nie umieścić danych w bazie...
sazian
ile masz dokładniej tych danych ? napisałeś że są to pliki po około 1MB ale z jaką częstotliwością zbierasz te dane ?
Czy to 1MB masz co sekundę ? dwie ? dziesięć? co minutę ?

Jeśli upierasz przy plikach, a przy tym nie potrzebujesz dostępu do tych danych poprzez plik natychmiast to możesz użyć jakiegoś systemu cache w pamięci ram(np. APC). Wtedy dane zapisujesz w pamięci jako tablicę którą możesz sortować, a gdy zostaną osiągnięte pewne kryteria zapisujesz tablicę na dysk jednocześnie czyszcząc tą w pamięci.

Ale i tak uważam że baza będzie bardziej wydajna
koneser69
Dane są odbierane z konkretnego urządzenia i zapisywane do pliku o id urządzenia co 5 sekund. Urządzeń jest 100. to działa na soketach. Tzn te 100 urządzeń wysyła dane równocześnie tworzą się osobne procesy z których każdy operuje na innym pliku. I tak to działa. Z tym, że muszę to mieć posortowane w tym pliku.
Postać odbieranej danej
#11111111111,CMD-F,V,DATE:140310,TIME:152556,LAT:67890988899N,LOT:78888776678E,Speed:000.1,0-0-1-0-16-10,000#

a sortowanie w pliku ma być po time.
maly_swd
Baza danych do tego będzie najlepsza.
Rozwiąże Ci to masę problemów i będziesz mógł to przeszukiwać, grupować, wyliczać trasę itp.
sazian
Zacząłem liczyć i rzeczywiście problem wydaje się być nieco bardziej skomplikowany, ponieważ ten system będzie generował ponad półtora miliona rekordów na dobę smile.gif
W związku z tym myślę że baza danych będzie jedynym sensownym rozwiązaniem dlatego że:
1)jest łatwiej zarządzać danymi
2)zapisujesz mniej danych na dysku - według moich skromnych obliczeń pliki z jednego miesiąca będą zajmowały 5GB, natomiast baza około 1GB

koneser69
Witam

Na studiach uczyli mnie, że do tego typu programów nie należy stosować bazy danych.
Tak to przygotowałem, że dane z każdego dnia są zapisywane w osobnych plikach tzn jest katalog rok/mc/dzień i tutaj są dane z poszczególnych urządzeń. Użytkownik który będzie operował na tych danych będzie maił możliwość wyboru urządzenia oraz konkretnego dnia.

Jak dane będą w bazie dany tzn w jednej tabelce bo nie ma nawet jak tego rozbić aby dokonać jakiejkolwiek optymalizacji. To każde zapytanie wydobywające tzn select będzie musiał przeanalizować wszystkie dane w tej tabelce. W przypadku gdy dane będą trzymane w plikach wystarczy pobrać dane z konkretnego pliku w katalogu dzień I to by było bardzo szybkie gdyby dane były posortowane.
nospor
1) Nic nie stoi na przeszkodzie, bys stworzyl tyle tabel ile urządzen. To nie problem.
2) Baza danych całkiem dobrze radzi sobie z dużą ilością rekordów. Wystarczy tylko wlasciwy indeks zalozyc.

ps: to dane urządzenie wysyła dane z roznymi datami? raz 2 godziny wstecz a pozniej 3 godziny wstecz? Dziwne...
koneser69
Samo urządzenie działa dobrze. Gdy uda mu się nawiązać połączenie to wysyła aktualne położenie a następnie te które ma w pamięci - i tu pojawia się mój problem z sortowaniem.
nospor
No to jedyne co musisz posortowac do dane otrzymane z urządzenia, a nie dane w pliku za kazdym razem. No to do tego przyda sie array_multisort.
koneser69
Witam

Postanowiłem przerobić program żeby korzystał z BD. Pojawia się kolejny problem. Skrypt podczas uruchomienia łącz się z BD

  1. $dbhandle = mysql_connect($hostname, $username, $password) or die("Unable to connect to MySQL");
  2. $selected = mysql_select_db($db_name, $dbhandle) or die("Could not select examples");


niestety połączenie po czasie wygasa. Przez co nie można wykonywać kolejnych insertów. Jak sobie poradzić z takim problemem.
YourFrog
Hej,

Przy tak dużej ilości danych wydaje mi się że PHP powinien odpaść. Jeżeli jednak zdecydujesz się na PHP to do bazy rzucaj dane które zgrupujesz np po 100 wpisów. Zmień MySQL na Postgres'a to zwiększysz wydajność bazy.
Zigi
Cytat(koneser69 @ 13.03.2014, 13:35:23 ) *
niestety połączenie po czasie wygasa. Przez co nie można wykonywać kolejnych insertów. Jak sobie poradzić z takim problemem.


Możesz napisać po ilu sekundach? Zgaduję: Może powinieneś zebrać wszystkie dane z socketa i dopiero wtedy na końcu skryptu wszystko zapisać.
Możesz zastosować taką konstrukcję żeby jednym zapytaniem zapisać wiele rekordów na raz:
  1. INSERT INTO TABLE ( Column1, Column2 ) VALUES
  2. ( Value1, Value2 ), ( Value1, Value2 )
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.