Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [MSSQL][PHP]Forum nieprzeczytane tematy i posty
Forum PHP.pl > Forum > Przedszkole
ZuyPan
Witam.
Od dawna męczy mnie to zagadnienie i jakoś nie potrafię z nim sobie poradzić... Jak rozwiązać problem nowych (nieprzeczytanych) postów i tematów? dla użytkowników?
john_doe
ja bym dołozył kolumnę np. post_status. I do niej dodawał jedynkę kiedy zostanie wyświetlony POST. Jeśli w tej kolumnie jest 0 wtedy wyświetlasz tytuł posta wyboldowany. ot taki sobie pomysł na szybko.
kda
tyle że jezeli jeden user otworzy post to status się zmieni na 1 i w tedy wszyscy będą widzieli dany post jako przeczytany a kolega chce dla kazdego odrębnie , może zrobić to na zasadzie ciasteczek ?
gothye
nowe posty oznaczasz te które powstały po dacie ostatniego logowania użytkownika

a post nie przeczytane oznaczasz wszystkie ostatnie np 100 postów których id nie ma w ciasteczkach użytkownika 

ZuyPan
a co jeśli użytkownik usuwa ciasteczka bądź nie przyjmuje ich wcale? Co powiecie na unikatowy plik tekstowy dla każdego użytkownika w którym zapisywane by były takie tematy i posty?
gothye
forum phpbb zapisuje dane (id,value itp) sesji w SQL ,więc warto przyjżeć sie temu szerzej winksmiley.jpg
thek
Moim zdaniem najprostsze rozwiązanie... Pierwsze zalogowanie usera to stworzenie mu X rekordów z najnowszymi postami. Potem musisz tę tabelę kontrolować. Wejście na dany temat to usunięcie postów z tego tematu jako "przeczytanych". Problemem jest wyłapywanie postów pojawiających się pomiędzy akcjami usera. Musisz bowiem kontrolować czasy tych akcji i na bieżąco korygować wszystko. Dlatego w sesji i/lub danych usera musisz te informacje przechowywać by móc na nich opierać swoje działania. Przykładowo user sobie coś robi na stronie, ale Ty musisz wiedzieć kiedy ostatnio robił coś na forum, bo tylko taka dana Cię interesuje. Jeśli wszedł na forum... Zapisz ten czas. Gdy przejdzie na inna stronę forum -> dopisz posty powstałe od czasu ostatniej aktywności na forum do tej jego "tabeli" i zapisz czas kiedy to zrobiłeś w jego danych. On forum czyta to odejmujesz przeczytane posty ale jednocześnie sprawdzasz czy nie ma nic nowego.
Sprawa więc wygląda tak, że przy każdym przejściu WEWNĄTRZ struktury forum pobierasz wszystkie posty od momentu ostatniej aktywności na forum, a czasem aktualnym i dokładasz je do tabelki, aktualizujesz zaraz po tym sprawdzeniu czas ostatniej bytności na czas aktualny. Wyjście z forum nie zmienia nic, ponieważ masz tabelę nieprzeczytanych postów i czas ostatniej aktywności forumowej. Wejście na dowolna stronę forum powoduje sprawdzenie czasu i dopisanie ewentualnych nowych postów do tabeli oraz aktualizację tego czasu. Jesteś wtedy na bieżąco z postami. Jeszcze tylko musisz kontrolować liczbę tych postów by w razie przekroczenia X usuwać najstarsze.
pablo89pl
Najprościej to robisz sobei w bazie SQL tabele viewed z polami: id, user_id, post_id

I sprawdzasz czy dla usera z id X, istnieje rekord dla postu z id Y
Jak tak to znaczy że juz ogladal tego posta

Tyle ze takie coś natworzy Ci miliony rekordów ;-)
Było swego czasu tu na forum kilka opinii jak zrobić cos tego typu na przykładzie NK itd... Poszukaj

Pozdrawiam
gothye
po co milion rekordów ,wystarczy tablice z id postów potraktować serialize i już winksmiley.jpg
thek
Dopóki działasz jedynie na danych liczbowych (a tak jest w tym wypadku) to całość jest bardzo szybka i nawet grubo ponad milion rekordów to nie są dane jakie tabeli sprawią problem. Zwłaszcza, że masz przecież indeksy. Poza tym chyba nie bierzesz pod uwagę, że masz każdemu userowi przypisany limit, po którym starsze posty są usuwane z owej tabeli. licząc, że ustawimy limit na 200 to przy normalnych forach user musiałby kilka dni nie być aktywny. A razy liczba 10k userów (wątpię czy tyle Twoje forum osiągnie) to "tylko" 2 miliony rekordów maksymalnie. Zaś operacje typu edycja postów nieprzeczytanych to nie będzie odczyt rekordu, unserialize, operacje na postach, serialize i tak bardzo często w ciągu minuty. To mniej optymalne niż kilka prostych zapytań do bazy, które na dodatek przy sprawdzeniu mogą Ci wykazać brak zmian do przeprowadzenia w następnych krokach. A serialize i unserialize musisz za każdym razem niemal wykonywać, co dość szybko przestanie być wydajne przy skakaniu między bazą a php. jeśli zaś wszystko ładnie przemyślisz, to może się okazać, że struktura tabel pozwala z całości stworzyć procedurę, dla której jedynym niezbędnym parametrem będzie id użytkownika, bo resztę operacji wykona sama. Sama sprawdzi ostatnią datę, sama porówna do czasu obecnego i sama przetworzy tabelę usuwając zbyt stare, wstawiając nowe i wyrzucając nadmiarowe. Tak więc czy lepsze będzie skakanie czy zdanie się na procedury?
ZuyPan
Cytat(thek @ 11.02.2010, 18:42:16 ) *
A razy liczba 10k userów (wątpię czy tyle Twoje forum osiągnie)

dzięki za wiarę tongue.gif

Cytat(thek @ 11.02.2010, 16:26:18 ) *
Pierwsze zalogowanie usera to stworzenie mu X rekordów z najnowszymi postami. Potem musisz tę tabelę kontrolować. Wejście na dany temat to usunięcie postów z tego tematu jako "przeczytanych". Problemem jest wyłapywanie postów pojawiających się pomiędzy akcjami usera. Musisz bowiem kontrolować czasy tych akcji i na bieżąco korygować wszystko. Dlatego w sesji i/lub danych usera musisz te informacje przechowywać by móc na nich opierać swoje działania. Przykładowo user sobie coś robi na stronie, ale Ty musisz wiedzieć kiedy ostatnio robił coś na forum, bo tylko taka dana Cię interesuje. Jeśli wszedł na forum... Zapisz ten czas. Gdy przejdzie na inna stronę forum -> dopisz posty powstałe od czasu ostatniej aktywności na forum do tej jego "tabeli" i zapisz czas kiedy to zrobiłeś w jego danych. On forum czyta to odejmujesz przeczytane posty ale jednocześnie sprawdzasz czy nie ma nic nowego.
Sprawa więc wygląda tak, że przy każdym przejściu WEWNĄTRZ struktury forum pobierasz wszystkie posty od momentu ostatniej aktywności na forum, a czasem aktualnym i dokładasz je do tabelki, aktualizujesz zaraz po tym sprawdzeniu czas ostatniej bytności na czas aktualny. Wyjście z forum nie zmienia nic, ponieważ masz tabelę nieprzeczytanych postów i czas ostatniej aktywności forumowej. Wejście na dowolna stronę forum powoduje sprawdzenie czasu i dopisanie ewentualnych nowych postów do tabeli oraz aktualizację tego czasu. Jesteś wtedy na bieżąco z postami. Jeszcze tylko musisz kontrolować liczbę tych postów by w razie przekroczenia X usuwać najstarsze.


troszkę to skomplikowane i nie jestem pewien, czy wszystko dokładnie rozumie...

Cytat(pablo89pl @ 11.02.2010, 16:28:30 ) *
Najprościej to robisz sobei w bazie SQL tabele viewed z polami: id, user_id, post_id

I sprawdzasz czy dla usera z id X, istnieje rekord dla postu z id Y
Jak tak to znaczy że juz ogladal tego posta


Ten sposób wydaje mi się najprostszy jednak nie wiem czy wybrać ten czy proponowany przez Thek'a...

Thek jeśli mógłbyś troszkę bardziej łopatologicznie? biggrin.gif

Pozdrawiam i dziękuję za zainteresowanie smile.gif
thek
To lecimy...
Gdy user się loguje sprawdzasz kiedy był ostatnio na forum (akcje typu dodaj post, czytanie tematu, przechodzenie między podforami itp... cokolwiek w strukturze forum). Jeśli nie było nigdy walisz mu ideki X najnowszych postów. Jeśli był to pobierasz wszystkie posty od tej daty do aktualnej z LIMIT X i ustawiasz mu znacznik czasu akcji na forum na aktualny. Te id wrzucasz do jakiejś tabeli, gdzie kluczem jest id usera, a dodatkowo masz mieć tam id posta ( tematu czy forum opcjonalnie jeśli chcesz zmniejszyć nieco późniejsze joiny ). W ten sposób stworzysz sumę starych i nowych nieprzeczytanych. Jeśli ta suma przekroczy X, usuwasz najstarsze powyżej limitu. Jako że posty mają strukturę zazwyczaj z id postu jako auto_increment, to wystarczy że sprawdzisz jaki id ma post o offsecie X i wszystkie dla danego usera z tej tabeli o id mniejszym wyrzucasz. W ten sposób robisz przy każdej akcji wewnątrz struktury forum. Niby generuje to ruch, ale zauważ, że podczas sprawdzania ile postów jest nowych od "starej" daty można w przypadku braku odpuścić dalszą część, przez co optymalizujemy szybkość eliminując zbędne operacje.

EDIT: Przykład...
User loguje się po raz pierwszy, więc w znaczniku czasu ma zapewne NULL lub 0, czyli przy wejściu na forum do tablicy wrzuca mu 150 (limit) wersów z jego id, id_post dla najwyższych postów w tabeli postów i id topicu oraz ustawia znacznik czasu dla akcji forumowych na $teraz = now(). Zaraz potem user przechodzi na stronę z najnowszymi postami, tu procedura wygląda nieco inaczej. Sprawdzenie znacznika pokaże czas z momentu wejścia na forum, a więc szuka posty z czasem powstania większym niż $teraz. Może coś być, ale nie musi. Jeśli jest, dopisze nowe posty do tej tabeli i wykona sprawdzenie czy jest ich więcej niż 150. Jeśli tak to sprawdzi id_post dla tego na miejscu 150 i wszystkie wpisy z tej tabeli o id_usera zgodnym oraz id_post mniejszym niż ten na 150 miejscu są usuwane z niej. Tak czy inaczej, niezależnie od wyniku jakichkolwiek operacji, aktualizujesz $teraz znów na aktualną. Wejście na dany temat oznacza usunięcie postów z tabeli nieprzeczytanych. Zauważ, że masz w kilku miescach sprawdzenie, które w zależności od wyniku pokazuje jakie operacje musisz wykonać lub możesz olać. Są to:
1. Sprawdzenie ilości postów od czasu wskazywanego przez $teraz -> to decyduje czy dodasz nowe rekordy do tabeli nieprzeczytanych postów
2. Sprawdzenie czy nie przekroczono limitu 150 postów -> tu reakcją jest obcięcie nadmiarowych powyżej limitu.

Adnotacja 1: Operacje usuwania z tabeli nieprzeczytanych robimy PRZED operacją sprawdzania. Czemu? Bo wejście na temat gdy mamy tylko jeden nieprzeczytany post w tym akurat temacie usunie go i porównanie ilości wpisów w tej tabeli zwróci 0 co optymalizuje całość.
Adnotacja 2: Usuwanie postów z tematu można rozbić na 2 przypadki. Albo usuwamy posty z tabeli poprzez ogólnie odwiedzenie tematu z tym postem (szybsze i prostsze w implementacji), albo jeśli temat jest długi to dodatkowo kontrolujemy, czy post mieści się na czytanej podstronie i od tego uzależniamy czy uznajemy post za przeczytany lub nie. Trochę więcej kodu sprawdzającego przed usunięciem w 2 przypadku, bo polegającego na sprawdzeniu wartości pierwszego i ostatniego id dla podstrony i porównanie z id w tabeli nieprzeczytanych dla danego tematu (stąd sugerowałem od razu zapisać też id tematu do tej tabeli).

I najważniejsze. To sa moje własne przemyślenia jako webmastera i informatyka. NIE WIEM jak fora i ich skrypty problem rozwiązują, bo nie patrzyłem w żaden kod od jakiegokolwiek nigdy. Ale jak dla mnie to jeden z sensowniejszych i logiczniejszych, a zarazem prostych.

EDIT2: Dobrze, że w sumie podniosłeś temat, bo mi to przyspieszyło myślenie o tym jak rowiązać ów problem pisząc własny system tego typu winksmiley.jpg Może nie jest on optymalny, ale z tego coe wiem wiele for ma problemy z wydajnością jeśli stosuje system zapamiętywania nieprzeczytanych. Choć to i tak nic w porównaniu do "żarcia zasobów" bajerów w stylu shoutboxa, które limity potrafią osiągnąć błyskawicznie.
ZuyPan
Dziękuję za wytłumaczenie smile.gif Fajny pomysł, szkoda tylko, że jest to ograniczenie dotyczące nieprzeczytanych postów... Gdyby poszło po mojej myśli i portal (a co za tym idzie forum) stał się naprawdę popularny to niestety trzeba by było zwiększać to ograniczenie a co za tym idzie coraz bardziej "zmulać" mysql... Tak czy inaczej dziękuję smile.gif Prawdopodobnie pokombinuje z podanym przez Ciebie pomysłem.
thek
Jeśli nie miałeś okazji, to powiem, że każde forum ma takie ograniczenie phpbb gdzieś około 500 bo miałem już "szansę" napotkać na pewnym forum smile.gif Poza tym limit ten możesz zmieniać dynamicznie, w zależności od "stażu". Nowi userzy będą go mieli nisko, bo i tak zazwyczaj spamują na potęgę winksmiley.jpg Jeśli im ileś postów "zginie" z widoku, tym lepiej dla wydajności.
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.