web-dev-qa-db-fra.com

Aime ou vote pour les messages

Je fais un petit programme où les utilisateurs font des publications ou écrivent des blogs. Sur ces publications, les autres utilisateurs peuvent aimer ou ne pas aimer la publication comme dans Facebook ou voter positivement ou défavorablement la publication comme dans stackoverflow. Je voudrais connaître une bonne structure de base de données qui est couramment utilisée et le programme fonctionne efficacement avec cette structure. J'ai deux options

Premier

Publier:

id   head   message   datepost   likes   dislikes
1     ab    anchdg     DATE      1,2,3   7,55,44,3

De la manière ci-dessus, id est le postid. Dans la colonne J'aime, 1,2,3 est l'identifiant de l'utilisateur qui a aimé ou voté pour le message ou le blog. 7,55,44,3 est l'identifiant des utilisateurs qui n'ont pas aimé ou ont voté contre le message ou le blog.

Deuxième

Publier:

id    head  message   datepost
1     ab    anchdg     DATE

Aime:

id    postid    userid
1       1         1
2       2         2

N'aime pas:

id    postid    userid
1       1         7
2       1         55

De cette façon, je dois créer deux tableaux séparés pour les likes et les likes pour obtenir les likes de la publication. De cette façon, les tables, c'est-à-dire Likes & Dislikes, seront fortement remplies. Cela pourrait rendre la table lourde et le traitement lent.

Donc, je voudrais savoir quelle est la meilleure façon et la meilleure façon d'accomplir cette tâche?

10
Harshit Shrivastava

Le problème que vous rencontrez est connu sous le nom de "formes normales" de bases de données, en particulier la première forme normale. https://en.wikipedia.org/wiki/First_normal_form .

Votre base de données avec les ID utilisateur concaténés (première version) n'est pas sous sa première forme normale.

Voir https://en.wikipedia.org/wiki/Database_normalization pour savoir pourquoi et comment la normalisation est généralement considérée comme bonne.

Dans votre premier exemple, la requête pour "l'utilisateur 4 n'aime plus la publication" devient compliquée. Il devra effectuer des opérations de chaîne, qui devront prendre en compte les effets secondaires et les cas d'angle (l'utilisateur est le seul utilisateur "aimant", l'utilisateur est le dernier utilisateur aimant, l'utilisateur est au milieu de la chaîne utilisateur aimante). Je trouverais ça mauvais. Ne le fais pas. Utilisez une conception normalisée.

re: la base de données devient lourde

Si vous avez une publication qui a 4 millions de likes, dans la conception de la base de données 1, vous auriez une ligne avec une colonne "likes" d'au moins 4 millions de caractères (car vous aurez besoin de la virgule comme caractères séparateurs). Vous devrez ensuite effectuer des opérations de chaîne sur des chaînes de quatre millions de chiffres. C'est très peu performant et lent.

D'un autre côté, les bases de données sont conçues pour gérer des millions de lignes. Nous avons des bases de données avec plusieurs centaines de millions de lignes et count () - les opérations sont rapides. Extrêmement vite. Donc non, ce ne sera pas un goulot d'étranglement en termes de performances.

Le prochain problème serait la lisibilité et la maintenabilité.

Par exemple, dites-moi ce que font ces 2 déclarations:

select count(*)
from posts
inner join likes on posts.postid = likes.postid
where postid = 7

select len(likes) - len(replace(likes, ',', ''))
from posts
where postid = 7
20
til_b

La deuxième façon est bien meilleure, car vous pouvez facilement ajouter ou supprimer un J'aime/Je n'aime pas.

Mais vous devez modifier votre deuxième solution en utilisant une table pour aimer ou ne pas aimer.
Les colonnes de la table like/dislike doivent être id, postid, userid et une autre pour la valeur de like ou dislike, par ex. 1 pour ne pas aimer et -1 pour aimer.

Définissez post_id et user_id comme clé primaire composite et cela fonctionne très bien.

La taille de la table augmentera avec le temps. mais vous ne disposez que de deux colonnes réelles. L'identifiant et la valeur de ce qui est/n'aime pas. Le postid et l'ID utilisateur ne sont liés qu'à lui et stockés dans votre table d'utilisateur et de publication.

9
Julian S