konto usunięte

Temat: Prywatne wiadomości w portalu. Jak zaprojektować?

Cześć,

Właśnie stoję przed problemem, który z początku wydawał się prostrzy. Musze do portalu, który tworzę storzyć wysłyanie wiadomości między użytkownikami. Wiadomości mają mieć opcję odpowiedzenia, czyli formowania się w wątki.

Jak zaprojektować to od strony bazy danych, by było w miare optymalnie, by pobrać cały wątek, w którym się wypowiedziałem itp. Myślałem o zastosowaniu drzewa depesza, ale ono nie rozwiązuje wszystkich problemów no i wymaga napisania kilku procedur w bazie danych.

Oto pierwsza myśl, która ma wiele wad.

messages:
_attributes: { phpName: Message }
id: ~
replay_id: { type: integer, foreignTable: messages, foreignReference: id, required: false, onDelete: cascade }
title: { type: varchar(50), required: true }
content: { type: longvarchar, required: true }
sender: { type: integer, foreignTable: sf_guard_user, required: true, foreignReference: id, onDelete: cascade }
reciever: { type: integer, foreignTable: sf_guard_user, required: true, foreignReference: id, onDelete: cascade }
is_read: { type: boolean, default: false }
created_at: ~
Wojciech Soczyński

Wojciech Soczyński Programista
eksplorator -
blog.wsoczynski.pl

Temat: Prywatne wiadomości w portalu. Jak zaprojektować?

Po pierwsze "prostrzy" -> "prostszy". Po drugie, w jakim języku będziesz to implementował ? Po trzecie może lepiej zaprojektować to od strony obiektów a sposób zapisu wyłoni się sam ?

konto usunięte

Temat: Prywatne wiadomości w portalu. Jak zaprojektować?

PHP framework Symfony. Chodzi mi bardziej o bazę danych bo nie mam tutaj zbytniej opcji obiektowości. Bardziej chodzi mi o schemat bazy danych, który rozwiąże problemy optymalnego dostępu bez rekurencyjnych zapytań
Wojciech Soczyński

Wojciech Soczyński Programista
eksplorator -
blog.wsoczynski.pl

Temat: Prywatne wiadomości w portalu. Jak zaprojektować?

Dawid D.:
PHP framework Symfony. Chodzi mi bardziej o bazę danych bo nie mam tutaj zbytniej opcji obiektowości. Bardziej chodzi mi o schemat bazy danych, który rozwiąże problemy optymalnego dostępu bez rekurencyjnych zapytań

Nie wiem co masz na myśli mówiąc, że nie masz opcji obiektowości. Natomiast ja bym to zrobił tak (od strony obiektów):



class Thread {

private $id;
private $author;
private $title;
private $message;
private $anwsers;

//przy tworzeniu nowego wątku musi istnieć pierwsza wiadomość
public function __construct($author, $message, $title){
//przypisywanie do pól

$this->_anwsers = new \Doctrine\Common\Collections\ArrayCollection;
}

public function anwser($author, $message){
$this->_anwsers->add( new Anwser($author, $message) );
}

public function listThread(){

$list = $this->anwsers->map(function($item){
return $item->toArray();
}
return $list->toArray();
}
}

class Anwser {

private $id;

public function __construct($author, $message);
public function toArray();

}


Jak już mamy coś takiego to wystarczy użyć Doctrine2 poopisywać pola adnotacjami i baza sama się wygeneruje. Btw to jest naiwna propozycja zakładająca, że wątek jest liniowy, bez żadnych rozgalęzień, po prostu >>

|-Pierwszy Post
|--odpowiedz
|--odpowiedz
|--odpowiedz
|...

Najlepiej od początku wszystko sobie dobrze wyspecyfikować i wtedy można dobrać optymalne rozwiązanie, bo możemy czasem próbować implementować coś co nie mieści się w problemie.

konto usunięte

Temat: Prywatne wiadomości w portalu. Jak zaprojektować?

Dzięki za Twoją propozycję. Niestety używam propela. Wadą takiej obiektowości jaką proponujesz jest ilość zapytań, które są generowane.

Twoja propozycja bardziej pasuje do płaskiej struktury forum, tzn tematu i odpowiedzi. W moim przypadku masz jeszcze nadawce i odbiorcę.

Problematyczne zapytania:
- masz nieprzeczytaną wiadomość w wątku,

Kolejne pytanie jakie mi się nasuwa to klasyfikowanie do skrzynki odbiorczej, nadawczej. Czy klasyfikować na podstawie wątku, tzn. jeżeli wysłałeś do zawsze będzie w nadawczej. Byłoby to trochę bez sensu, bo jak otrzymasz odpowiedź to powinieneś mieć to w odbiorczej.

Tutaj widzę kolejny problem SQLowy. Przypisanie do skrzynki wysłanej było by następujące:
Po pierwsze pobieranie wszystkich wiadomości wysłanych bez odpowiedzi.
Pobranie wszystkich wątków, w których ostatnia wiadomość jest wiadomością wysłaną przez nas.
Wojciech Soczyński

Wojciech Soczyński Programista
eksplorator -
blog.wsoczynski.pl

Temat: Prywatne wiadomości w portalu. Jak zaprojektować?

Dawid D.:
Dzięki za Twoją propozycję. Niestety używam propela. Wadą takiej obiektowości jaką proponujesz jest ilość zapytań, które są generowane.

Twoja propozycja bardziej pasuje do płaskiej struktury forum, tzn tematu i odpowiedzi. W moim przypadku masz jeszcze nadawce i odbiorcę.

Problematyczne zapytania:
- masz nieprzeczytaną wiadomość w wątku,

Kolejne pytanie jakie mi się nasuwa to klasyfikowanie do skrzynki odbiorczej, nadawczej. Czy klasyfikować na podstawie wątku, tzn. jeżeli wysłałeś do zawsze będzie w nadawczej. Byłoby to trochę bez sensu, bo jak otrzymasz odpowiedź to powinieneś mieć to w odbiorczej.

Tutaj widzę kolejny problem SQLowy. Przypisanie do skrzynki wysłanej było by następujące:
Po pierwsze pobieranie wszystkich wiadomości wysłanych bez odpowiedzi.
Pobranie wszystkich wątków, w których ostatnia wiadomość jest wiadomością wysłaną przez nas.

Tutaj potwierdza się stara prawda, że jednym kluczem nie otworzysz wszystkich zamków. Moim zdaniem taka struktura, która opisujesz słabo się nadaje do relacyjnej bazy danych. Niestety pewnie nie masz wpływu na decyzje gdzie to będzie utrwalone.

Jeżeli już tak upierasz się przy SQL-u. To proponuje, żeby to trochę zdenormalizować. Case nieprzeczytana wiadomość w wątku może być jakimś polem w tabeli pomocniczej, załóżmy, że będziemy mieli tabele skrzynki odbiorczej gdzie przykładowy wpis będzie wyglądał tak:

id_uzytkownika: 1
nieprzeczytane_wiadomosci: 1,2,3,5 (tutaj są id nieprzeczytanych wiadomości)
ilosc_wiadomosci_w_skrzynce: 15

Co do wiadomości bez odpowiedzi też można zastosować podobną strategię, jak w przypadku nieprzeczytanych.

Kluczową kwestią w przypadku takiego podejścia jest to, żeby wszystkie operacje, jakie dzieją się na tabelach związanych z prywatnymi wiadomościami przechodziły przez jedno API, które będzie dbało o dopisywanie rzeczy w "nierelacyjnych" kolumnach.

Przykład:



class Messages_Api {

function newMessage();
function anwserMessage();
function listNotAnwsered();
function listNotRead();

//inne przydatne metody
}

Wojciech Soczyński edytował(a) ten post dnia 25.05.11 o godzinie 13:41
Adam Jakub Maciejczyk

Adam Jakub Maciejczyk newPR :: Grupa AG
ESSEKER

Temat: Prywatne wiadomości w portalu. Jak zaprojektować?

Kup sobie klon facebooka na Otwartej Licencji i przerób go pod siebie :)

Mówię jako user - gdyż panel wiadomości (wysyłania, odbierania i czytania) na FB jest chyba najlepszym możliwym przykładem jak to wyglądać powinno :)

konto usunięte

Temat: Prywatne wiadomości w portalu. Jak zaprojektować?

Upieram się przy SQL, bo w aktualnej architekturze portalu to baza przyjmuje ciężar obliczeń i kalkulowania. Niestety w MySQLu nie mam możliwości stworzenia zmaterializowanych widoków, które dały by niezłego kopa dla takich funkcji jak np. liczba nieprzeczytanych wiadomości.

Moja akutlna propozycja relacji w bazie to:
- thread (id, topic)
- message(id, thread_id, content, created_at,sender_id, receiver_id)
- unread_message(user_id, message_id)

w takim układzie zapytania dotyczyć będą jednej tabeli. Pobierając wiadomośc gdzie receiver_id = id uzytkownika i dajac distnict na thread_id mam dostep do wszystkich watkow w skrzynce odbiorczej i do tematu, i do daty ostatniej tresci,

pobierajac unread_messages moge latwo podrubic wiadomosci nieprzeczytane lub wypisac liczbe nieprzeczytanych wiadomosci na stronie głównej.

konto usunięte

Temat: Prywatne wiadomości w portalu. Jak zaprojektować?

Adam Maciejczyk:
Kup sobie klon facebooka na Otwartej Licencji i przerób go pod siebie :)

Mówię jako user - gdyż panel wiadomości (wysyłania, odbierania i czytania) na FB jest chyba najlepszym możliwym przykładem jak to wyglądać powinno :)

Poniekąd tym się sugeruję, jednak bardziej zmierzam w stronę gmaila.
Wojciech Soczyński

Wojciech Soczyński Programista
eksplorator -
blog.wsoczynski.pl

Temat: Prywatne wiadomości w portalu. Jak zaprojektować?

Dawid D.:
Upieram się przy SQL, bo w aktualnej architekturze portalu to baza przyjmuje ciężar obliczeń i kalkulowania. Niestety w MySQLu nie mam możliwości stworzenia zmaterializowanych widoków, które dały by niezłego kopa dla takich funkcji jak np. liczba nieprzeczytanych wiadomości.

Moja akutlna propozycja relacji w bazie to:
- thread (id, topic)
- message(id, thread_id, content, created_at,sender_id, receiver_id)
- unread_message(user_id, message_id)

w takim układzie zapytania dotyczyć będą jednej tabeli. Pobierając wiadomośc gdzie receiver_id = id uzytkownika i dajac distnict na thread_id mam dostep do wszystkich watkow w skrzynce odbiorczej i do tematu, i do daty ostatniej tresci,

pobierajac unread_messages moge latwo podrubic wiadomosci nieprzeczytane lub wypisac liczbe nieprzeczytanych wiadomosci na stronie głównej.

Możesz też do message dodać pole "status" - 0/1 (przeczytana/nieprzeczytana) co do zmaterializowanych widoków to zawsze możesz sobie dodać jakąś warstwę cache'ującą, która będzie np. pomiędzy klasą Api o którym mówiłem a bazą...

Następna dyskusja:

Jak zaprojektować mod_rewrite




Wyślij zaproszenie do