traducir online inspiration desing bom app design

online - desing o design



Construyendo un sistema de notificación (3)

Esta es realmente una pregunta abstracta, así que supongo que tendremos que discutirla en lugar de señalar lo que debe o no debe hacer.

Esto es lo que pienso sobre tus preocupaciones:

  • Sí, un sistema de notificación es complejo, pero no tanto como el infierno. Puede tener muchos enfoques diferentes sobre el modelado y la implementación de dichos sistemas, y pueden tener un nivel medio o alto de complejidad;

  • Pesonalmente, siempre trato de hacer cosas basadas en bases de datos. ¿Por qué? Porque puedo garantizar un control total de todo lo que está sucediendo, pero así soy yo, puedes tener el control sin un enfoque basado en bases de datos; confía en mí, vas a querer el control de ese caso;

  • Déjame ejemplificar un caso real para ti, para que puedas comenzar desde algún lado. En el último año, he modelado e implementado un sistema de notificación en algún tipo de red social (no como Facebook, por supuesto). La forma en que solía almacenar notificaciones allí? Tenía una tabla de notifications , donde guardaba el generator_user_id (el ID del usuario que está generando la notificación), el target_user_id (algo obvio, ¿no?), El notification_type_id (que hacía referencia a una tabla diferente con tipos de notificación ), y todas las cosas necesarias que necesitamos para llenar nuestras tablas (marcas de tiempo, banderas, etc.). Mi tabla notification_types solía tener una relación con una tabla notification_templates , que almacenaba plantillas específicas para cada tipo de notificación. Por ejemplo, tenía un tipo POST_REPLY , que tenía una plantilla similar a {USER} HAS REPLIED ONE OF YOUR #POSTS . A partir de ahí, acabo de tratar el {} como una variable y el # como un enlace de referencia;

  • Sí, el rendimiento debe y debe estar bien. Cuando piensas en las notificaciones, piensas que el servidor empuja de la cabeza a los pies. O bien, si lo vas a hacer con solicitudes ajax o lo que sea, tendrás que preocuparte por el rendimiento. Pero creo que es una preocupación por segunda vez;

Ese modelo que he diseñado es, por supuesto, no el único que puedes seguir, ni tampoco el mejor. Espero que mi respuesta, al menos, te siga en la dirección correcta.

Estoy comenzando a construir un sistema de notificación de estilo de Facebook para nuestra página (tipo de juego social) y ahora estoy investigando cuál sería la mejor manera de diseñar dicho sistema. No estoy interesado en cómo enviar notificaciones al usuario ni nada de eso (por ahora, incluso). Estoy investigando cómo construir el sistema en el servidor (cómo almacenar notificaciones, dónde almacenarlas, cómo recuperarlas, etc.).

Entonces ... algunos requisitos que tenemos:

  • en las horas punta tenemos aproximadamente 1k usuarios conectados simultáneos (y muchos más invitados, pero no importan porque no tendrán notificaciones) que generarán muchos eventos
  • Habrá diferentes tipos de notificaciones (el usuario A lo ha agregado como amigo, el usuario B ha comentado su perfil, el usuario C le ha gustado su imagen, el usuario D lo ha derrotado en el juego X, ...)
  • la mayoría de los eventos generará 1 notificación para 1 usuario (al usuario X le ha gustado su imagen), pero habrá casos en que un evento generará muchas notificaciones (es el cumpleaños de Y del usuario, por ejemplo)
  • las notificaciones deben agruparse juntas; si, por ejemplo, cuatro usuarios diferentes prefieren alguna imagen, el propietario de esa imagen debería recibir una notificación que indique que a cuatro usuarios les ha gustado la imagen y no a cuatro notificaciones separadas (al igual que FB)

OK, entonces lo que estaba pensando es que debería crear algún tipo de cola en la que almacenara eventos cuando ocurrieran. Entonces, ¿tendría un trabajo de fondo (¿ gearman ?) Que analizaría esa cola y generaría notificaciones basadas en esos eventos. Este trabajo almacenaría notificaciones en la base de datos para cada usuario (por lo que si un evento afecta a 10 usuarios, habría 10 notificaciones por separado). Luego, cuando el usuario abriera una página con la lista de notificaciones, leería todas las notificaciones para él (pensamos limitar esto a 100 notificaciones más recientes) y las agruparemos para finalmente mostrarlas.

Cosas que me preocupan con este enfoque:

  • complejo como el infierno :)
  • La base de datos es el mejor almacenamiento aquí (estamos usando MySQL) o debería usar otra cosa (el redis también parece una buena opción)
  • ¿Qué debo almacenar como una notificación? ID de usuario, ID de usuario que inició el evento, tipo de evento (para que pueda agruparlos y mostrar el texto apropiado) pero luego no sé cómo almacenar los datos reales de la notificación (por ejemplo, URL y título de la imagen que me gustó). ¿Debo simplemente "hornear" esa información cuando genero la notificación, o debo almacenar la identificación del registro (imagen, perfil, ...) afectada y extraer la información del DB al mostrar la notificación?
  • el rendimiento debería estar bien aquí, incluso si tengo que procesar 100 notificaciones sobre la marcha al mostrar la página de notificaciones
  • posible problema de rendimiento en cada solicitud porque tendría que mostrar el número de notificaciones no leídas al usuario (lo que podría ser un problema en sí mismo ya que agruparía las notificaciones juntas). Esto podría evitarse si generara la vista de las notificaciones (donde están agrupadas) en el fondo y no sobre la marcha

Entonces, ¿qué piensas sobre mi solución propuesta y mis preocupaciones? Comente si cree que debería mencionar cualquier otra cosa que sea relevante aquí.

Oh, estamos usando PHP para nuestra página, pero eso no debería ser un gran factor aquí, creo.


Una notificación se trata de algo (objeto = evento, amistad ...) cambiado (verbo = agregado, solicitado ...) por alguien (actor) e informado al usuario (sujeto). Aquí hay una estructura de datos normalizada (aunque he usado MongoDB). Debe notificar a ciertos usuarios sobre los cambios. Por lo tanto, se trata de notificaciones por usuario ... lo que significa que si hubo 100 usuarios involucrados, generas 100 notificaciones.

╔═════════════╗ ╔═══════════════════╗ ╔════════════════════╗ ║notification ║ ║notification_object║ ║notification_change ║ ╟─────────────╢ ╟───────────────────╢ ╟────────────────────╢ ║ID ║—1:n—→║ID ║—1:n—→║ID ║ ║userID ║ ║notificationID ║ ║notificationObjectID║ ╚═════════════╝ ║object ║ ║verb ║ ╚═══════════════════╝ ║actor ║ ╚════════════════════╝

(Agregue campos de tiempo donde mejor le parezca)

Esto es básicamente para agrupar los cambios por objeto, para que pueda decir "Tiene 3 solicitudes de amistad". Y la agrupación por actor es útil, por lo que podría decir "Usuario James Bond hizo cambios en su cama". Esto también le da la capacidad de traducir y contar notificaciones a su gusto.

Pero, como el objeto es solo una identificación, necesitaría obtener toda la información adicional sobre el objeto que desea con llamadas separadas, a menos que el objeto realmente cambie y quiera mostrar ese historial (por ejemplo, "el usuario cambió el título del evento para ... ")

Debido a que las notificaciones están cercanas a tiempo real para los usuarios en el sitio, las vincularía con nodejs + websockets client con php presionando update en nodejs para todos los oyentes a medida que se agreguen los cambios.


╔════════════════════╗ ║notification ║ ╟────────────────────╢ ║Username ║ ║Object ║ ║verb ║ ║actor ║ ║isRead ║ ╚════════════════════╝

Esto parece una buena respuesta en lugar de tener 2 colecciones. Puede consultar por nombre de usuario, objeto y esRead para obtener nuevos eventos (como 3 solicitudes de amistad pendientes, 4 preguntas, etc.)

Avíseme si hay un problema con este esquema.