Base de Datos de Arquitectura de Sistema y arbitrarias “insignia” Criterios (MySQL / PHP)

StackOverflow https://stackoverflow.com/questions/1049233

  •  20-08-2019
  •  | 
  •  

Pregunta

Quickie-Pregunta:

En resumen, estoy un poco confundido en cuanto a cómo iba a diseñar una base de datos de tal manera que permite la creación indefinida insignia en reglas sin necesidad de cambios estructurales en la facilidad de uso tablas previamente existente en la base de datos.

Almacenamiento de Placa título, criterios, etc. ¿Cómo sería que el cuadro parece?

  • badge_id (1)
  • badge_title (10K insignia)
  • badge_image (10k.jpg)
  • badge_criteria ([mensajes]> = 10.000)
    ...

Winded-Pregunta:

Me gustaría poner en práctica un sistema de tarjeta de identificación en mis propios proyectos personales, pero estoy buscando un poco de consejo en cuanto a cómo se podría hacer mejor tal cosa. He estado leyendo algunas de las preguntas aquí sobre insignia-sistemas, pero no veo la base de datos en la arquitectura conseguir mucha atención.

Placas que se basan en la facilidad de puntos (hipotética "insignia" 10k) parece bastante sencillo. Cualquier evento que afecta a la reputación de los usuarios (upvotes, downvotes, respuesta-aceptado, etc) podría invocar un método para revisar la reputación de los usuarios nuevos y potencialmente otorgará una tarjeta de identificación.

Ese sistema suena bastante simple, pero lo que se ve eso como una base de datos para el administrador que quiere crear innumerables cantidades de insignias con poco esfuerzo en el camino - algunos de los cuales puede estar basada en diferentes criterios, y no simplemente la reputación del usuario.

es el usuario reputación probablemente un valor dentro de la facilidad de registro mismo. Pero lo ideal, no le gustaría evitar tener que añadir nuevos campos a la tabla de usuario al crear nuevas insignias? Por ejemplo, el "Editado 100 entradas" insignia - no se podría crear una nueva columna "entries_edited" dentro de los Usuarios de mesa, ¿verdad? Y a continuación, incremento que después de cada entrada-editado ...

¿Alguna pista?

Stackoverflow Archivo:


Nota: No estoy pidiendo cómo asociar insignias con los usuarios. No estoy pidiendo la forma de insignias de premios (que se llevará a cabo mediante programación)

¿Fue útil?

Solución

Dado que los criterios insignia pueden ser arbitrariamente compleja, no creo que se puede almacenar en una tabla de base de descomponerse en elementos de datos "simples". Tratando de escribir un "motor de reglas" que puede manejar criterios arbitrariamente complejas se va a llevar por el camino de, básicamente, volver a escribir todas las herramientas que usted tiene en su lenguaje de programación.

Si usted sabe de antemano que desea las insignias limitan a sólo ciertos campos (es decir, insignias se basan únicamente descuento en la reputación o el número de ediciones o algo así), entonces se puede almacenar las de una tabla sencilla como:

ReputationBadgeCriteria
  BadgeId
  BadgeName
  MinReputation

Como alternativa, puede utilizar algún tipo de DSL para escribir sus "reglas", pero que al final tener que crear también un analizador para analizar las reglas cuando los lee, así como algo de ejecutar estas reglas. Dependiendo de la complejidad que desee en su DSL, esto puede no ser una tarea trivial. Esto parece el camino que va en su pregunta con tener una columna Criterios (texto sin formato presumiblemente) que tiene algo así como "[Reputación]> 1000" o "[Mensajes]> 5" en ella. Usted todavía tiene que analizar y ejecutar las reglas y la complejidad de escribir algo para hacerlo depende de la complejidad que desea esas reglas sean.

Yo recomendaría que lea estos Daily WTF artículos para obtener información sobre por qué este enfoque conduce al dolor.

Otros consejos

En función de lo lejos que quiere ir con él, el esquema puede ser bastante complicado. Me parece que los elementos de base que necesita para realizar un seguimiento son:

Badges awarded
Points earned

Muy simple hasta el momento, pero que desea ser capaz de crear dinámicamente nuevas insignias y nuevas categorías puntos. premios insignia dependerían de ganar puntos en una o más categorías de puntos que se suman a una cierta cantidad. Así que hay que realizar un seguimiento de la relación entre las categorías de puntos (y los puntos ganados) e insignias:

Point categories
Badge categories

Así que la clave sería la tabla de puntos de usuario, que uniría a señalar categorías, que enlazan con insignias. Los usuarios ganan puntos en una categoría en particular, lo que contribuiría a ganar puntos para una o más placas.

badges:
badge_id
badge_name
required_points
....

point_categories:
point_id
category_name
weighting (optional)
...

point_groups:
badge_id
point_id
weighting (optional)
...

user_points:
user_id
point_id
points
...

user_badges:
user_id
badge_id
points_earned
badge_awarded (yes/no)
...

Su interfaz "admin" permitiría a alguien para crear una nueva tarjeta de identificación y elegir qué categorías punto se requiere para ganar esa placa (point_groups). Cada vez que un usuario gana puntos (user_points), se actualiza la tabla user_points, a continuación, determinar qué insignias aquellos puntos que podrían contribuir a (point_groups). A continuación, vuelva a compilar los puntos para las insignias que fueron afectadas por los puntos ganados y actualizar la tabla user_badges con el point_earned. A continuación, compruebe el campo points_earned en user_badges contra los required_points en la tabla insignias.

Se puede conseguir mucho más elegante mediante la asignación de diferentes pesos para diferentes categorías de puntos, o incluso diferentes pesos para las categorías de puntos de insignias particulares. Sin embargo, esta configuración permitiría una cantidad ilimitada de divisas y categorías de punto de ser creado y gestionado con bastante facilidad sin cambiar las estructuras de tablas.

Si eso no es lo que busca es completo, entonces creo que debería tener al menos uno o dos votos para escribir mucho.

Se podría realizar un seguimiento de sus usuarios únicos en una tabla e insignias únicas en otro continuación, crear una tabla de referencia cruzada de relacionarlos.

Un usuario puede tener muchas insignias y una tarjeta de identificación puede tener muchos usuarios.

create table users (
id int,
name varchar
)

create table badges (
id int,
badge_name varchar
)


create table user_badges_xref (
user_id int,
badge_id int
)

Estadísticas que podrían afectar si un usuario gana una tarjeta de identificación se realiza un seguimiento como parte de la administración del sitio. así que algo como una respuesta de ser aceptado estaría en un esquema que relaciona las preguntas y respuestas. con el fin de mostrar la respuesta y el propietario de la respuesta, no habría una relación a la tabla de usuario y disparadores que comprobar si hay condiciones insignia cada vez que se realiza un cambio.

  

No estoy pidiendo la manera de premio insignias.   Estoy preguntando cómo almacenar criterios dentro de la base de datos.

Así que desea almacenar la operación lógica requerida para determinar si una tarjeta de identificación se gana en un campo en algún lugar?

Creo que de acuerdo con el otro cartel que los criterios deben ser una parte de la lógica de negocio. Esa lógica puede estar en el lado aplicación o dentro de un gatillo. Creo que es una cuestión de estilo.

Si estaba realmente casado con la idea de almacenar los criterios en un campo, me lo guardo como SQL parametrizada y ejecutarlo de forma dinámica.

Así que este tipo de cosas que sería en su campo de criterios:

select "Badge Earned"
from all_posts 
where user_id = @user_id
having count(*) > 10000

No crearía un incremento de la edición placa. Creo que usted debe tener un trabajo en ejecución en segundo plano y count () el numbero de mensaje editado para los miembros que no tienen la insignia de la edición todavía. Cuando vea que el conteo ha terminado el intervalo que desea, se agrega una entrada en la base de datos que decir que el usuario tiene la tarjeta de identificación.

Creo que es aproximadamente el mismo para otras insignias. Trate de limitar el número de escritura y no escribir directamente el recuento de la información insignia en la tabla de usuario. Utilizar una tabla que contendrá información insignia y vincularlo a la tabla de usuario.

Me disculpo por ser breve.

Para implementar un sistema de este tipo, podría crear una tabla que almacena ya sea nombres de los procedimientos almacenados o consultas reales que serían utilizados para determinar si un usuario particular ha ganado una insignia.

badge_criteria
badge_key int
badge_criteria varchar(max)

Puede extraer y ejecutar las consultas para los pases de los cuales el usuario no ha conseguido desde su nivel medio, pero no tendría que hacer ningún cambio de código o estructurales para agregar nuevas insignias en el futuro.

Me estoy acercando de esta manera: Crear una tabla para almacenar todas las insignias, y tiene una columna de referencia de una función que se ejecuta para ver si se otorga el distintivo. De esta manera la tabla sigue siendo simple y la lógica para determinar las insignias se pueden mantener en el código, en el que es el más adecuado.

Con este método, Requisitos de la identificación podría también ser unidos entre sí, para formar dependencias más complejas. Por ejemplo, el usuario debe recibir tres placas separadas, específicas w / en un período de tiempo determinado con el fin de obtener esta placa.

Esto va a ser casi imposible de hacer en la base de datos - entregando insignias deben hacerse en su lógica de negocio dentro de la aplicación. De esta manera, usted tiene todos los datos existentes es necesario (ediciones, visitas, reputación, etc.) y que pueden ser tratados como mejor le parezca.

Actualización:

Si por criterios que quiere decir reglas que determinan si y cómo se otorga el distintivo, entonces eso no es algo que debe ser almacenada en la base de datos. Esto sería casi imposible de probar y mantener.

Si usted quiere decir, por ejemplo, almacenando el "número de ediciones", no hay manera de moverse por la modificación de una tabla o un procedimiento almacenado para incluir esos datos si la necesita.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top