PDA

Pogčedajte punu verziju : Kako realizovati FIFO buffer u PHPu


shoba
15. 10. 2007., 20:08
Kako realizujete FIFO buffer u PHPu?

Da bih bio jasniji dacu jedan primer FIFO buffera. Na primer, treba napraviti opciju da se zapisuje poslednjih 10 posetilaca necijeg licnog profila ili stranice. Dakle, za svaki profil bih u bazi zapisivao poslednjih 10 usernameova koji su ga posetili.

Da li bi resenje bilo sledece:

- pri svakoj novoj poseti profila proveravam koliko je poseta imao taj profil
- ako je imao manje od 10, zapisujem novi red
- ako je imao vise od 10 brisem najstarijeg iz tabele (znaci da sam uz username pamtio i datum) i upisujem novi

Ima li neko elegantnije/logicnije/brze resenje?

misk0
15. 10. 2007., 20:21
Ne moras brisati najstarijeg pa insertovati novi, samo updateujes (overwrite) taj najstariji sa novim podacima.

benjamin
15. 10. 2007., 20:29
Kako realizujete FIFO buffer u PHPu?

Da bih bio jasniji dacu jedan primer FIFO buffera. Na primer, treba napraviti opciju da se zapisuje poslednjih 10 posetilaca necijeg licnog profila ili stranice. Dakle, za svaki profil bih u bazi zapisivao poslednjih 10 usernameova koji su ga posetili.

Da li bi resenje bilo sledece:

- pri svakoj novoj poseti profila proveravam koliko je poseta imao taj profil
- ako je imao manje od 10, zapisujem novi red
- ako je imao vise od 10 brisem najstarijeg iz tabele (znaci da sam uz username pamtio i datum) i upisujem novi

Ima li neko elegantnije/logicnije/brze resenje?

Generalno nema potrebe da pamtiš datum, ukoliko optimizuješ bazu, mada je preporučljivo jer ko zna za šta će ti posle zatrebati. ako je baza lepo podešena id polja će ti fino raditi taj deo posla.

dakle ako imaš tabelu visits [id, who, whom], jednostavan select * from visits where whom = 'ime_profila' order by id desc /*ili datum ukoliko ga koristis */ limit 0, 10;


na taj način izbegneš brisanje iz baze, realno niko ne voli brisanje iz baze :).

ukoliko dodaš datum, možeš ovo koristiti i za neku lepu statistiku (ukoliko ne brišeš rekorde)

e da nije mi samo jasan taj uslov ukoliko ima manje od 10 poseta upisuješ posetu ? valjda bi je upisivao u svakom slučaju

misk0
15. 10. 2007., 20:42
Da, ali tako pamti SVE MOGUCE posjete, sto vremenom u zavisnosti od broja korisnika moze da bude... ogromna kolicina podataka. Isto tako, ukoliko jedan korisnik posjeti 3 puta nekoga bice 3 puta njegov nick na listi. Znaci samo insertovanje bas i nije mudra odluka.


e da nije mi samo jasan taj uslov ukoliko ima manje od 10 poseta upisuješ posetu ? valjda bi je upisivao u svakom slučaju

Pa na pocetku, kod novoregistrovanih korisnika koji nemaju ni jednu 'posjetu'.

ivanhoe
15. 10. 2007., 22:08
jos jednostavnije, napravi inicijalno svakom po 10 dummy recorda za posete, i onda samo radi update najstarijeg recorda:
UPDATE tabela
SET name='nesto_novo'
WHERE id=(SELECT id FROM tabela ORDER BY datum LIMIT 1)

kodi
15. 10. 2007., 22:15
-napravis autoincrement id
-ubacis novi record

//losije resenje
-prebrojis recorde
-ako ih imas vise od 10, obrises onaj sa najmanjim id-om


//malo bolje resenje
-obrises sve sto ima id manji od (next_auto_id-10)

edit: i meni je palo na pamet nesto slicno kao sto je rekao ivanhoe, osim sto tu ne mozes da budes siguran da imas tacno 10 recorda, ali to jeste najbrze resenje jer nema brisanja

kodi
15. 10. 2007., 22:37
btw, ovo mu vise dodje round-robin nego FIFO ;)

a evo i detaljnog resenja (uz pomoc trigera)

http://www.shinguz.ch/MySQL/rrd.pdf

noviKorisnik
15. 10. 2007., 22:55
Ako sam dobro razumeo, želiš uređenu listu poslednjih 10 posetilaca profila.

Ok, ako ih nije bilo 10, onda će biti manje, no to i ne može da pravi neki problem.

Ono što je interesantno, to je - šta ukoliko u poslednjih 10 poseta ima više poseta od istog korisnika (mora da je neki prijatelj onda)? Ako tražimo poselednjih 10 posetilaca, onda mu se priznaje samo jedna poseta, a pošto treba da bude uređena lista, to se računa samo najsvežija poseta, odnosno treba da nestane prethodna koja je bila tu, isplivavanje posetioca, efekat mehurića :-)

Recimo, stavimo tabelu posete, 3 polja: domaćin, gost i vreme posete, primarni ključ na domaćinu i gostu, dodatni indeks za domaćina.

Pa onda - dolazak gosta:

- ubaci da je gost posetio domaćina sad. ... ako javi da je affected_rows < 0, znači da je gost već ranije dolazio, pa treba njihov zapis to da se osveži sadašnjim trenom.

Uređena selekcija poslednjih 10:

- odaberi goste i njihovo vreme kad su bili kod ovog domaćina, ređaj po svežini i da ih ne bude više od 10.

Vidiš da nigde ne spominjem brisanje ... ne znam koliki broj zapisa bi trebao da bude da ovo počinje da guši, ako imaš 1000 korisnika i svi socijalni manijaci pa se međusobno isposećuju, to bi bilo blizu milion zapisa, pa ti vidi ima li potrebe.

filjo
16. 10. 2007., 01:28
nemoj ni da pravis novu tabelu, dodaj samo polje posete varchar(200) u korisnike


$posete // iz tabele
$koID // ID posetioca

$posete=str_replace($koID.';','',$posete);
if (substr_count($posete,';')>=10)
$posete=substr($posete,strpos(';',$posete)+1)
$posete.=$koID.';'; // dodavanje na kraj


// ispis

$arr=explode(';',$posete);
for ($i=count($arr)-2;i>=0;$i--)
echo 'userID='.$arr[$i];


tako nekako, a puno brze

bluesman
16. 10. 2007., 01:41
Ako želiš mene da poslušaš, napraviš tabelu posete (user_id, visitor_id, timestmap) i samo ubacuješ u tu tabelu, a onda kroz neko cron jednom dnevno obrišeš sve upise starije od mesec dana.

Na taj način:
- ne opterećuješ user tabelu dodatnim poljem
- ne upisuješ / brišeš svaki čas veš samo upisuješ a brišeš jednom dnevno
- ne "maltretiraš" users tabelu već drugu tabelu koja je daleko manje bitna
- useri sa puno poseta će ti biti zahvalni, useri sa malo poseta ne zauzimaju prostor.

Ne znam koliko je bitno da bude baš tačno 10 poslednjih, ako jeste možeš iz tabele da kupiš samo tih poslednjih 10 i to je to.

shoba
16. 10. 2007., 12:35
Hvala na pomoci.

Naravno da niko ne voli brisanje i svakako da je brisanje pre svakog azuriranja najgore i najsirovije resenje. Ali opet ne smem ni samo upisivati podatke i ne razmisljati o tabeli nakon nekog vremena.

Dobro resenje je uvek negde izmedju pa cu izvagati izmedju brisanja s vremena na vreme pomocu crona ili bez brisanja uz odgovarajuci update.

:1043:

cvele
16. 10. 2007., 14:13
Potpuno se slazem sa onime sto je Blues rekao...
Ukoliko ti imas ocekivanje da ce ti se tabela prepunjavati, postavi trigger koji ce na svakih 500k redova particionisati tabelu.