Diseño de base de datos para una aplicación estilo correo electrónico

Estoy buscando algunos consejos sobre cómo diseñar una base de datos para una aplicación estilo correo electrónico, específicamente cómo manejar el envío de un mensaje a múltiples usuarios y mostrar qué mensajes se enviaron a qué usuarios.

Esto es lo que tengo hasta ahora:

Mensajes (La clave principal es Id)

  • Id (identidad)
  • SenderId (clave externa para Users.Id)

Mensajes recibidos (La clave principal es MessageId + RecipientId)

  • MessageId (clave externa a Messages.Id)
  • RecipientId (clave externa para Users.Id)
  • Es leído

Entonces, por cada mensaje enviado, habría una fila en Mensajes, con los datos, y luego una fila para cada destinatario en ReceivedMessages.

Pero, ¿qué pasa si quiero ver todos los mensajes enviados por un usuario y a quién se enviaron? Para cada mensaje, necesitaría encontrar todas las filas de ReceivedMessages para ese mensaje y unirlas a todas con la tabla de usuario, y luego de alguna manera concatear todos los nombres (algo como esto: ¿Concatenar muchas filas en una sola cadena de texto?). ¿Podría esto causar problemas de escala o no es realmente algo de qué preocuparse?

¿Alguna idea / sugerencia? Gracias.

preguntado el 16 de mayo de 11 a las 20:05

4 Respuestas

No veo ningún problema con su diseño, y no anticiparía problemas de escalabilidad con una indexación adecuada en sus tablas (a menos que esté hablando de una escala masiva, por ejemplo, gmail, correo de Yahoo, etc.).

En cuanto a concatenar los nombres de los destinatarios, le recomendaría que lo haga en el lado de la aplicación y no en SQL, o que determine si necesita hacerlo (es posible que desee mostrar una lista y no una cadena concatenada).

contestado el 17 de mayo de 11 a las 00:05

todos los mensajes enviados por un usuario y a quién fueron enviados

Puede hacerlo como una consulta agregada, algo como:

SELECT u1.user_name, m.message, GROUP_CONCAT(DISTINCT u2.user_name)
FROM messages m JOIN users u1 ON (m.senderID=u1.user_id)
                JOIN receivedmessages r ON (m.id=r.messageId)
                JOIN users u2 ON (r.RecipientId=u2.user_id)
GROUP BY u1.user_name, m.message;

Pero debido a que Destinatarios es esencialmente ilimitado, puede encontrarse con el límite de longitud de la cadena en GROUP_CONCAT.

Por lo tanto, es probable que sea mejor hacer una selección no agregada y procesar los registros para mostrarlos en su capa de aplicación:

SELECT u1.user_name, m.message, DISTINCT u2.user_name
FROM messages m JOIN users u1 ON (m.senderID=u1.user_id)
                JOIN receivedmessages r ON (m.id=r.messageId)
                JOIN users u2 ON (r.RecipientId=u2.user_id)
ORDER BY u1.user_name, m.sent_date, u2.user_name;

contestado el 17 de mayo de 11 a las 00:05

Los usuarios cambian el nombre y el correo electrónico, pero no su inicio de sesión. Considere la posibilidad de imitar lo que sucede en un buzón de correo basado en Unix (por ejemplo, pine) en su lugar:

received_messages (
  user_id,
  message_id,
  message_date,
  message_title,
  message_content,
  message_sender,
  message_recipient,
  message_is_read
)

y sent_messages en la misma línea, es decir, dos "archivos" por usuario.

O incluso fusionando los dos últimos con una bandera de enviado / recibido.

contestado el 17 de mayo de 11 a las 08:05

Me enfrento al mismo desafío de crear un correo electrónico o un sistema de mensajería para un sitio web ... Ustedes se olvidan de una cosa ... IsRead, IsDraft, IsFlagged, IsReply, IsTrash, etc. ¡El mismo mensaje será marcado, leído o no leído por dos o más personas! Entonces, debemos tener una tabla de estado como se muestra a continuación ...

StatusID    int     
MessageID   int  
MemberID    int  
DateTime    datetime    
IPAddress   varchar(65)  
IsRead  char(1)   
IsDraft char(1)  
IsFlagged   char(1)   
IsForwarded char(1)  
IsReply char(1)  
IsTrash char(1) 

Necesitará al menos tres tablas además de la tabla de miembros o usuarios:

mail  
folders  
status  
attachment  
log  

Si esto es para un sitio web existente ... Separaría el sistema de correo en una base de datos separada si espera que este sistema de correo tenga mucha actividad.

respondido 10 nov., 12:12

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.