1

I'm designing a mongo database and I have a dilemma if I should go for normalization. Let's say that there is a database with images and descriptions. Many alternative descriptions can belong to one image, but only one is assigned as the main one. When I fetch a document for a given Image, I need to have only the main description. Besides that, I need to have some statistics about the description (all of them, not only the main ones), so I will be executing on them some aggregations.

I consider three designs:

  1. To have only one collection called "images" with embedded descriptions. The fetching would be fast and straightforward, but I'm not sure if it is efficient to run aggregates on the nested documents.
  2. Put the descriptions into a separate collection and store the id of the main one in each image document. The data would be normalized and I can run aggregations on the collection, but I also have to do one more query for each image to get the corresponding description.
  3. Combine the two above and store all descriptions in a dedicated collection, but at the same time embed the main one in the corresponding image document.

Thank you for any suggestions.

1 Answer 1

1

What to chose ?

In a document DB you are free to chose the one that best represents your intent:

  1. Choose the embedded description, if you primarily access the objects by image and either frequently need to access multiple descriptions, or, if choosing a main description would in reality be completely arbitrary.
  2. Chose the separate collection, if you often access the images and the descriptions independently, i.e. the description has a value of its own that makes it relevant to search for or to process without necessarily needing the image immediately.
    Also chose this option if descriptions have independent identifies and may be reused in several images.
  3. Choose the embedded main description, ONLY if it corresponds to a reality, for example if the main description is mandatory and special compared to the other descriptions.

Don't feel constraint if there is no need - NoSQL DBs are not SQL DBs

Keep in mind that document databases are designed to address other problems that relational databases. There is no obligation to normalize by putting objects into different tables, if there is not a solid reason.

Normalisation is a technique that is needed for relational databases because:

  1. The columns and rows in a table are "flat". Without normalisation, if you'd group several objects in the same table (e.g. an image and a set of descriptions), it would result in partially redundant rows (e.g. a copy of the image for each separate description). Moreover, there would be ambiguity about what column belongs to what object (more formally, it's expressed in functional dependencies of values). You don't have this constraint with documents and nested objects !
  2. Redundancy is a source of possible inconsistency and overhead. In our previous example, if one of the redundant fields belonging to the image would be different for one line and contradict the others, it would be unclear which is the right value of the image attribute. Moreover if you'd you'd update the image, you'd need to find all the related rows and update
    them all. You don't have this issue with documents and nested objects !
  3. Having different objects decompose into different tables allows to find back very fast linked objects. But you do as well with nested objects if the navigation is mainly from the enclosing objects to the embedded ones. On the other side, the performance argument stays valid in the document world, if you may frequently access the nested objects independently of the nesting objects.
  4. Having different objects in different tables identifies perfectly each object with a primary key and allows to reuse objects without duplication. You don't care about this if the nested object are value objects (because they have no identity that would be independent of the values). But if identify of nested objects matters, especially, if you may need to associate the same nested object to different images, then you need to consider nesting only the ids of objects that are maintained in a separate collection.
2
  • Thanks for the answer. Could you please also clarify the following things: Is there any functionality in MongoDB that allows to "propagate" or join the corresponding document (description) into the main one (image), which stores only its ID (normalization case)? Is it much less efficient to aggregate query nested documents than documents stored in a dedicated collection? Commented Aug 17, 2022 at 10:23
  • @KarolBorkowski In principle, it’s up to you to do the necessary in you code. But there is a shortcut available in the console and query language: stackoverflow.com/q/2350495/3723423
    – Christophe
    Commented Aug 20, 2022 at 12:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.