9
votes

Stocke des chiffres d'enregistrement de base de données redondant?

J'utilise des rails et MySQL, et j'ai une question d'efficacité basée sur le comptage de la ligne.

j'ai un projet modèle que has_many: dons .

Je veux compter le nombre de donateurs uniques pour un projet.

a un champ dans la table appelé num_donors et l'incrémentation quand un nouveau donneur est créé une bonne idée?

ou est quelque chose comme @num_donors = donor.count (: select => 'user_id distinct') va être similaire ou identique en termes d'efficacité grâce à l'optimisation de la base de données? Cela vous obligera-t-il à créer des index pour user_id et de tout autre champs que je veux compter?

La même réponse porte-t-elle pour résumer la quantité totale donnée?


0 commentaires

5 Réponses :


8
votes

Bien que cela dépend de la taille de votre base de données, ce sont les types d'opérations que les bases de données se spécialisent afin de pouvoir être rapides. C'est probablement un cas d'optimisation prématurée ici - vous devez commencer par ne pas stocker les totaux, ce qui le rend plus simple - et optimiser ultérieurement si nécessaire.


0 commentaires

16
votes

Pour répondre à la question du titre. Oui, il est redondant, mais si vous devriez le faire dépend de votre situation.

sauf si vous avez connu des problèmes de performance, calculez les comptes et les totaux à la volée de votre application et ne les stockez pas. Autrement dit, ne stockez pas les valeurs calculées à moins que vous n'ayez aucun autre choix.

Dans la plupart des situations, vous n'aurez pas à recourir à cela et ne devrait pas.

Si vous devez stocker des valeurs calculées, procédez comme suit:

  • Ne le garde pas à jour en l'incrémentant. Recalculez le nombre / total de toutes les données à chaque fois que vous le mettez à la mettre à jour.
  • Si vous n'avez pas beaucoup de mises à jour, mettre le code dans un déclencheur de mise à jour à Gardez le comte / totaux à jour.
  • le problème avec la redondance dans bases de données est que lorsque les chiffres pas d'accord, vous n'êtes pas sûr de ce qui est autorité. Ajouter à la Documentation Une note que la source Les données sont la source faisant autorité si ils sont en désaccord et peuvent être écrasés.

1 commentaires

+1 pour ne pas essayer d'augmenter / décrémenter. S'il y a un certain niveau de complexité au comptage, cela vous évitera un mal de tête.



4
votes

Les réponses de Peter's et Johnfx sont sonores, ce que vous proposez est le dénormalisation de votre Schema de base de données, qui peut améliorer les performances de lecture, mais au détriment des écritures tout en mettant en outre la limite de l'ONUS sur le développeur (ou des cigests SDBM supplémentaires) afin d'empêcher les incohérences dans votre ensemble de données.

ActionCord a une fonctionnalité intégrée pour gérer automatiquement les comptes sur has_many relations. Consultez ce Railscast sur Counter Caches .


0 commentaires

7
votes

N'oubliez pas que la maxime "Un homme avec une montre sait toujours l'heure. Un homme avec deux montres n'est jamais sûr." Je ne stockerais que le nombre dérivé si:

Les problèmes de performance vous empêchent d'obtenir les numéros dérivés lorsque vous en avez besoin (ce qui ne devrait pas être un problème dans ce cas car la réponse est susceptible d'être disponible dans les index)

ou

Vous avez des raisons de croire que vous perdez des enregistrements de la table principale via une erreur de programmation ou une action d'utilisateur délibérée ou accidentelle. Dans ce cas, vous pouvez utiliser votre numéro dérivé pour vérifier le numéro actuellement calculé.


2 commentaires

J'adore la maxime - je ne l'ai pas entendu auparavant. Gardera à l'esprit :)


J'aime la citation, ça m'a vraiment aidé



3
votes

Savez-vous qu'un drapeau simple fait l'activeCord Magic?

class ThingOwner

# it has a column like
# t.integer things_count, :default => 0

has_many :things, :counter_cache => true

end


0 commentaires