php - Logros/Sistema de Insignias.
mysql architecture (4)
He estado buscando en este sitio la respuesta, pero todavía no estoy seguro de cómo planificar un sistema similar en su estructura de base de datos e implementación.
En PHP y MySQL quedaría claro que algunos logros se obtienen de inmediato (cuando se realiza una acción especializada, en el caso de SO: se completaron todos los campos de perfil), aunque sé que SO se actualiza y asigna credenciales después de un cierto tiempo. Con tantos usuarios y distintivos, esto no crearía problemas de rendimiento (en términos de escala: gran número de usuarios y distintivos).
Así que la estructura de la base de datos que asumo sería algo tan simple como:
Badges | Badges_User | User
----------------------------------------------
bd_id | bd_id | user_id
bd_name | user_id | etc
bd_desc | assigned(bool) |
| assigned_at |
Pero como algunas personas han dicho, sería mejor tener un enfoque de estilo incremental para que un usuario que tenga 1,000,000 publicaciones en el foro no ralentice ninguna función.
¿Sería entonces otra tabla para credenciales que podría ser incremental o simplemente un campo de ''progreso'' en la tabla badges_user de arriba?
Gracias por leer y concéntrese en la escalabilidad del sistema deseado (como SO miles de usuarios y 20 a 40 credenciales).
EDITAR: para aclarar un poco la confusión que había asignado como Fecha / Hora, los criterios para otorgar la credencial serían los mejores colocados dentro de las consultas / funciones preparadas para cada credencial, ¿no es así? (mejor flexibilidad)
Creo que este es uno de esos casos en los que su tabla de muchos a muchos (Badges_User) es apropiada.
Pero con una pequeña alteración para que las insignias no asignadas no se almacenen.
Supongo que el valor assigned_at
es una fecha y / o una hora.
Por defecto es que el usuario no tiene las insignias.
Badges | Badges_User | User
----------------------------------------------
bd_id | bd_id | user_id
bd_name | user_id | etc
bd_desc | assigned_at |
| |
De esta manera solo se almacenan las insignias que se otorgan.
Una fila Badges_User solo se crea cuando un usuario obtiene una insignia.
Saludos
Sigersted
Creo que la estructura que ha sugerido (sin el campo "asignado" según los comentarios) funcionaría, con la adición de una tabla adicional, diga "Usuario_devisiones", que contiene una referencia a ID de usuario y un campo de incremento para contar las presentaciones. Entonces, todo lo que necesitas es un "detector de eventos" según esta publicación y los métodos que deberías configurar.
EDITAR: para las insignias de logros, ejecute el oyente del evento en cada presentación (solo para el usuario que realiza la presentación, por supuesto), y otorgue cualquier insignia relevante en el momento. Para las insignias basadas en el tiempo, ejecutaría un trabajo CRON cada noche. Recorra la lista completa de usuarios una vez y otorgue las insignias según corresponda.
Mantendría una estructura de tipo similar a la que tienes
Badges(badge_id, badge_name, badge_desc)
Users(user_id, etc)
UserBadges(badge_id, user_id, date_awarded)
Y luego agregue la (s) tabla (s) de seguimiento dependiendo de lo que quiera rastrear y @ a qué nivel de detalle ... luego puede actualizar la tabla como corresponda y configurar los activadores para "otorgar" los distintivos
User_Activity(user_id, posts, upvotes, downvotes, etc...)
También puede realizar un seguimiento de las estadísticas desde la otra dirección y activar premios de distintivos.
Posts(post_id, user_id, upvotes, downvotes, etc...)
Algunos otros buenos puntos se hacen aquí
con respecto al boceto que incluyó: elimine la columna booleana en badges_user. no tiene sentido allí: esa relación se define en términos del predicado "usuario user_id ganó la credencial bd_id en asignado_at".
En cuanto a su pregunta general: defina que el esquema sea relacional sin tener en cuenta la velocidad primero (eso lo librará de la mitad de los posibles problemas de rendimiento, posiblemente a cambio de diferentes problemas de rendimiento), indexe correctamente (lo que sea correcto depende de los patrones de consulta), entonces si es lento, derive un diseño (aún relacional) a partir de eso es más rápido. como es posible que tenga que tener algunos agregados precomputados, etc.