2010-09-29 11 views
7

bien, otro problema interesante sobre en la Ruta 50.¿Cuál es la forma más eficiente de crear un sistema de bombilla de foro (no leída)?

Nos quería implementar un verdadero sistema de bombilla foro en el que los mensajes que son leídos por un usuario (después de crear la cuenta del usuario) muestran como no leído hasta que se borre esa condición o hasta que el usuario los lea.

Pensamos que la mejor y más fácil forma de hacerlo sería implementar una tabla de mensajes no leídos.

Las columnas son: user_id, board_id, thread_id, post_id, timestamp, y hidden

Esto está funcionando muy bien y muy rápidamente para ver qué tablas/hilos/mensajes son leídos (y la vinculación a ellos) por usuario , sin embargo, es increíblemente lento para que un usuario publique en el foro a pesar de que sólo una única consulta SQL se ejecuta:

INSERT IGNORE INTO `forums_lightbulb` SELECT `id`,'x','x','x',UNIX_TIMESTAMP(),0 FROM `users` 

estoy seguro que esto es el resultado de tener 3065 cuentas de usuario. ¿Cómo puedo acelerar este proceso? Prefiero mantener el sistema como Real-Time como sea posible.

Nota importante: Limite sus respuestas a un entorno de alojamiento compartido sin presupuesto adicional. Estamos limitados a PHP y MySQL 5.1.53-log

+0

Si pudiera, querría usar filtros de floración – amirouche

Respuesta

9

Lo que hace PHPBB es una forma muy rápida de hacerlo. Mantiene una tabla que marca para cada hilo y cada foro cuando la última vez que un usuario lo abrió. Y lo usa para determinar si hay mensajes no leídos.Permite a los Usuarios * Temas + Usuarios * el esquema de uso de almacenamiento de Foros al tiempo que permite un control con consultas simples y rápidas.

Puede ver cómo funciona desde la estructura de la base de datos.

# Table: 'phpbb_forums_track' 
CREATE TABLE phpbb_forums_track (
    user_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, 
    forum_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, 
    mark_time int(11) UNSIGNED DEFAULT '0' NOT NULL, 
    PRIMARY KEY (user_id, forum_id) 
) CHARACTER SET `utf8` COLLATE `utf8_bin`; 

# Table: 'phpbb_topics_track' 
CREATE TABLE phpbb_topics_track (
    user_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, 
    topic_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, 
    forum_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, 
    mark_time int(11) UNSIGNED DEFAULT '0' NOT NULL, 
    PRIMARY KEY (user_id, topic_id), 
    KEY topic_id (topic_id), 
    KEY forum_id (forum_id) 
) CHARACTER SET `utf8` COLLATE `utf8_bin`; 
+0

¡Esto podría ser lo que estoy buscando! ¡Gracias! Otorgaré la recompensa a menos que alguien responda mejor, ¡pero estoy bastante seguro de que esto es lo que estaba intentando descubrir! – Navarr

+1

¿Para qué es el software de código abierto? Aprendiendo el uno del otro: D – Beanow

1

En lectura:

insert into read_articles(user_id, article_id); 

En la exhibición:

SELECT a.*, r.user_id FROM articles a 
LEFT OUTER JOIN read_articles r ON (a.article_id = r.article_id and r.user_id = $user_id) 
WHERE (article_filter, like forum or thread id, or whatever) 

En el conjunto de resultados, si user_id no es nulo, entonces' he leído el artículo. De lo contrario, no lo han hecho.

Indique según corresponda. Servidor cálido con galletas y mermelada.

+0

Esto es realmente lo contrario de lo que quería manejar esto .. – Navarr

4

Lo siento, pero la solución propuesta en la pregunta es un diseño no escalable.

Estaba investigando este problema en here, que tuvo una discusión decente (antes de que apareciera). Echa un vistazo allí.

En su caso, almacenar registros U * M para rastrear publicaciones "no leídas", donde U es la cantidad de usuarios y M es la cantidad de mensajes, se saldría de control muy, muy rápido. Esto se debe a que su eficacia en el mejor de los casos requiere que todos los usuarios lean cada mensaje (y a la mayoría de los usuarios no les importa todo, ya que la mayoría de los elementos de un foro son ruidos). Caso promedio, tal vez el 20% de los usuarios han leído el 100% de las publicaciones, pero el 80% han leído cerca del 0% de las publicaciones y nunca leerán el resto. Esto significa que te obligan a almacenar 0.8 * U * M, con U y M solo aumentando, geométricamente. Ninguna cantidad de indexación solucionará esto.

La respuesta anterior @ will-hartung tiene el enfoque más eficiente.

Veo que esto es bastante viejo, y espero que haya encontrado una mejor solución mientras tanto.

+0

Teoricé una solución mejor, que es una mezcla de marcas de tiempo y mensajes de almacenamiento leídos, o algo así como ese. No lo he planeado por completo. Mientras tanto, sin embargo, desactivé el sistema de bombilla. – Navarr

2

Aquí es la forma más eficiente:

  1. tiene una tabla llamada read_threads que almacena la thread_id y user_id
  2. tiene una columna en la tabla users llama mark_read_date que almacena la fecha en que el usuario hizo clic en el enlace mark all threads read en su foro
  3. para determinar si se lee un hilo, su consulta comprobará si está en eltabla, o si su last_post_date (la fecha del último mensaje fue hecha a él) es más antiguo que el usersmark_read_date

Es importante que también elimina todas las filas de la tabla read_threads cuando un usuario hace clic en el enlace mark all threads read en tu foro

Cuestiones relacionadas