Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Prywatne wiadomości jako wątki
Forum PHP.pl > Forum > Bazy danych
WebCM
Rozwiązanie jest znane z IPB i wielu innych serwisów.

Osoba A wysyła prywatną wiadomość #1 do B.
Osoba B odpisuje na wiadomość #1 i widzi ją na tej samej podstronie (#2 pod #1).
Osoba A widzi wątek #1 jako NOWY. Wchodzi do środka. Tam widzi wiadomości - #1 (swoją) i #2 od osoby B.
I tak dalej...

W skrócie: wiadomości są wyświetlane jako wątki - jak na forum.

Dotychczas skrypt wyświetlał wiadomości osobno. Pola w bazie danych:

+ ID - ID wiadomości
+ topic - tytuł
+ owner - właściciel wiadomości, zazwyczaj odbiorca (ten, którego konto obciąża)
+ usr - odbiorca lub nadawca (w zależności od statusu)
+ st - status (1 - nowa, 2 - przeczytana, 3 - szkic, 4 - kopia)
+ date - data wysłania
+ txt - treść

W IPB prawdopodobnie istnieje dodatkowa tabela dla wątków. Ja próbuję zrobić to bez tworzenia dodatkowej tabeli. Założenie: jak najmniejsza ilość pól.

Dodałem nowe pole - th - numer wątku, czyli ID wiadomości nadrzędnej.

Warunek do listy wiadomości w folderze ODEBRANE (dla użytkownika o ID=1):
  1. WHERE p.st<3 AND p.th=0 AND p.owner=1

Zakładam, że wiadomości nadrzędne mają wartość pola th równą 0.

Zapytanie wyświetlające konkretny wątek o ID=5 dla użytkownika o ID=1:
  1. SELECT
  2. p.*, u.login, u.photo
  3. FROM
  4. pms p
  5. LEFT JOIN
  6. users u
  7. ON
  8. p.usr = u.ID
  9. WHERE
  10. p.owner=1 AND (p.ID=5 OR p.th=5)
  11. ORDER BY
  12. p.th, p.date

Wszystko wyświetla się dobrze, ale przejdźmy teraz do wysyłania wiadomości:

Wg moich przemyśleń odbiorca musi otrzymać osobną kopię wiadomości. Może to jest błędne założenie?

Już tłumaczę, o co chodzi. Zarówno odbiorca i nadawca widzą całą swoją korespondencję - wiadomości wysłane i odebrane. Pewnego dnia jedna ze stron chce wyczyścić swoją skrzynkę. Mając tylko 1 kopię wiadomości, będzie to niemożliwe, gdyż wiadomości od niej straci druga osoba (a ona chciała sobie je zatrzymać dla siebie).

A więc nadawca przymusowo otrzymuje kopię listu, który wysłał. Wtedy do konfliktu nie dojdzie smile.gif

Znacie inne, lepsze rozwiązania, aby zaoszczędzić miejsce?

Zaczynają się schody

Jak pamiętamy, wiadomości nadrzędne muszą mieć th=0.

Wiadomość #1 u osoby B ma inne ID niż u osoby A (bo to oddzielne kopie).

Osoba B chce odpisać osobie A. Tylko jest problem. Nie znamy ID wątku u użytkownika A. Gdybyśmy zapisali go w polu "th", osoba B nie zobaczyłaby wątku nadrzędnego na liście w folderze "Odebrane". A przecież odpowiedź ma pojawić się u A pod jego wiadomością, którą wysłał do B.

Jakie zatem proponujecie rozwiązanie tego problemu?

Mogę pokombinować z polem st (status) - tak, aby w polu th mógł znaleźć się ID wątku. Prostszym wyjściem jest stworzenie nowej kolumny w tabeli (też jest kilka opcji). Może służyć do połączenia z innymi wiadomościami lub określenia, czy jest nadrzędną wiadomością...

Jaka jest Wasza wizja?

PS. Czy w ten sposób nie złamię patentu na wyświetlanie wiadomości jako wątków? Czy dotyczy on tylko telefonów komórkowych i SMS-ów?
erix
Cytat
Ja próbuję zrobić to bez tworzenia dodatkowej tabeli. Założenie: jak najmniejsza ilość pól.

I to jest błąd. Dlaczego? Przy większym obciążeniu może dać nieźle popalić bazie. Problem taki sam, jak przy drzewkach, chyba że coś źle zrozumiałem.

Cytat
Znacie inne, lepsze rozwiązania, aby zaoszczędzić miejsce?

Powiem to tak - lepiej zmarnować więcej miejsca, niż zbędnie komplikować strukturę: KISS
WebCM
Nie, tu nie chodzi o drzewka, a dodatkowa tabela nic nie rozwiąże.

Chcę, aby powiązane ze sobą prywatne wiadomości były wyświetlane jak posty w wątku na forum - podobnie jak w nowym IPB. Bez dodatkowych poziomów zagnieżdżenia - po prostu w płaskim widoku. User A pisze do B, potem B odpisuje A (opcja Odpowiedz), z kolei A odpisuje B... Jednak wszystkie wiadomości są wyświetlane na 1 podstronie - czyli powstaje wątek.

Aby nie tworzyć 2 kopii tej samej wiadomości w tabeli, można stworzyć dodatkowe pole kto_usunal (DEFAULT 0).

Kiedy obie strony usuną wiadomość, zostanie fizyczne wydalona z bazy.

Aby wyświetlić wątek o ID=1 dla użytkownika UID=5, wystarczy warunek:
  1. WHERE (p.owner = 5 OR p.usr = 5) AND (p.ID = 1 OR p.th = 1) AND p.kto_usunal != 5
Aby wyświetlić listę wiadomości, potrzeba:
  1. WHERE p.st < 3 AND p.th = 0 AND p.kto_usunal != 5 AND (p.owner = 5 OR p.usr = 5)
Indeksy na polach: ID, th, owner, usr. Czy to jest dobre wyjście?

Co się bardziej opłaca? Tworzyć 2 kopie rekordów, czy współdzielić 1 kopię (jak powyżej)? Zależy mi głównie na wydajności.

Taki model nie sprawdzi się, gdy w dyskusji biorą 3 osoby lub więcej, ale z tym jest znacznie więcej roboty i nie wprowadzam.
Riklaunim
Pierwsza wiadomość zostaje rodzicem wszystkich innych wysłanych z widoku wyświetlającą ją (tj. na stronie gdzie się wyświetla link typu "odpowiedz" przekazują parametr o rodzicu). Przy listowaniu wiadomości możesz stworzyć wątek po tej wartości. Zupełnie nowa wiadomość wysłana z innego miejsca nie ma rodzica i może stworzyć własny wątek jeżeli konwersacja będzie kontynuowana.
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.