Banco de dados Architecture for Critérios “Badge” Sistema e arbitrárias (MySQL / PHP)

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

  •  20-08-2019
  •  | 
  •  

Pergunta

Quickie-Pergunta:

Para resumir, eu estou um pouco confuso a respeito de como eu iria criar uma tal base de dados que permite a criação indefinida badge-regra sem a necessidade de mudanças estruturais para a facilidade de tabelas previamente existentes no banco de dados.

Armazenamento emblema Título, critérios, etc. Qual seria a aparência da tabela como?

  • badge_id (1)
  • badge_title (10K emblema)
  • badge_image (10k.jpg)
  • badge_criteria ([mensagens]> = 10000)
    ...

Winded-Pergunta:

Eu gostaria de implementar um sistema de crachá em meus próprios projetos pessoais, mas estou procurando um pouco de conselhos sobre como seria melhor fazer uma coisa dessas. Estive lendo algumas das perguntas aqui sobre Badge-sistemas, mas não vê o banco de dados arquitetura recebendo muita atenção.

Emblemas que são baseados em usuário-pontos (hipotético "Distintivo 10k") parece bastante simples. Qualquer evento que afeta a reputação usuários (upvotes, downvotes, a resposta aceita, etc) iria chamar um método para analisar a utilizadores nova reputação, e potencialmente conceder um distintivo.

Isso soa sistema bastante simples, mas o que isso parece como um banco de dados para o administrador que quer criar inúmeras quantidades de emblemas com pouco esforço no caminho - alguns dos quais podem ser baseadas em critérios diferentes, não e simplesmente o usuário reputação.

User-reputação é provavelmente um valor dentro do próprio utilizador-registro. Mas o ideal é que você não quer para evitar ter de adicionar novos campos para a tabela do usuário quando você criar novos emblemas? Por exemplo, a "Editado 100 entradas" badge - você não iria criar uma nova coluna "entries_edited" dentro dos usuários da tabela, não é? E então incrementar que após cada entrada editado ...

Alguma dica?

Stackoverflow Archive:


Nota: Eu não estou perguntando como emblemas associados com os usuários. Eu não estou pedindo como emblemas concessão (que será feito por meio de programação)

Foi útil?

Solução

Uma vez que os critérios de crachá podem ser arbitrariamente complexo, eu não acho que você pode armazená-lo em uma tabela de banco de dados dividido em "simples" elementos de dados. Tentando escrever um "mecanismo de regras" que pode lidar arbitrariamente critérios complexos vai levar você para baixo o caminho da basicamente re-escrever todas as ferramentas que você tem em sua linguagem de programação.

Se você sabe de antemão que você quer os crachás limitada a apenas determinados campos (ou seja, emblemas são apenas baseado fora reputação ou número de edições ou algo assim), então você pode armazenar os em uma tabela simples como:

ReputationBadgeCriteria
  BadgeId
  BadgeName
  MinReputation

Como alternativa, você poderia usar algum tipo de DSL para escrever suas "regras", mas você acaba tendo também criar um analisador para analisar as regras quando você lê-los, bem como algo para executar essas regras. Dependendo da complexidade que você quer em sua DSL, isso pode não ser uma tarefa trivial. Este parece ser o caminho que você está indo na sua pergunta com ter uma coluna Critérios (texto presumivelmente simples) que tem algo como "[Reputação]> 1000" ou "[mensagens]> 5" nele. Você ainda tem que analisar e executar essas regras e a complexidade de escrever algo para fazê-lo depende de quão complexo você quer essas regras para ser.

Eu recomendo que você leia estes diário WTF artigos para informações sobre por que esta abordagem leva à dor.

Outras dicas

Dependendo de quão longe você quer ir com ele, o esquema pode ficar muito complicado. Parece-me que os elementos básicos que você precisa para pista são:

Badges awarded
Points earned

simples Bonita até agora, mas você quer ser capaz de criar dinamicamente novas emblemas e novas categorias de pontos. prêmios emblema dependeria de ganhar pontos em uma ou mais categorias de ponto que se somam a um determinado montante. Então, você precisa controlar a relação entre categorias pontuais (e pontos ganhos) e emblemas:

Point categories
Badge categories

Portanto, a chave seria sua mesa de pontos do usuário, que ligaria a categorias pontuais, que apontam para emblemas. Os usuários ganham pontos em uma categoria particular, o que contribuiria para ganhar pontos para um ou mais emblemas.

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)
...

O seu interface de "admin" permitiria que alguém para criar um novo emblema e escolher quais as categorias ponto são obrigados a ganhar o distintivo (point_groups). Sempre que um usuário ganha pontos (user_points), você atualizar a tabela de user_points, em seguida, determinar qual emblemas aqueles pontos que poderiam contribuir para (point_groups). Você, então, recompilar os pontos para os emblemas que foram afetados pelos pontos ganhos e atualizar a tabela de user_badges com o point_earned. Em seguida, verifique o campo points_earned em user_badges contra os required_points na tabela de crachás.

Você pode obter muito amador, atribuindo pesos diferentes a diferentes categorias de ponto, ou mesmo pesos diferentes para categorias de ponto para emblemas particulares. Mas essa configuração permitirá que uma quantidade ilimitada de emblemas e categorias de pontos a serem criados e geridos facilmente sem alterar estruturas de tabelas.

Se isso não o que você está procurando é completamente, então eu acho que deveria, pelo menos, obter um voto ou dois para um monte de digitação.

Você iria acompanhar os seus utilizadores únicos em uma tabela e emblemas únicos em outro, em seguida, criar uma tabela de referência cruzada para relacioná-los.

Um usuário pode ter muitos emblemas e um distintivo pode ter muitos usuários.

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
)

Estatísticas que podem afetar se um usuário ganha um crachá são rastreadas como parte da administração do site. assim algo como uma resposta a ser aceites estaria em um esquema que relaciona perguntas e respostas. a fim de exibir a resposta eo proprietário da resposta, haveria uma relação com a tabela de usuário e gatilhos que iria verificar se há condições de crachá sempre que uma alteração foi feita.

Eu não estou pedindo como emblemas de adjudicação. Estou perguntando como armazenar critérios dentro do banco de dados.

Então você deseja armazenar a operação lógica necessária para determinar se um crachá é ganho em um algum lugar campo?

Eu acho que concordar com o outro cartaz que critérios devem ser uma parte da lógica de negócios. Essa lógica pode ser no lado do aplicativo ou dentro de um gatilho. Eu acho que é uma questão de estilo.

Se você estava realmente casado com a idéia de armazenar os critérios em um campo, eu armazená-lo como SQL parametrizado e executá-lo de forma dinâmica.

Portanto, este tipo de coisa seria de seu campo de critérios:

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

Eu não criar um incremento para o crachá de edição. Eu acho que você deve ter um trabalho em execução em segundo plano e count () do numbero de post editado para membros que não têm o emblema de editar ainda. Quando você vê que a contagem é sobre o intervalo que deseja, você adiciona uma entrada no banco de dados que dizer que o usuário tem o distintivo.

Eu acho que é sobre o mesmo para outros emblemas. Tente limitar o número de escrita e não escrever diretamente a contagem das informações crachá na tabela do usuário. Use uma tabela que conterá informações crachá e vinculá-lo à mesa do usuário.

Peço desculpas por ser breve.

Para implementar um sistema como este, eu poderia criar uma tabela que armazena armazenado nomes de procedimentos ou consultas reais que seriam utilizados para determinar se um determinado usuário ganhou um distintivo.

badge_criteria
badge_key int
badge_criteria varchar(max)

Você pode extrair e executar as consultas para emblemas que o usuário não ganhou de sua camada intermediária, mas você não teria que fazer qualquer código ou mudanças estruturais para adicionar novos emblemas daqui para frente.

Estou me aproximando-o assim: Criar uma tabela para armazenar todos os emblemas, e ter uma referência de coluna uma função que é executado para ver se o emblema é concedido. Dessa forma, a tabela permanece simples e lógica para determinar os crachás podem ser mantidos no código, onde ela é mais adequada.

Com este método, os requisitos crachá poderia também ser ligados entre si, para formar dependências mais complexos. Por exemplo, o usuário deve receber três, emblemas específicos separados w / em um determinado período de tempo a fim de obter este emblema.

Este vai ser quase impossível de fazer no banco de dados - emblemas adjudicação deve ser feito em sua lógica de negócio dentro do aplicativo. Dessa forma, você tem todos os dados existentes que você precisa (edições, visitas, reputação, etc.) e pode ser tratada como você vê o ajuste.

Update:

Se por critérios regras significam que determinam se e como o emblema é concedido, então isso não é algo que deve ser armazenado no banco de dados. Isso seria quase impossível de testar e manter.

Se você quer dizer, por exemplo, armazenando o "número de edições", não há nenhuma maneira se locomover modificar uma tabela ou procedimento armazenado para incluir esses dados se você precisar dele.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top