MongoDB
 sql >> Base de données >  >> NoSQL >> MongoDB

Un moyen efficace de stocker des données dans MongoDB :documents intégrés vs documents individuels

Il serait préférable d'utiliser la première approche (documents individuels) et d'utiliser une collection plafonnée si possible, car vous ne voulez pas avoir une collection en croissance rapide (mongoid prendra en charge les collections plafonnées en 2.2, qui sortira ce week-end, je devinez).

La deuxième approche (documents intégrés), vous devrez d'abord récupérer le document racine pour l'utilisateur, puis parcourir le tableau dans l'application pour trouver l'activité liée à la publication que vous recherchez. Mongoid peut donner l'impression que tout est fait dans la base de données en raison de la similitude de la syntaxe dans la recherche d'un document intégré, mais il itère vraiment le tableau.

Comme vous avez déjà le user_id, activity_id et activity_type avant de faire une requête, et que vous ne voudriez pas que la liste complète des activités de l'utilisateur soit récupérée à partir de la base de données lorsque vous recherchez une activité particulière, je préférerai le premier cas. Il y aurait beaucoup moins de calculs (recherches) dans l'application et il y aurait beaucoup moins de trafic réseau.

Avec l'approche des documents individuels, ce serait formidable si vous créiez également un index unique sur user_id, activity_id, activity_type. Cela vous aidera à contenir le nombre de documents. Vous pouvez avoir la validation de l'unicité (requête supplémentaire), mais ce serait généralement inutile si vous avez l'index unique. Le seul avantage de la validation sera une erreur de validation s'il y a des doublons, mais l'index ignorera silencieusement les entrées en double à moins que vous ne persistiez en mode sans échec.

Si vous souhaitez également que l'activité historique du site soit conservée, vous pouvez avoir la structure suivante :

class SiteActivity
  include Mongoid::Document
  include Mongoid::Timestamps
  belongs_to :user
  belongs_to :activity, polymorphic: true

  index [:user_id, :activity_id, :activity_type], :background => true, :unique => true

  field :last_access_time, :type => Time
  # last_access_times just here for history, not used
  field :last_access_times, :type => Array, :default => []
end

activity = SiteActivity.find_or_initialize_by(:user_id => current_user.id,
               :activity_id => post.id, :activity_type => post.class)
time = Time.now.utc
activity.last_access_time = time
activity.last_access_times << time
activity.save