4 votes

Conception de base de données - Approche pour stocker des points pour les utilisateurs

Je cherche juste des suggestions sur la manière d'aborder la conception de la base de données pour cela.

Sur mon site, un utilisateur peut gagner des points en effectuant différentes activités. Actuellement, il y a 3 activités pour lesquelles je distribue des points - mais la conception doit être évolutive pour que je puisse ajouter d'autres activités pour attribuer des points également.

Aujourd'hui - l'utilisateur obtient des points 1) Lorsqu'il ajoute un nouveau magasin, il obtient 10 points (les informations du magasin sont stockées dans la table STORE) 2) Lorsqu'il répond à une question, il obtient 7 points (les questions/réponses sont stockées dans la table ANSWERS) 3) Lorsqu'il parraine des amis qui rejoignent le site, il obtient 5 points

Donc voici ce que j'ai jusqu'à présent - mais cela ne semble pas correct :)

Points_Table point_id user_id action (Cela enregistrera pour quelle action les points sont attribués) points

Je devrais être capable de déduire de la base de données que cet utilisateur a obtenu xxxx points pour avoir créé ce magasin ou pour avoir parrainé ces amis ou pour avoir répondu à cette question. La conception ci-dessus ne prend évidemment pas cela en compte.

Merci pour vos conseils

2voto

Kangkan Points 7119

Ajoutez une table qui stocke les actions (tableau générique répertoriant les actions qui pointent vers l'action réelle dans différentes tables) pour lesquelles l'utilisateur obtient des points. La table pourrait ressembler à quelque chose comme Actions_Récompenses (IdAction, TypeAction, Points gagnés) etc. et vous pouvez ajouter différents types d'actions de récompense à travers cela.

2voto

Jeffrey L Whitledge Points 27574

Ne stockez pas du tout les points. Faites simplement des requêtes sur cette vue. De cette façon, elle sera robuste face à des modifications arbitraires.

create view UserPoints
as
select
    created_by_id as user_id,
    'STORE' as action_type,
    store_id as action_id,
    (select points from action_points where action_desc='create store') as points
from store
union
select
    user_id,
    'ANSWER' as action_type,
    question_id as action_id,
    (select points from action_points where action_desc='answer question') as points
from answer
union
select
    referred_by_id as user_id,
    'REFERRAL' as action_type,
    referred_id as action_id,
    (select points from action_points where action_desc='referral') as points
from referral

Edité pour ajouter :

Cela suit les principes normaux de conception de base de données. Toute normalisation de base de données peut se résumer ainsi : ne pas répéter les données.

L'inclusion d'une table de points répète essentiellement des informations que le reste de la base de données contient déjà. Par conséquent, elle devrait être omise. Cela est clair lorsqu'on considère les efforts à fournir pour maintenir la cohérence des données. Sans se soucier des points, si un parrainage est attribué à Alice, mais plus tard il est décidé que Bob devrait recevoir le crédit, cela nécessitera un changement dans un seul champ d'une seule ligne d'une seule table. Si une table de points est incluse, alors elle doit également être mise à jour d'une certaine manière. Si des résumés de points sont stockés, que Dieu ait pitié de votre base de données.

Au lieu de stocker les points, une vue ou une procédure stockée peut être utilisée à la place, et le système de points est ajusté automatiquement lorsque les données changent.

Je pense qu'une vue est préférable à une procédure stockée dans ce cas, car il existe de nombreuses façons dont les données de points peuvent nécessiter une analyse, ce qui offre la plus grande flexibilité et donne à l'optimiseur la meilleure chance d'identifier le chemin optimal.

Vous pouvez sélectionner à partir de la vue par user_id ou par action_type ou faire la somme de la colonne points pour obtenir des totaux pour un utilisateur ou pour tous les utilisateurs. Regardez le plaisir que vous pouvez avoir, et c'est pratiquement gratuit !

select
    sum(up.points) as total_points,
    up.user_id,
    u.user_name
from
    UserPoints up
    join user u on up.user_id = u.user_id
group by
    user_id,
    user_name
order by
    total_points desc

1voto

Wayne Hartman Points 647

Un design typique pour cela consisterait en la table Utilisateur, la table Action et la table User_Action pour enregistrer toutes les actions que l'utilisateur effectue. Vous auriez besoin des deux clés étrangères et probablement une clé primaire, ainsi qu'un horodatage pour quand elles ont été accomplies. Ensuite, vous pourriez stocker les points pour chaque action dans la table Action, et chaque fois que vous recherchez le total des points, il suffit de joindre les tables et de les ordonner par horodatage pour obtenir l'historique de leurs points.

0voto

Jimbolino Points 121

Si vous voulez pouvoir retracer l'action jusqu'à une ligne dans le magasin ou la table des réponses, ajoutez une quatrième colonne, qui est l'entrée pk pour la ligne ajoutée par l'action.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X