DEV Community

Cover image for 3. Designing a Microservice: choosing a DB
Ashutosh Sahu
Ashutosh Sahu

Posted on

3. Designing a Microservice: choosing a DB

In the previous article, we looked into the characteristics of microservice architecture and the steps involved in their design process like domain analysis, bounding context, and selecting a communication channel along with an example of our food ordering application. This article will discuss selecting databases and applying some design patterns or scaling techniques to our microservice architecture.

Step 4. Selecting the Database:

Databases are an essential part of any architecture. While selecting a database, we need to consider various factors like consistency, query performance, cost, scalability, and most importantly - the type of structure we will save in the database. Let's look at different types of databases:

SQL (MySQL, PostgreSQL, MSSQL)

SQL databases are used for storing structured data that is related to one another. If your service has to store data related to customer information, financial transactions, inventory management, or other such things in which different piece of information is related to one another in some way and need to be frequently queried, then you should use an SQL database.

NoSQL

NoSQL databases are used for storing unstructured or semi-structured data. They are widely used in web applications for storing user-generated content such as social media posts, comments, and reviews. NoSQL databases come in different types, each with its purpose.

  • Key-Value Store (DynamoDB, Redis, Memcache): Key-value stores are used for storing any data structures such as strings, integers, or objects which is tied to a key. They are widely used in caching and session management. Redis is an in-memory database, which is used for caching mainly. DynamoDB is a cloud-native database that is offered by Amazon Web Services (AWS). It is designed to handle large amounts of data and traffic while maintaining consistent and fast performance.
  • Document Store (MongoDB, CouchDB): Document stores are used for storing semi-structured data such as JSON documents. They are widely used in web applications for storing user-generated content. If your service needs to store data related to users which is more likely unstructured or has frequent changes and needs to be scaled easily, then MongoDb or CouchDb are good choices.
  • Column Store (Cassandra, HBase): Column stores are used for storing large amounts of data that can be queried quickly. They are widely used in big data applications for storing and analyzing large datasets. Column stores provide a type of structure to the NoSQL databases, making it easier to make faster queries. If you need to process real time or high volume of data, you should choose column store databases.
    Graph Store (Amazon Neptune, Neo4j): Graph stores are used for storing data that has complex relationships. They are widely used in social networking and recommendation systems. If your service is related to providing some recommendations based on users past activities then a graph store is best choice.

  • Hybrid (CockroachDB, PostgreSQL): Hybrid databases combine the benefits of SQL and NoSQL databases. They are used for storing structured and unstructured data. CockroachDB is a distributed SQL database that is designed for scalability and high availability. PostgreSQL is a hybrid database that supports both SQL and NoSQL data models.

When deciding which type of database to use, consider the following factors:
Data Structure: If your data is structured and related to one another, then a SQL database is a good choice. If your data is unstructured or semi-structured, then a NoSQL database is a better choice.
Scalability: If you need to scale your database horizontally, then a NoSQL database is a better choice. If you need to scale your database vertically, then a SQL database is a better choice.
Querying: If you need to perform complex queries on your data, then a SQL database is a better choice. If you need to perform simple queries on your data, then a NoSQL database is a better choice.
Consistency: If you need strong consistency guarantees, then a SQL database is a better choice. If you can tolerate eventual consistency, then a NoSQL database is a better choice.
Cost: SQL databases are generally more expensive than NoSQL databases. If cost is a concern, then a NoSQL database is a better choice.


Let's continue with assigning a database for our food ordering microservice architecture. 
For users and restaurant inventory-related data, we can use an SQL database like Postgres. 
For managing orders, we can use a NoSQL database like MongoDB.
For real-time delivery tracking and queries, we can use Cassandra or HBase.
For recommendation systems, we can use Neptune as a graph db.


Step 5. Integrating Design Patterns or Techniques

The final step is to apply some design patterns or techniques that can help us solve some common problems or challenges in a microservice architecture. They are not required at the beginning phase, but eventually, you will need them.

Some common design patterns or practices are:

  • Strangler Pattern
  • SAGA Pattern
  • CQRS Pattern
  • API Gateway Routing
  • Circuit Breaker Pattern
  • Backend for Frontend
  • Load balancing
  • Consistent Hashing
  • Partitioning
  • Replication
  • Caching
  • Sharding
  • Rate Limiting
  • Locking and Idempotency handling
  • Concurrency handling
  • Application metrics
  • Audit logging

We will discuss them in detail later in our series.

A few things to remember

There are a few more small things that can help further in the design process.

  1. It is not always necessary to create a service if you just need separation of concern in code, you can create a library or a package instead. For example, a part of your codebase works in designing email templates and generating PDF invoices or Excel reports. These tasks are independent functions in themselves, they just need an input and are supposed to give some output. they share common util functions and imports and sometimes, are needed across different services. For such tasks, it's better to create a library/package rather than a service. Using the library, you can abstract that part of code from your services, also they are faster to serve because there is no inter-service communication involved.

  2. Try to make service communications unidirectional. Your microservice structure should be like a tree, with Parent and child services. where parents can send requests to children and get a response, but the reverse should be avoided as much as possible.

  3. Always use a centralized logging system with a standard format for easy-to-find issues among different requests. Use headers like correlation ID to see all logs related to a single transaction among all services. also log key data points like order ID to retrieve all logs related to them at any point.

  4. Stay near code, there are too many small business details that are never covered in any document. They are only in the code. No person knows them better than your code. So stay near the code or the person writing them. It's easier to draw boxes and design but harder to implement. Knowing how things like message queues, load balancers, and rate limiting are implemented and work at a low level is equally important.


In our next article, we are going to discuss infrastructure estimations for microservice architecture, how to choose the right infrastructure and calculate costs.

AWS Q Developer image

Your AI Code Assistant

Automate your code reviews. Catch bugs before your coworkers. Fix security issues in your code. Built to handle large projects, Amazon Q Developer works alongside you from idea to production code.

Get started free in your IDE

Top comments (0)

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more