Choosing the perfect NoSQL database (part 2)

This article is the second part of the series Creating the modern developer stack template. I definitely recommend reading the first one before this to get more context.

Introduction

Hello folks,

Let's start with the piece of the stack that is sitting all the way back, the database. There exist two primary types of database, SQL and NoSQL. For each of those types, there are dozens of different alternatives. To cut down my research in more than half, I will solely focus on databases from the NoSQL family. As mentioned in the first article, I will only investigate open source databases. I will be looking for ease of use; so how easy it is to get started with this database and the quality of the documentation. Popularity is another big factor that goes hands down with the ease of use as you will be able to find solutions to all the common problems a newbie can have. Performance is also something to keep in mind. Still, it will have lesser importance than the 2 previous points as I believe most databases nowadays will provide decent enough performance for most of the use cases. Thus, you don't want to sacrifice development speed for your database's very marginal performance gain.

Comparisons

MongoDB

Pros:

  • Easy to set up with adequate support in node
  • Advanced query language supported in the form of JSON
  • Easy to scale
  • Amazing documentation
  • Wide community support
  • Compound indexes
  • Transaction support

Cons:

  • Data size because each document store every field names
  • Joining collections together is tedious

rxdb

Pros:

  • Good documentation
  • Uses CouchDB under the hood
  • Subscription to events (real-time)
  • Offline support

Cons:

  • Not used in many projects
  • Doesn't provide enterprise-grade support
  • Was created only four years ago (2016)

Arangodb

Pros:

  • Uses SQL like query language
  • Can store multi-model documents, graphs, key-value
  • Supports elastic scalability
  • Very fast

Cons:

  • Not used in many projects
  • Has a high memory usage

Neo4j

Pros:

  • Very fast for handling relationships as it is a graph database
  • Supports ACID transactions

Cons:

  • Hard to follow the documentation
  • You need to define schemas of your data at the database level
  • The javascript driver only has one year of life (2019)

There exist, of course, many other databases in the NoSQL realm, although I can't cover them all. I've selected these databases based on this query on GitHub, and I chose the top 4. After identifying some pros and cons, I noticed that each database has different use cases in mind. If you want a real-time database, use rxdb, for complex relationships: Neo4j, general-purpose with broad community support: MongoDB and the one that tries to mix the capabilities of both MongoDB and Neo4j, go with ArangoDB. Since I'm trying to build a general-purpose template, I think going with the database that has the most significant community will alleviate some of the missing features it might miss through community projects.

Implementation in Stator

I'm a massive advocate of monorepos, but one of the most commonly cited critics of them is the build time and testing time, which gets annihilated by NX. NX uses an intelligent build system with distributed caching to solve those issues. It also allows you to generate pre-configured projects to add missing pieces to your stack easily.

Enough said about monorepos, let's get back to our database. To ensure ease of use, let's create a docker-compose.yml file:

version: '3.6'
services:
  database:
    image: mongo:4.2.3-bionic
    container_name: stator-mongo
    ports:
      - 27017:27017
    environment:
      - MONGO_INITDB_DATABASE=stator
      - MONGO_INITDB_ROOT_USERNAME=admin
      - MONGO_INITDB_ROOT_PASSWORD=admin
    volumes:
      # seeding scripts (optional)
      - ./mongo-entrypoint:/docker-entrypoint-initdb.d
      # named volumes
      - mongodb:/data/db
      - mongoconfig:/data/configdb

volumes:
  mongodb:
  mongoconfig:

Using docker-compose up, we can easily launch our database. One advantage of using docker is that we ensure all the developers working on the project will be using the same version. Running this command will launch your mongo database seeded with a user [stator] with password [secret], which you can use to connect to the database. A default database [stator] will also be created for you. Note that all your database data will be persisted unless you intentionally remove the docker volume. If you would also like to see how the data seeding works, please refer to this.

Choosing the perfect database is a daunting task as it will be one of the core pieces of your architecture. Hopefully, this article helped you shed some light on which database you should use based on your use case. This now completes the deepest layer of my open-source template on stator.

You can read the next article here.

Comments (2)

Vivek Tiwari's photo

Detailed comparison. Thank you.

Yann Thibodeau's photo

I'm happy this could help ;)