2010-06-19 9 views
3

J'ai deux tables appelées (Up | Down) Vote, vous pouvez faire BOTH upvote et downvote, donc ce n'est pas une table avec un bool. Les gens ont suggéré que je devrais utiliser une table appelée votes et avoir un champ appelé type.Pourquoi devrais-je utiliser 1 table au lieu de deux?

Pourquoi devrais-je faire cela? Je pense que l'écriture du nom unique de la table est plus facile que d'écrire Vote puis l'instruction supplémentaire where (type & upOrDownTypeBit) <>0.

NOTE: (Vers le haut | bas) table de vote est PK id, FK userId

+0

Je ferais: PK ID, FK utilisateur, Vote BIT (où 1 est en hausse de vote et 0 est en baisse de vote) – BrunoLM

+0

@BrunoLM: Vous êtes autorisé à faire les deux, c'est le catch. –

+0

Eh bien, vous ne devriez pas le faire dans deux tables, IMO c'est juste inutile et ne ferait qu'accumuler le même type de données à différents endroits, je ne vois pas comment cela pourrait être utile du tout. – BrunoLM

Répondre

2

Une personne peut-elle avoir à la fois un UPvote et un DOWNvote? Si non, alors deux tables n'a pas de sens. En outre, vous devez écrire deux requêtes pour supprimer un vote; un pour chaque table. Cela vaut-il toujours la peine?

+0

Je ne comprends pas très bien comment cela peut être la réponse acceptée, quand OP a spécifiquement dit qu'une personne pouvait faire des votes à la hausse comme à la baisse, mais je suppose que c'est la vie. Je suis d'accord avec la réponse que deux tables est moins préférable, mais je suis confus néanmoins. – MJB

+1

Pour être honnête, je ne suis pas sûr que quiconque (y compris moi-même) a entièrement compris la question dans son intégralité. C'est un peu ambigu. Si cela a répondu à la question de l'opération, eh bien, je ne sais pas quoi dire. –

+1

Pas comme si je vous en tiendrais rigueur ou que vous m'en voudriez; ça semblait juste étrange. – MJB

3

Une chose utile que vous pourriez faire en fusionnant cela en une seule table est de trouver rapidement le vote net global en affectant 1 dans une colonne delta pour la table pour un upvote et -1 dans la colonne delta pour un downvote.

Ensuite, vous pouvez aller

SELECT SUM(delta) FROM votes WHERE id = ?

0

Si la performance est une préoccupation du tout, alors il serait plus rapide à la liste à partir d'une seule table au lieu d'une jointure ou une union sur deux tables. Peut-être que je ne comprends pas ce que vous faites, mais avez-vous une autre clé étrangère concernant l'objet qui est voté? Ou les utilisateurs sont-ils votés?

Dans les deux cas, il serait plus facile et plus efficace d'agréger sur une seule table, par exemple si vous vouliez Sum() les upvotes ou les downvotes. Vous devriez probablement faire 1 et -1 dans le champ de vote pour cela.

0

Votre approche offrira une certaine facilité d'utilisation lors de la lecture des données. Une table unique fournirait la facilité d'utilisation lors de l'écriture des données. Avec deux tables, vous devez vérifier la valeur avant de décider à quelle table écrire. Avec une seule table, vous écrivez à la table sans même savoir ou prendre soin du contenu des variables. Je pense que c'est une façon plus normale de faire les choses, surtout quand elle est étendue au-delà de cet exemple unique. Pour autoriser à la fois les votes Up et Down, vous pouvez avoir une colonne booléenne pour chacun d'entre eux.

0

Faites ce qui est le plus logique dans le contexte de votre application. Gardez à l'esprit quels systèmes vont consommer les données, et assurez-vous que ce que vous implémentez est logique pour ces systèmes. Considérez également le coût de changer les tables si un jour vous découvrez que vous en avez besoin (cela aura tendance à augmenter s'il y a plusieurs applications utilisant les données). Mais l'essentiel, c'est que ce sont vos données, représentez-le de la manière qui rend les choses les plus faciles pour vous.

0

En fait, cela dépend de votre volume de données et de ce que vous allez faire de vos données. Si vous n'avez pas de raison particulière d'utiliser deux tables, utilisez une table. Comme une table peut fournir toutes les fonctions que vous avez avec deux tables, et il est plus simple et plus facile dans certains scénarios: Changer un vote up vers le bas vote; somme tous les votes, etc.

5

Pour la modélisation de données, il est généralement important de savoir ce que les choses signifient.

Est-ce qu'un vote up ET un vote négatif sur la même chose par la même personne sont les mêmes que l'absence de vote du tout par une personne sur une chose?

Dans tous les cas, il est certainement possible (avec une indexation appropriée pour les performances) de l'avoir dans une seule table pour faciliter la gestion. En plus de cette table de base, vous pouvez ajouter des vues UpVote et DownVote.Ou vous pouvez aller dans l'autre sens et avoir deux tables de base avec une seule vue Votes pour plus de commodité.

Généralement, avoir deux tables signifie maintenant deux ensembles d'intégrité référentielle, deux schémas de table semi-identiques à maintenir, et une vue pas tout à fait unifiée des données. Cela signifie également que vous devrez avoir deux plans d'archivage et/ou de partitionnement pour gérer l'historique, etc.

Cela ne veut pas dire que c'est faux, mais si les entités sont très similaires, les modéliser dans une seule table fait souvent beaucoup de sens.

Parfois, les entités peuvent sembler similaires, mais en réalité, elles ne le sont pas vraiment et elles devraient être modélisées dans des tables séparées. Citations, bons de commande et factures me viennent à l'esprit ici. Beaucoup de gens aiment mettre deux ou plusieurs de ces choses dans la même table, et c'est vraiment une mauvaise idée.

3

DRY. Un inconvénient d'avoir deux tables est que tout code traitant des votes devra probablement être répété. Cela peut inclure la duplication de toute contrainte et autre logique dans la base de données. Il existe un principe de conception de base de données relationnelle qui affirme que vous devez éviter de répéter les mêmes données dans plusieurs tables: The Principle of Orthogonal Design.

4

Pourquoi ne pas en faire un INT? Je soupçonne fortement qu'une donnée BIT prend tout autant d'espace qu'une INT en raison du rembourrage et autres. Avec un INT, vous pourriez avoir:

-1: downvote 
    0: neutral vote (might not be used) 
    1: upvote 
NULL: no vote 

Et votre voix table peut être:

create table votes (
    post INT, 
    user INT, 
    vote INT 
); 

Le tableau des votes devrait avoir les clés étrangères pour la poste et l'utilisateur ainsi qu'un index sur (poste, user), mais je ne connais pas la syntaxe de MySQL.

Questions connexes