4

I'm designing a NoSQL database schema - MongoDB in particular - and I'm wondering if it's a good idea not to embed certain one-to-one relationships.

For one example, I have an accounts collection, which stores all the account information. The account balance requires some calculation to compute, and I see two options:

  1. Have a cached_balance field on the accounts collection, which starts off as null. Whenever the balance is recomputed, the field for the relevant account is updated.
  2. Have an account_balances_cache collection with a one-to-one relationship with accounts. Whenever the balance is recomputed, the relevant field in this collection is updated.

The benefit of the embedded document is that I get all the information in one join. A separate collection would require an application-level join which is not as wieldy.

However, the reason I thought of having a separate collection is because I like the conceptual separation of it. There is one collection for all the important data that must not be lost, and there's another with data that could be recomputed at any time, where the entire collection could be dropped and nothing of ultimate value will have been lost. Or it could even be in another database which could be kept on a different server, etc. Is this sound reasoning or am I just making it unnecessarily difficult for myself?

(Note that this is a simplified example. In actuality the things in these caches may be hard/computationally expensive to compute, which is why I'm putting them in the database as well instead of something like redis or memcached.)

2
  • Your answer will be mongodb specific, there is no answer in general for NoSQL databases because it covers a too wide range of databases.
    – Pieter B
    Mar 16, 2016 at 10:15
  • @PieterB: Ah I was wondering if it would be. Thanks, updated the question.
    – Claudiu
    Mar 16, 2016 at 14:03

2 Answers 2

3

Specifically, if you're using MongoDB, then in my view you should really be storing the cached value in the account collection in the document, and not in a separate collection. The reason is that MongoDB only guarantees atomicity on the writes on a per-document basis. So you would have no way of avoiding potential cached values being out of sync with the actual account balance if you spread it over two collections.

1

Option 1 makes sense because that's the edge you get from the document/key-value stores. There is suggestion in it though:

  1. Instead of creating it with null value create it on the go as on when required.
  2. add/update the respective field in document which internally holds the document comprises of several fields you plan to create in account_balance_cache.
  3. You can filter on account collection to retrieve on balances by account etc.
  4. For the expensive calculation I don't see any issues because cache_balance is document inside account creation which holds several accounts as document.

Sample account collection represents account doc:

[{
    accid:x, 
    name:y, 
    cache_balance:[{ #fields for balances}] 
}, 
{}] 

In option 2, you are going towards normalization, and if it's a normalization then why document store?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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