Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [PHP]System wiadomości
Forum PHP.pl > Forum > Przedszkole
user767
Jak rozwiązać przesyłanie wiadomości między użytkownikami, jeśli już pisałem w php i mysql takie coś, tylko skończyłem w ślepym zaułku, gdzie czekało na mnie co zrobić, gdy użytkownik usunie wiadomość, to drugi też już jej nie ma. Wiadomości zapisywane w bazie danych, w tabeli wiadomości z id użytkownika wysyłającego i odbierającego i innymi polami. Czy jedyne rozwiązanie, to dla każdego użytkownika utworzyć tabelę wiadomości ? Jak wykonać taki system wiadomości między użykownikami.
IceManSpy
Każdy użytkownik musi mieć unikalne ID, które zapisujesz w bazie.
Nawet tutaj na forum tak jest:
http://forum.php.pl/IceManSpy_m50591.html
http://forum.php.pl/user767_m51703.html

To są jakieś numery,. które nas identyfikują w bazie. A w bazie trzymasz informacje od kogo i do kogo jest wiadomość.
user767
Dobra, a co z usuwaniem wiadomości ? Usunę to wysyłający nie zobaczy w wysłanych. A jak napiszę niewidoczność dla usuniętych to i tak zostaną na serwerze.
nekomata
Ja bym to rozwiązał tak :
Załóżmy ze masz 3 kolumnę z bazie (Od, Do, Wiadomość) , wiadomość zostaje wysłana przez użytkownika o ID 666 do użytkownika o ID 997 ,
wiec nasza tabela wygląda tak :

Od | Do | Wiadomosc
----+---+----------------
666|997| Siema zenek

Teraz użytkownik o ID 666 chce usunąć wiadomość z listy wysłanych (jednak chce zęby wiadomość doszła bo to tylko archiwum przecież) i tutaj pojawia się mój pomysl
zamiast usuwać wpisu zastosowałbym UPDATE na danej wiadomość zamieniając ID na np. 0 (konto które stworzyłeś samemu wcześniej albo możesz NULL walnąć)
teraz tylko wystarczy zastosować to samo w druga stronę(jak 997 usunie u siebie a 666 nie usunął) i dodać warunek ze jeśli Od i Do wynoszą 0 , NULL czy co tam wstawiłeś wpis jest usuwany.

EDIT : Chwile po napisaniu tego posta dotarło do mnie ze powyższa metoda będzie mieć jedna wadę, mianowicie jeśli 666 usunie wiadomość u siebie , wiadomość u użytkownika 997 nie będzie miała nadawcy, mógłbyś dodać dwie kolumny typu tinyint np.UsunieteAutor,UsunieteOdbiorca , i jeśli któraś z nich zawiera np. 1 to nie wyświetlać dla danej osoby jeśli NULL to wyświetlać , jeśli obydwa usunięte(znaczy 1 był usunięty a ty dodajesz drugi w tym momencie usuwa cala linie).
wNogachSpisz
Cytat(IceManSpy @ 24.02.2011, 23:42:49 ) *
Każdy użytkownik musi mieć unikalne ID, które zapisujesz w bazie.


Nie musi.
Jeśli w tabeli istnieje wartość za pomocą której można unikatowo zidentyfikować użytkownika, np. jego login lub data rejestracji, lub kombinacja dwóch, to po jaką cholere dopychać jeszcze uniqId.
To jest jeden z najczęstrzyszch błędów popełnianych przez "projektantów" baz danych - daja auto-icrement dosłownie wszędzie..
Pole auto-icrement dodajesz kiedy nie ma możliwości unikatowego zidentyfikowania wiersza bazując na innych kolumnach, a takiej identyfikacji wymaga projekt.

Oczywiście, jeśli projekt przewiduje takie coś jak prywatne wiadomości, to ID wydaje się być najlepszym rozwiązaniem, ponieważ zajmuje ono najmniej miejsca, a jeśli ma być często powtarzane w tabeli odpowiedzialnej za PW, to w celu uniknięcia nadmiarowości danych, będzie najlepszym rozwiązaniem.
Należy się jednak bardzo mocno zastanowić, czy np. kombinacja końcówki czasu rejestracji i końcówki numeru IP nie będzie lepsza.
Lepsze w sensie umozliwiające unikatową identyfikację, nie wymagające tworzenia dodatkowej kolumny w tabeli, nie zajmujące zbyt dużo miejsca.
Podejmowanie takich decyzji mozna przyrównać do przeciągania liny.

Osobiście mam w zwyczaju nie usuwać wierszy kiedy wiadomość zostaje usunięta przez użytkownika, zamiast tego nadaje właściwy status.

Ja bym to zrobił tak:

Kod
Od | Do | Wiadomosc   | Status
---+----+-------------+------
666|997 | Siema zenek | 1


Status 1: wiadomość oczekująca na przeczytanie
Status 2: wiadomość przeczytana
Status 3: wiadomość usunięta
Status 4: ....
Status 5: wiadomość systemowa
Status 6: ...
Wilu88
Cytat(wNogachSpisz @ 25.02.2011, 09:18:45 ) *
Nie musi.
Jeśli w tabeli istnieje wartość za pomocą której można unikatowo zidentyfikować użytkownika, np. jego login lub data rejestracji, lub kombinacja dwóch, to po jaką cholere dopychać jeszcze uniqId.
To jest jeden z najczęstrzyszch błędów popełnianych przez "projektantów" baz danych - daja auto-icrement dosłownie wszędzie..
Pole auto-icrement dodajesz kiedy nie ma możliwości unikatowego zidentyfikowania wiersza bazując na innych kolumnach, a takiej identyfikacji wymaga projekt.

Oczywiście, jeśli projekt przewiduje takie coś jak prywatne wiadomości, to ID wydaje się być najlepszym rozwiązaniem, ponieważ zajmuje ono najmniej miejsca, a jeśli ma być często powtarzane w tabeli odpowiedzialnej za PW, to w celu uniknięcia nadmiarowości danych, będzie najlepszym rozwiązaniem.
Należy się jednak bardzo mocno zastanowić, czy np. kombinacja końcówki czasu rejestracji i końcówki numeru IP nie będzie lepsza.
Lepsze w sensie umozliwiające unikatową identyfikację, nie wymagające tworzenia dodatkowej kolumny w tabeli, nie zajmujące zbyt dużo miejsca.
Podejmowanie takich decyzji mozna przyrównać do przeciągania liny.

Osobiście mam w zwyczaju nie usuwać wierszy kiedy wiadomość zostaje usunięta przez użytkownika, zamiast tego nadaje właściwy status.

Ja bym to zrobił tak:

Kod
Od | Do | Wiadomosc   | Status
---+----+-------------+------
666|997 | Siema zenek | 1


Status 1: wiadomość oczekująca na przeczytanie
Status 2: wiadomość przeczytana
Status 3: wiadomość usunięta
Status 4: ....
Status 5: wiadomość systemowa
Status 6: ...


No tak ale co w przypadku gdy tylko nadawca usunął wiadomość ze swojej skrzynki a odbiorca nadal go ma? Wiadomość przyjmie wartość statusu 3 i będzie niewidoczna dla obu użytkowników. Ja bym to rozwiązał na dwa statusy status dla nadawcy i odbiorcy. Nie obciąży to w żadnym stopniu strony a łatwiej będzie operować na wartościach.

Tak samo jeśli tworzysz wiadomość systemową czyli pole status przyjmuje wartość 5 to wyklucza to sprawdzeni czy przeczytana czy nie? I tym samym nie można jej usunąć?
wNogachSpisz
Cytat(Wilu88 @ 25.02.2011, 09:35:47 ) *
No tak ale co w przypadku gdy tylko nadawca usunął wiadomość ze swojej skrzynki a odbiorca nadal go ma? Wiadomość przyjmie wartość statusu 3 i będzie niewidoczna dla obu użytkowników. Ja bym to rozwiązał na dwa statusy status dla nadawcy i odbiorcy.


No i błąd.

status 3: wiadomość usunięta przez nadawce
status 4: wiadomośc usunięta przez odbiorce
status 5: wiadomość usunięta zarówno przez odbiorce jak i nadawce.

Proste.
I obyło się bez dodatkowej kolumny.

Cytat(Wilu88 @ 25.02.2011, 09:35:47 ) *
Nie obciąży to w żadnym stopniu strony a łatwiej będzie operować na wartościach.


Obciązy w bardzo konkretny sposób:
Tabela będzie większa, jaj przeszukiwanie zajmie więcej czasu,
bezpośrednio spowoduje to spadek wydajności systemu.
Wilu88
Cytat(wNogachSpisz @ 25.02.2011, 09:40:19 ) *
No i błąd.

status 3: wiadomość usunięta przez nadawce
status 4: wiadomośc usunięta przez odbiorce
status 5: wiadomość usunięta zarówno przez odbiorce jak i nadawce.

Proste.
I obyło się bez dodatkowej kolumny.


Ale dalej mieszasz np. ze sprawdzeniem czy przeczytana? Nie możesz tego wrzucić do tego samego pola co sprawdzanie czy jest usunięta czy nie? No bo co jeśli jest przeczytana czyli przyjmuje wartość 2, nadawca ja usunie wtedy przyjmuje wartość 3. I jak teraz sprawdzisz czy odbiorca ją przeczytał?
wNogachSpisz
Cytat(Wilu88 @ 25.02.2011, 09:43:39 ) *
Ale dalej mieszasz np. ze sprawdzeniem czy przeczytana? Nie możesz tego wrzucić do tego samego pola co sprawdzanie czy jest usunięta czy nie? No bo co jeśli jest przeczytana czyli przyjmuje wartość 2, nadawca ja usunie wtedy przyjmuje wartość 3. I jak teraz sprawdzisz czy odbiorca ją przeczytał?


Udajesz prawda?

Status 3: Wiadomość przeczytana, usunięta przez odbiorce
Status 4: Wiadomość przeczytana, usunięta przez nadawce
Status 5: Wiadomość nieprzeczytania, usunięta przez odbiorce
Status 6: ...
Status 7:
Status 8:
Status 9:
Status 10:
Status 11:

Nawet jeśli dojdziesz ze statusami do 10.000, nadal będzie się bardziej opłacać niż kolejna kolumna..

------------------------------------------------------------------------------------------

Możesz też dać coś w stylu liczby dwócyfrowej, gdzie pierwsze cyfra to status dla nadawcy, a druga status dla obiorcy np:

Status: 31: usunięta przez odbiorce, nieprzeczytana
Status: 32: usunięta przez odbiorce, przeczytana
Status: 41: usunięta przez odbiorce, nieprzeczytana
Status: 42: usunięta przez odbiorce, przeczytana

Nadal lepsze rozwiązanie niż dodatkowa kolumna..
Wilu88
Cytat(wNogachSpisz @ 25.02.2011, 09:46:18 ) *
Udajesz prawda?

Status 3: Wiadomość przeczytana, usunięta przez odbiorce
Status 4: Wiadomość przeczytana, usunięta przez nadawce
Status 5: Wiadomość nieprzeczytania, usunięta przez odbiorce
Status 6: ...
Status 7:
Status 8:
Status 9:
Status 10:
Status 11:

Nawet jeśli dojdziesz ze statusami do 10.000, nadal będzie się bardziej opłacać niż kolejna kolumna..


No właśnie nie wydaje mi się aby sprawdzanie za pomocą case 1000 wartości było bardziej wydajne niż dodanie kolejnego pola z jedno znakowym charem. A tutaj musisz przewidzieć wszystkie możliwe kombinacje, a dodanie np kolejnego statusu sprawia że na nowo musisz wszystkie statusy przebudować.

No ale nigdy tego nie robiłem mam dopiero w planach, także może masz rację .Jak zajmę się systemem wiadomości to przetestuje oba sposoby.
wNogachSpisz
Cytat(Wilu88 @ 25.02.2011, 09:49:52 ) *
No właśnie nie wydaje mi się aby sprawdzanie za pomocą case 1000 wartości było bardziej wydajne niż dodanie kolejnego pola z jedno znakowym charem. A tutaj musisz przewidzieć wszystkie możliwe kombinacje, a dodanie np kolejnego statusu sprawia że na nowo musisz wszystkie statusy przebudować.


Nie musisz robić żadnego case.
Wystarczy że dodasz kolejną table w bazie danych, gdzie będziesz miał te wszystkie statusy przetłumaczone na taką formę jaka Ci odpowiada.
Potem wykonujesz odpowiednie zapytanie i baza zwraca nawet 10 kolumn ze statusami dla odbiorcy, nadawcy, kogokolwiek innego.
Jeżeli uznasz że własnie taki format odpowiedzi Ci odpowiada, możesz tak zrobić..

Jeszcze raz powtórze, liczy się wydajność, nie wygoda..
Gość
Tak pokazywałem
  1. $this -> query="SELECT * FROM osoby WHERE id='$id_od_kogo'";


Odebrane nowe
  1. $query="SELECT * FROM wiadomosci left join wiadomosci_osoby on wiadomosci.id=wiadomosci_osoby.id_wiadomosci


Tak zaznaczałem jako przeczytane
  1. $typ = $r['status'];
  2. $typ_get = "0"; // 0, czyli przeczytana
  3.  
  4. echo "<table border=\"0\">";
  5. echo "<tr><td width=\"350\"><strong>{$r['temat']}</strong>
  6. <br />"; echo $dzien. " ". $mies. " ". $rok. " r. </td> <td width=\"200\">
  7. <a href=\"mail_zapisz.php?od_kogo=$id_od_kogo&typ_get=$typ_get&typ_baza=$typ&id={$r['id_wiadomosci']}\">[ Zobacz ]</a>


Tak pokazywałem przeczytane
  1. $query="SELECT * FROM wiadomosci left join wiadomosci_osoby on wiadomosci.id=wiadomosci_osoby.id_wiadomosci
  2. WHERE (id_do_kogo='$id' AND status='0') AND (typ!='$id_os') ";


Pokazywałem wysłane
  1. $query="SELECT * FROM wiadomosci left join wiadomosci_osoby on wiadomosci.id=wiadomosci_osoby.id_wiadomosci
  2. WHERE (id_od_kogo='$id' AND typ!='$id_os')";


Ile nowych
  1. $query="SELECT * FROM wiadomosci_osoby WHERE (id_do_kogo=$id && status=1) && typ!=$id ";
  2. $wynik2 = mysql_query($query);
  3. $ile_nowych = mysql_num_rows($wynik2);
  4.  
  5. echo "<center>Masz <u>" . $ile_nowych . "</u> nieprzeczytanych wiadomości.<br />";


Ile razem
  1. $query="SELECT * FROM wiadomosci_osoby WHERE (id_do_kogo=$id AND typ!=$id)";
  2.  
  3. $wynik=mysql_query($query);
  4. $ile_razem = mysql_num_rows($wynik);
  5.  
  6. echo "Razem <u>" . $ile_razem . "</u> wszystkich wiadomości.<br /><br />";


Czy jest jakaś opcja, dzięki której gdyby wszystkie status wiadomości przyjął wartość usunięte przez jednego i drugiego użytkownika, usunąć oraz w jakim czasie taką komendę wstawić. Bo ja znam tylko trunkable to czyszczenia tabel, np. tymczasowej pomocniczej dla sesji.
nekomata
Cytat(Gość-)
Czy jest jakaś opcja, dzięki której gdyby wszystkie status wiadomości przyjął wartość usunięte przez jednego i drugiego użytkownika, usunąć oraz w jakim czasie taką komendę wstawić. Bo ja znam tylko trunkable to czyszczenia tabel, np. tymczasowej pomocniczej dla sesji.

Sprawdzać przy zmianie statusu na usunięty??np. Autor usuwa wiadomość i przed tym daj zapytanie czy odbiorca usunął wiadomość również , jeśli obydwoje usunęli : dajesz DELETE w zapytaniu .
thek
Pytanie... A po co mi sprawdzać, czy użytkownik przed wywaleniem czytał wiadomość? Usunął ją to usunął - nieważne co zrobił wcześniej. Chcesz zrobić historię wiadomości? To bez sensu. Jeśli już tak bardzo Ci zależy, to posłuż się maskami:
00000 - 1 cyfra - zapisanie przez nadawcę, 2 cyfra - usunięcie przez nadawcę, 3 cyfra odczytanie przez odbiorcę, 4 cyfra - zapisanie przez odbiorcę, 5 cyfra - usunięcie przez odbiorcę
Tam gdzie prawda ustaw 1, jeśli false to niech jest 0. Gdy 2 i 5 cyfra są na 1 to usuwaj wiadomość. Jeśli tylko jedna z nich jest na false to jej nadawcy lub odbiorcy nie pokazuj i tyle. Zamiast masek możesz użyć czegokolwiek, ale mechanizm jest identyczny.
wNogachSpisz
Cytat(thek @ 25.02.2011, 16:00:07 ) *
Jeśli już tak bardzo Ci zależy, to posłuż się maskami:


Maska, brakowało mi terminu "maska" w moich powyższych wywodach ;p
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.