2010-09-14 6 views
2

Il existe des produits avec un nom et un prix.Comment modéliserais-tu ceci dans MongoDB?

Les utilisateurs se connectent sur les produits qu'ils ont achetés.

# option 1: embed logs 
product = { id, name, price } 
user = { id, 
     name, 
     logs : [{ product_id_1, quantity, datetime, comment }, 
       { product_id_2, quantity, datetime, comment }, 
       ... , 
       { product_id_n, quantity, datetime, comment }] 
} 

J'aime ça. Mais si les ID de produit ont une longueur de 12 octets, la quantité et le datetime sont des entiers de 32 bits (4 octets) et des commentaires de 100 octets en moyenne, alors la taille d'un journal est 12 + 4 + 4 + 100 = 120 octets. La taille maximale d'un document est de 4 Mo. La quantité maximale de journaux par utilisateur est donc de 4 Mo/120 octets = 33 333. Si l'on suppose qu'un utilisateur enregistre 10 achats par jour, la limite de 4 Mo est atteinte en 33 333/10 = 3 333 jours ~ 9 ans. Eh bien, 9 ans c'est probablement bien, mais si nous avions besoin de stocker encore plus de données? Que faire si l'utilisateur enregistre 100 achats par jour?

Quelle est l'autre option ici? Dois-je normaliser cela complètement?

# option 2: normalized 
product = { id, name, price } 
log = { id, user_id, product_id, quantity, datetime, comment } 
user = { id, name } 

Meh. Nous sommes de retour à relationnel.

+0

Pourquoi avez-vous besoin de 12 octets pour un ID de produit? Peut-être que vous pouvez utiliser une séquence de 32 bits (ou moins)? – diederikh

+0

Vous pouvez également déplacer les commentaires vers une collection distincte et référencer les commentaires par ID. – diederikh

+0

Oh, gentil .. alors générez manuellement les identifiants en auto-incrémentant? Où stockez-vous la dernière valeur d'ID affectée? – randomguy

Répondre

0

Oui, l'option 2 est votre meilleur pari. Oui, vous êtes de retour à un modèle relationnel, mais alors, vos données sont mieux modélisées de cette façon. Je ne vois pas d'inconvénient particulier à l'option 2, c'est-à-dire vos données qui vous obligent à passer par là, pas un mauvais processus de conception.

3

si la taille est la principale préoccupation, vous pouvez aller de l'avant avec l'option 2 avec mongo DbRef.

 logs : [{ product_id_1, quantity, datetime, comment }, 
      { product_id_2, quantity, datetime, comment }, 
      ... , 
      { product_id_n, quantity, datetime, comment }] 

et intégrer ces journaux à l'intérieur utilisateur à l'aide Dbref, quelque chose comme

 var log = {product_id: "xxx", quantity:"2", comment:"something"} 
     db.logs.save(log) 
     var user= { id:"xx" name : 'Joe', logs : [ new DBRef('logs ', log._id) ] } 
     db.users.save(user)