web-dev-qa-db-fra.com

Implémentation de commentaires et de goûts dans la base de données

Je suis un développeur de logiciels. J'aime coder, mais je déteste les bases de données ... Actuellement, je crée un site Web sur lequel un utilisateur sera autorisé à marquer une entité comme aimé (comme dans FB), tag et comment comment .

Je suis bloqué sur la conception des tables de base de données pour gérer cette fonctionnalité. La solution est triviale, si nous ne pouvons le faire que pour un type de chose (par exemple, des photos). Mais je dois l'activer pour 5 choses différentes (pour le moment, mais je suppose aussi que ce nombre peut augmenter, tout comme le service dans son ensemble).

J'ai trouvé des questions similaires ici, mais aucune d'entre elles n'a de réponse satisfaisante, alors je pose à nouveau cette question.

La question est de savoir comment bien efficacement et élastiquement concevoir la base de données , de sorte qu'il puisse stocker des commentaires pour différentes tables , aime pour différentes tables et balises pour elles. Certains modèles de design comme réponse seront les meilleurs;)

Description détaillée: J'ai un tableau User avec quelques données utilisateur et 3 autres tables : Photo avec photographies , Articles avec articles , Places avec places . Je souhaite autoriser tout utilisateur connecté à:

  • commenter l'une de ces 3 tables

  • marquer l'un d'eux comme aimé

  • taguer l'un d'eux avec un tag

  • Je veux aussi compter le nombre de goûts pour chaque élément et le nombre de fois où cette balise a été utilisée.

1st approche:

a) Pour les balises , je vais créer un tableau Tag [TagId, tagName, tagCounter], alors je vais créer plusieurs tables de relations pour: Photo_has_tags, Place_has_tag, Article_has_tag.

b) Même chose pour les commentaires.

c) Je vais créer un tableau LikedPhotos [idUser, idPhoto], LikedArticles[idUser, idArticle], LikedPlace [idUser, idPlace]. Le nombre de j'aime sera calculé par requêtes (ce qui, je suppose, est mauvais). Et...

Je n'aime vraiment pas ce dessin pour la dernière partie, ça sent mauvais pour moi;)


2dakota du Nord approche:

Je vais créer un tableau ElementType [idType, TypeName == some table name] qui sera peuplé par l’administrateur (moi) avec les noms de tables pouvant être aimées , commenté ou étiqueté . Ensuite, je vais créer des tables :

une) LikedElement [idLike, idUser, idElementType, idLikedElement] et identique pour les commentaires et les balises avec les colonnes appropriées pour chacun. Maintenant, quand je veux faire une photo aimé, je vais insérer:

typeId = SELECT id FROM ElementType WHERE TypeName == 'Photo'
INSERT (user id, typeId, photoId)

et pour les lieux:

typeId = SELECT id FROM ElementType WHERE TypeName == 'Place'
INSERT (user id, typeId, placeId)

et ainsi de suite ... Je pense que la deuxième approche est meilleure, mais je sens aussi que quelque chose manque dans cette conception aussi ...

Enfin, je me demande également quel est le meilleur endroit pour stocker le nombre de fois où l'élément a été aimé. Je ne peux penser qu'à deux manières:

  1. dans élément (Photo/Article/Place) table
  2. par select count ().

J'espère que mon explication de la question est plus approfondie maintenant.

121
Kokos

La solution la plus extensible consiste à n'avoir qu'une seule table "de base" (connectée à des "j'aime", des balises et des commentaires) et à "en hériter" toutes les autres tables. L'ajout d'un nouveau type d'entité implique simplement l'ajout d'un nouveau tableau "hérité" - il se connecte ensuite automatiquement à l'ensemble, comme/tag/commentaire.

Le terme entité-relation utilisé est "catégorie" (voir le Guide de méthodes ERwin , section: "Relations entre sous-types"). Le symbole de la catégorie est:

Category

En supposant qu'un utilisateur puisse aimer plusieurs entités, une même balise peut être utilisée pour plusieurs entités mais si un commentaire est spécifique à une entité, votre modèle pourrait ressembler à ceci:

ER Diagram


BTW, il y a environ 3 façons d'implémenter la "catégorie ER":

  • Tous les types dans une table.
  • Tous les types de béton dans des tableaux séparés.
  • Tous les types concrets et abstraits dans des tableaux séparés.

À moins d’exigences de performances très strictes, la troisième approche est probablement la meilleure (ce qui signifie que les tables physiques correspondent à 1: 1 aux entités du diagramme ci-dessus).

169

Puisque vous "détestez" les bases de données, pourquoi essayez-vous de les mettre en place? Au lieu de cela, sollicitez l'aide de quelqu'un qui aime et respire ce genre de choses.

Sinon, apprenez à aimer votre base de données. Une base de données bien conçue simplifie la programmation, l’ingénierie du site et facilite son fonctionnement continu. Même un concepteur expérimenté en d/b n'aura pas une vision complète et parfaite: certains changements de schéma seront nécessaires ultérieurement, au fur et à mesure de l'apparition de modèles d'utilisation ou de modifications des exigences.

S'il s'agit d'un projet à une personne, programmez l'interface de base de données en opérations simples à l'aide de procédures stockées: add_user, update_user, add_comment, add_like, upload_photo, list_comments, etc. N'intégrez pas le schéma dans une seule ligne de code. De cette manière, le schéma de base de données peut être modifié sans affecter le code: seules les procédures stockées doivent être renseignées sur le schéma.

Vous devrez peut-être refactoriser le schéma plusieurs fois. C'est normal. Ne vous inquiétez pas pour que tout soit parfait la première fois. Il suffit de le rendre suffisamment fonctionnel pour créer un prototype de conception initiale. Si vous avez le temps, utilisez-en un peu, supprimez le schéma et recommencez. C'est toujours mieux la deuxième fois.

21
wallyk

C’est une idée générale, ne faites pas très attention au style des noms de champs, mais plutôt à la relation et à la structure.

enter image description here

Ce pseudocode obtiendra tous les commentaires de la photo portant l'ID 5
SELECT * FROM actions
WHERE actions.id_Stuff = 5
AND actions.typeStuff = "photo"
AND actions.typeAction = "comment"

Ce pseudocode obtiendra tous les goûts ou les utilisateurs qui ont aimé une photo avec l’ID 5
(vous pouvez utiliser count () pour obtenir le nombre de likes)

SELECT * FROM actions  
WHERE actions.id_Stuff = 5  
AND actions.typeStuff="photo"  
AND actions.typeAction = "like"  
18
user964260

pour autant que je comprends. plusieurs tables sont nécessaires. Il existe de nombreuses relations entre eux.

  • Table qui stocke les données utilisateur telles que nom, prénom, date de naissance avec un champ d'identité.
  • Table qui stocke les types de données. ces types peuvent être des photos, des partages, des liens. chaque type doit avoir une table unique. par conséquent, il existe une relation entre leurs tables individuelles et cette table.
  • chaque type de données a sa table. par exemple, mises à jour de statut, photos, liens.
  • la dernière table concerne plusieurs relations comprenant un identifiant, un identifiant utilisateur, un type de données et un identifiant de données.
0
erencan

Regardez les modèles d'accès dont vous aurez besoin. Est-ce que l'un d'eux semble rendre particulièrement difficile ou inefficace mon choix de conception ou l'autre?

Si non privilégier celui qui nécessite le moins de tables

Dans ce cas:

  1. Ajouter un commentaire: soit vous choisissez une table plusieurs/plusieurs, soit vous l'insérez dans une table commune avec un identifiant spécifique connu de ce qui vous plaît, je pense que le code client sera légèrement plus simple dans votre deuxième cas.
  2. Trouver des commentaires pour item: ici, il semble que l'utilisation d'une table commune soit légèrement plus simple - nous n'avons qu'une seule requête paramétrée par type d'entité
  3. Rechercher les commentaires d'une personne sur un type de problème: une requête simple dans les deux cas
  4. Retrouvez tous les commentaires de personnes à propos de toutes choses: cela semble un peu gnarly de toute façon.

Je pense que votre approche "discriminée", option 2, donne lieu à des requêtes plus simples dans certains cas et ne semble pas beaucoup pire dans les autres, alors j'y vais.

0
djna

Allez certainement à la deuxième approche où vous avez une table et stockez le type d'élément pour chaque ligne, cela vous donnera beaucoup plus de flexibilité. En gros, quand on peut logiquement faire quelque chose avec moins de tables, il vaut presque toujours mieux utiliser moins de tables. Un des avantages qui me vient à l’esprit au sujet de votre cas particulier est que vous souhaitez supprimer tous les éléments appréciés d’un utilisateur donné. Dans le cadre de votre première approche, vous devez émettre une requête pour chaque type d’élément, mais avec la deuxième approche, cela peut être fait. avec une seule requête ou si vous envisagez d'ajouter un nouveau type d'élément, la première approche implique la création d'une nouvelle table pour chaque nouveau type, mais avec la deuxième approche, vous ne devez rien faire ...

0
nobody