2009-02-19 6 views
4

Je développe un nouveau site, et je dois faire des messages privés pour nos utilisateurs. J'ai déjà fait cela sur d'autres projets, mais la conception là-bas ne me semble pas juste (je ne peux pas avoir plus de deux personnes engagées dans un message par exemple). Alors, quelle est la «bonne» approche? J'aimerais offrir à mes utilisateurs la même fonctionnalité que Facebook (encore une fois, j'ai déjà fait ça mais ça me semble sale :)) Donc le système devrait supporter 2 utilisateurs ou plus dans une conversation et des messages de type thread.Conception de messages privés

Je pensais et une solution serait d'avoir deux tables comme ceci:

pm_messages: id | pm_messages_id | user_id | titre | contenu | date_time

pm_recipients: id | pm_messages_id | user_id | has_seen |

Je stockerais le contenu réel dans la table "pm_messages", et je stockerais les destinataires (y compris l'expéditeur d'origine) dans la table "pm_recipients".

Est-ce la bonne direction ou suis-je complètement hors de cela? Ce qui me dérange ici, c'est que les messages ne sont vraiment effacés que lorsque tous les destinataires ont supprimé le message, ce qui entraîne une logique de suppression délicate.

Répondre

6

S'il peut y avoir plusieurs destinataires, et qu'ils peuvent envoyer des msgs de réponse, vous êtes plus à traiter avec une sorte d'application de chat. Vous pouvez stocker les sessions de "chat", ou les conversations dans une table séparée avec une relation 1-n entre la conversation et le participant, ainsi que la relation 1-n entre la conversation et le message (tableaux présentés ci-dessous). Mais à la fin, c'est bien sûr à vous de voir. Pour l'envoi régulier de messages, un 1-n entre le message et le destinataire que vous utilisez fera l'affaire.

table user: 
- id (pk) 
- name 

table conversation (one entry per "chat/messaging" session) 
- id (pk) 
- started_by_user_id 
- started_ts 

table conversation_participant (keeps track of all recipients) 
- id (pk) 
- conversation_id 
- user_id (refers to user.id) 

table message 
- id 
- conversation_id (refers to conversation.id) 
- sender (refers to user.id) 
- msg 
+0

Quel est l'avantage de deux tables (la vôtre conversation et le message) par rapport à un pour les messages (mes pm_messages)? –

+0

La conversation est comme une session de conversation. Il peut contenir beaucoup de messages. – tehvan

+0

Vous pouvez le faire avec ma conception à, et c'est une table de moins. D'autres ups? –

1

Je ne dirais pas que la mise en œuvre que vous avez proposée dans votre message est nécessairement mauvaise. Certes, ce n'est pas le plus concis ou le plus rapide, mais il me semblerait le plus compréhensible pour les humains. De plus, la logique de suppression ne devrait pas être très difficile à encapsuler.

Une solution que je pourrais suggérer est d'utiliser plutôt une seule table qui stocke chaque message, contenant le champ pour l'ID de l'expéditeur, et un autre champ qui est une liste d'ID de destinataire. Le problème, bien sûr, est de décider comment représenter une liste d'ID en utilisant l'un des types de base de données standard, étant donné qu'il n'y a généralement pas de type array/vector/list. Je vous suggère d'utiliser le type VARBINARY (max), s'il est disponible, en le traitant comme un vecteur bit (disons 4 octets par identifiant de destinataire). Ensuite, vous pouvez simplement créer quelques fonctions pour faire le très simple encodage/décodage bit à bit vers/à partir d'un tableau/liste.

+0

Il n'y aurait aucun moyen propre de suivre qui a vu ou/et supprimer le message de cette façon. À moins, bien sûr, qu'il me manque quelque chose avec votre proposition? J'aime aussi avoir mes tables normalisées à moins que ce ne soit absolument nécessaire ... –

+0

Eh bien, vous utiliseriez simplement un autre champ de vecteur de bits pour cela (où chaque bit représente un drapeau booléen) - c'est assez simple à implémenter, vraiment. Ma solution proposée n'est peut-être pas la plus belle, mais elle est certainement rapide, si vous êtes après ça! – Noldorin

+0

Dunno, il semble que je devrais le faire dans la base de données pour obtenir les résultats souhaités et je ne suis pas au courant de MySQL supportant cela. –

0

Qu'est-ce que la colonne pm_messages_id dans la table pm_messages?

Sinon, cela a du sens ... Mais je ne vois pas pourquoi la logique de suppression devrait être gênante. Vous pouvez le gérer de l'une des deux manières suivantes:

  1. Après qu'un utilisateur l'ait supprimé: supprimez s'il n'y a plus de destinataires.
  2. En tâche cron ou manuellement ultérieurement: Il n'y a aucune raison pour que cette suppression ait lieu immédiatement. Ils sont simplement des enregistrements orphelins, et ils peuvent être trouvés facilement:

par exemple.:

DELETE FROM pm_messages 
RIGHT JOIN pm_recipients ON pm_messages.id = pm_recipients.pm_messages_id 
+0

Bizarre dans un sens que ce n'est pas une simple clause DELETE FROM. Et j'aime bien :) Le pm_messages_id fait référence au message "parent" pour que vous puissiez avoir des messages threadés. Une structure arborescente si vous voulez. –

-1

(trop long pour un commentaire)

méthode Tehvans consiste à stocker une liste des participants pour une conversation particulière, alors que dans votre méthode, les participants sont stockés par message. Je m'attends à ce que la raison de ceci soit de permettre la suppression et la lecture des messages, la question est: pourquoi le faire comme ça? En règle générale, les forums ne requièrent pas de marquer chaque partie de la conversation comme lue, donc de stocker un horodatage last_read dans la table des participants, de manière à ce que tous les messages créés/modifiés après l'horodatage puissent être mis en évidence.

Dans (presque) tous les cas, la suppression de messages de forum est effectuée par l'auteur/les administrateurs et entraîne la suppression du message pour tous les utilisateurs.

+0

Ce sont des messages privés, pas des forums – Swati

0

Encore un cas d'utilisation à considérer (je sais que mes utilisateurs le veulent) ... ils veulent tous un "éléments envoyés". Peut-être que vous devriez considérer ce cas d'utilisation avant de nettoyer pour ainsi dire.

Ce qui me dérange est ici que les messages ne sont pas vraiment supprimés jusqu'à ce que tous les destinataires ont supprimé le message qui conduit à une certaine logique la suppression maladroite.

Créez un déclencheur qui effectue cela pour vous. Tout ce que votre code d'application doit faire, c'est vous inquiéter de mettre votre colonne "deleted" à true et que le déclencheur UPDATE nuke l'ensemble du deal lorsque tout le monde marque le message comme supprimé.

Bien sûr, vos utilisateurs voudront peut-être supprimer. Personnellement, je ne supprimerais jamais le message de la base de données, juste le cacher de l'utilisateur.