Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MongoDB schema for reservations, nested or referenced?

I'm designing my first database for MongoDB, I'm wondering if I'm going in a right direction about it.

It's basically a mock reservation system for a theatre. Is there anything inherently wrong about going 2 or 3 levels deep with nesting?

Will it create problems with queries later on?

What would be performance and usability wise the best solution here?

Should I perhaps use references like i did with clients that made reservations?

Here is what I have so far:

//shows

    {
       _id: 2132131,
       name: 'something',
       screenplay: ['author1', 'author2'],
       show_type: 'children',
       plays:  {
                  datetime: "O0:00:00 0000-00-00",
                  price: 120,
                  seats: 
                          {
                            _id:['a', 1],
                            status: 'reserved',
                            client: 1
                          },

                          {
                            _id:['a', 2],
                            status: 'reserved',
                            'client:1
                          }
                }
    }



//clients

    {
      _id:1,
      name: 'Julius Cesar',
      email: '[email protected]',
    }
like image 578
Matija Milković Avatar asked Feb 13 '23 08:02

Matija Milković


2 Answers

You might hear different opinions on this one but let me share my views on this with you.

First of all, your schema does not seem correct for your usecase. You most likely want "plays" to be an array rather than an object, so :

{  
   "_id":2132131,
   "name":"something",
   "screenplay":[  
      "author1",
      "author2"
   ],
   "show_type":"children",
   "plays":[  
      {  
         "datetime":"O0:00:00 0000-00-00",
         "price":120,
         "seats":[  
            {  
               "_id":[  
                  "a",
                  1
               ],
               "status":"reserved",
               "client":1
            },
            {  
               "_id":[  
                  "a",
                  2
               ],
               "status":"reserved",
               "client":1
            }
         ]
      }
   ]
}

If my assumption is correct you now have double nested arrays which is an extremely impractical schema since you cannot use more than one positional operator in a query or update.

Despite what most of the NoSQL crowd seems to think there are actually only a few valid use-cases to embed collections into a document. The following conditions need to be met :

  • The embedded collection has very clear upper limits in terms of size. This limit should not be higher than a couple of dozen before this becomes unwieldy/inefficient.
  • The embedded collection should not grow regularly (this causes the document to move around on disk which dramatically reduces performance)
  • The elements in the embedded collection should not contain array attributes (the current query language does not allow you to modify specific elements of a double nested array)
  • You should never require the elements of the nested collection without having to query the root document that contains that embedded collection.

You'll find that not that many situations will meet all the criteria above. Some of those criteria are somewhat subjective but lightweight referencing is not actually that more complicated. Actually, not being able to "atomically" modify documents in different collections is the only complication and you'll find and that isn't as big a problem as it sounds in most cases.

TL;DR : Don't double nest arrays; stick "plays" in a seperate collection

like image 76
Remon van Vliet Avatar answered Feb 24 '23 03:02

Remon van Vliet


Usually you should always prefer embedding over referencing in MongoDB, so you are already heading into the right direction.

The only reason to use referencing for a 1:n relation is when you have growing objects, because an update which causes a document to grow in size can be slow. However, it seems like you are working with data which isn't going to grow very frequently (maybe a few times a day), which likely means that you shouldn't run into performance problems.

like image 33
Philipp Avatar answered Feb 24 '23 03:02

Philipp