Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [php] nieprzeczytane posty
Forum PHP.pl > Forum > PHP
AndyPSV
w jaki sposob rozwiazac najefektywniej problem "ostatnio przeczytanych" postow?
musi to byc baza? czy cookie albo sesja?

jak to zrobic?
zapisuje nieprzeczytane posty od daty ostatniej wizyty (24h) a nastepnie je kasuje?

chodzi mi o teorie
chodzi mi o rozwiazanie mozliwie jak najlepsze (najszybsze, takie ktore wytrzyma znaczacy ruch)
hind
robisz tabele, w której są informacje które posty dany user nie przeczytał (id-usera, id-temat, id/data ostatno przeczytanego
lub po prostu po dacie ostatniego logowania wyświetlasz miany
thek
Andy... Tyle razy nawet tutaj na forum temat wałkowany. Nie mogłeś użyć szukajki? Sam tu się w przynajmniej 2-3 tematach o tym wypowiadałem. Ludzie rzucali wieloma pomysłami, także optymalizowanymi już. Nie jesteś tu na forum nowy i naprawdę nie potrafisz go przejrzeć? Jeśli Ty nie potrafisz, to niby nowi, którzy są tu góra kilka miesięcy, myślisz, że używają opcji Szukaj?
AndyPSV
Jednak doszedlem do wniosku, ze baza danych to najlepsze i najszybsze rozwiazanie. Tematy beda markowane od daty last_logd (ostatniego logowania), a pozniej w momencie przeczytania usuwane z bazy danych.

  1. CREATE TABLE `xx`.`XX_ph_unread` (
  2. `id` INT( 11 ) NOT NULL AUTO_INCREMENT ,
  3. `id_u` INT( 11 ) NOT NULL ,
  4. `id_` INT( 11 ) NOT NULL ,
  5. PRIMARY KEY ( `id` )
  6. ) ENGINE = MYISAM
thek
A więc to rozwiązanie nie jest optymalne Andy
1. Wezmę się zaloguję, zapomnę hasła, nie wchodzę na serwer przez 2 miesiące. Co robisz i jak wygląda w bazie ta tabela przy kilkudziesięciu takich userach? winksmiley.jpg
2. Jak wygląda "markowanie"? Kiedy je robisz? Każdemu userowi w bazie w chwili zalogowania ponownego? Po każdym dodaniu nowego postu wszystkim userom? A co gdy user/moderator usuwa jakiś post/wydziela do innego tematu/zmienia jego widoczność userom?
3. Czy za przeczytanie uznajemy wejście na dowolną stronę tematu, czy tylko zawierającą ów post?
4. Po co Ci w tabeli kolumna id z auto increment? Czy klucz unikatowy na (id_usera, id_posta) nie jest wystarczający? A może rozbić go na dwa klucze typu index, po jednym dla każdej z wymienionej przeze mnie dwóch kolumn?

Nadal uważasz, że Twój pomysł to najlepsze rozwiązanie? winksmiley.jpg A co najważniejsze... Czy aby faktycznie optymalne? To tylko mały zgrzyt, który chciałbym byś zauważył, a o którym w tematach tu na forum PISALIŚMY, i gdybyś tam zajrzał to byś o nich PRZECZYTAŁ.
AndyPSV
znalazlem tylko to: http://forum.php.pl/index.php?showtopic=20...mp;#entry129428
reszta to posty nic nie wnoszace do tematu

Cytat
1. Wezmę się zaloguję, zapomnę hasła, nie wchodzę na serwer przez 2 miesiące. Co robisz i jak wygląda w bazie ta tabela przy kilkudziesięciu takich userach?


limit 100 nieprzeczytanych postow?
musze to przemyslec

Cytat
2. Jak wygląda "markowanie"? Kiedy je robisz? Każdemu userowi w bazie w chwili zalogowania ponownego? Po każdym dodaniu nowego postu wszystkim userom? A co gdy user/moderator usuwa jakiś post/wydziela do innego tematu/zmienia jego widoczność userom?

uzytkownik ma opcje "zaznacz wszystkie posty jako przeczytane"

Cytat
3. Czy za przeczytanie uznajemy wejście na dowolną stronę tematu, czy tylko zawierającą ów post?

oo na to nie zwrocilem uwagi, dzieki

  1. 4. Po co Ci w tabeli kolumna id z auto increment? Czy klucz unikatowy na (id_usera, id_posta) nie jest wystarczający? A może rozbić go na dwa klucze typu INDEX, po jednym dla każdej z wymienionej przeze mnie dwóch kolumn?


zawsze wprowadzam primary key, nigdy nie bawilem sie na indexach

----

w takim razie moglbys napisac jakie rozwiazania sugerujesz? bardzo chetnie ich wyslucham
dziekuje
thek
ad1) Limitowanie nieprzeczytanych to konieczność. Wiele kont jest porzucanych i chcąc nie chcąc musisz je zlimitować.

ad2) Nie o to mi chodziło. Chodzi mi o sytuację kiedy następuje dodanie do tabeli nieprzeczytanych kolejnych postów użytkownikom. Czy jest to robione w momencie napisania posta czy może dopiero w momencie zalogowania się użytkownika, albo dodane od czasu jego ostatniej akcji w serwisie. Innymi słowy czy masz coś w stylu:
- dodaj wszystkim userom tego posta jako nieprzeczytanego gdy jest dodawany do bazy (od razu dodaje wszystkim userom, co jest wygodne)
- dodaj konkretnemu userowi posty z data większą niż określona w momencie zalogowania (dodawanie konkretnemu userowi tylko raz na dłuższy czas),
- dodaj konkretnemu userowi posty z data większą niż czas jego ostatniej akcji w serwisie (dodawanie ewentualnych postów pomiędzy refreshami strony, bardzo aktualne dane )
Każde rozwiązanie ma swoje wady i zalety związane z obciążaniem systemu i rozpychaniem bazy.
Wersja 1: Dane są bardzo aktualne dla wszystkich, ale musisz napisać mechanizm kontrolujący limit postów. Poza tym powoduje przechowywanie nadmiaru danych zwłaszcza dla userów rzadko odwiedzających serwis. Oni niemal zawsze będą mieli limit wykorzystany.
Wersja 2: Posty są dodawane tylko raz w czasie całego pobytu - przy zalogowaniu, co zmniejsza obciążenie bazy, ale kosztem aktualności. User nie zobaczy nowych postów napisanych podczas jego pobytu w serwisie.
Wersja 3: To pewien kompromis wydajności z objętością bazy. Tabela nieprzeczytanych jest uzupełniana i sprawdzana przy każdym/co ileś requestów usera. Dzięki temu tylko w czasie bytności usera zachodzą operacje na bazie postów i są one w miarę aktualne. Obciążenie bazy jednak mocno może urosnąć, gdyż operacja sprawdzenia czy są nowe posty od ostatniego żądania, dodania ich i ewentualnego usunięcia wykraczających poza limit może być znacząca.

ad 3) Rozwiązanie ze stronami jest bardziej obciążające, ale eliminuje sytuację, gdy user wszedł tylko na pierwszą stronę, która nie zawiera nieprzeczytanego posta, a post uznano za przeczytany. Znów dylemat wydajność kontra dokładność. Tutaj więc bardziej osobiste preferencje i możliwości serwera się liczą, podobnie jak w poprzednim punkcie.

ad 4) Ale po co Ci primary key tak naprawdę, skoro nigdy nie używasz go? System jedynie przy wewnętrznych operacjach. Dla Ciebie najistotniejsze jest operowanie na id_użytkownika i id_posta. Tylko one mają znaczenie. Lepiej chyba je zaindeksować by zrobić:
  1. DELETE FROM nieczytane WHERE id_usera = X

By usunąć wszystkie nieczytane posty tego usera (opcja "Oznacz wszystkie jako przeczytane")
Czy też może
  1. DELETE FROM nieczytane WHERE id_posta IN ( X, Y, Z)

gdy usuwamy posty z przeczytanego tematu. Drugi przypadek to w zasadzie najlepiej pogodzić z JOINEM tabeli postów by wyłapać id tematu czytanego, ale to tylko moja sugestia. Zovbacz, że tylko tego koniecznie potrzebujesz. Dla wygody jeszcze możesz ewentualnie dodać id_tematu czy id_forum, by zredukować operacje JOINowania z odpowiednimi tabelami by wyszukać ilość postów nieprzeczytanych z określonego forum lub tematu. Tu jest pułapka jednak... Musisz uważać na opcję przenoszenia tematu do innego forum lub wydzielania postów do innego tematu.

Co do tylko tego tematu to widać, że nie szukałeś dobrze. Użyj w wyszukiwarce słów: nieprzeczytane, posty, oznaczanie i kilka innych w różnych kombinacjach, bo ten co znalazłeś to nie jedyny temat tutaj o tym problemie tyczący.
AndyPSV
Najbardziej optymalne i najlepsze rozwiazania wydaja mi sie byc takie, jesli jest jeszcze cos do poprawienia to poprosze o napisanie:

1. Limit postow: 100
2. Jest tak zrobione, ze przy zalogowaniu sprawdza ostatnia date zalogowania sie (robie strone na certyfikatach ssl, 256-bit wiec caly czas trzeba sie logowac) i na jej podstawie robi petle, gdzie dodaje wszystkie nieprzeczytane posty od najnowszych z limitem jak w punkcie 1.

3. Post jest zamarkowany jako przeczytany, jesli wejdzie sie na ostatnia strone (ostatnia strona moze byc pierwsza strona, glowna tematu). Jest to zrobione bez obciazania czegokolwiek - wystarczy sprawdzic ilosc stron i jesli user wejdzie na ostatnia to sie odhacza.
4.

  1. CREATE TABLE `chcur_ph_unread_pl` (
  2. `id_u` int(11) NOT NULL,
  3. `id_` int(11) NOT NULL,
  4. `id_f` int(11) NOT NULL,
  5. KEY `id_u` (`id_u`,`id_`)
  6. ) ENGINE=MyISAM DEFAULT CHARSET=latin2;


1 pole wiecej id_f <- mowi, do ktorego forum zostal przypisany post, eliminuje to sprawdzanie kazdego postu i zwieksza szybkosc (czyt. czy w danym forum sa nieprzeczytane posty).

Gwoli wyjasnienia: kiedy ktos doda post w TEMACIE to jest w tym ostatnim uaktalniania kolumna: "updated", po tej kolumnie wyswietlana jest lista tematow (wg najnowszych).


----

dorzuce jeszcze kod, moze komus sie przyda:

uaktualnianie bazy
  1. $q = q('SELECT id,id_ FROM `'.PRFX.'ph_topics'.LG.'` WHERE updated BETWEEN "'.$r['last_logged'].'" AND "'.DATETIME.'" ORDER BY updated DESC LIMIT 100'); if(n_r($q) > 0) while($_r = f($q)) {
  2. $q2 = q('SELECT id_u FROM `'.PRFX.'ph_unread'.LG.'` WHERE id_u = "'.$_r['id'].'" AND id_ = "'.$_r['id'].'" LIMIT 1');
  3. if(n_r($q2) == 0) q('INSERT INTO `'.PRFX.'ph_unread'.LG.'` (id_u,id_,id_f) VALUES ("'.$r['id'].'","'.$_r['id'].'","'.$_r['id_'].'")');
  4. }


tablea "updated" w temacie -> rodzaj: DATETIME

reszta, wiadomo
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.