4

I don't have a formal education regarding application architecture, what I know I mostly "absorbed" on the job from enterprise architectures of the companies I worked for and/or from senior colleagues.

One principle I absorbed from a huge company is that each server-side enterprise application should only have access to its own database, and if other applications need to read/write data on that database they should do so through a layer of services exposed by the application "owning" the database.

I like this principle because I find it neat and clean, but I suppose that more consistent arguments exist in favor and against it.

I tried googling this concept but I mostly find Q&A/guides about how to connect to multiple databases from technology X. One tip I came across is that connecting to multiple databases from a single application will probably be faster, since we're skipping a step. This is relevant and interesting but hardly complete.

Hence my question: is there any recognized pattern supporting or discouraging the access to multiple database from a single application?

Edit: comments and answers made me realize that the actual question I had in mind was not much about accessing multiple database from a single application, but rather about sharing the same database between multiple applications (that in turn might connect to multiple database but, again, that's not quite the point). I modified the title of this question accordingly, from "access to multiple database from a single application" to "access to the same database from multiple applications". The answers below are still relevant to the topic.

9
  • 6
    Design patterns are not guidelines for how to design your system. They are always detailed solutions for how to combine classes and instances to solve a recurring non-obvious requirement that follows from how your system is designed. Dec 1, 2020 at 11:17
  • 1
    @KilianFoth I suppose that widely-known/recognized enterprise architetture guidelines do exist though. I assumed they were called "patterns" as well but I acknowledge from your comment that such taxonomy is incorrect. Can you suggest a better name so I can improve my question? That being said the question still stands... or do you find the question is inconsistent altogether?
    – Tom
    Dec 1, 2020 at 12:52
  • 1
    There is no pattern supporting or discouraging this. There are patterns that utilize one way or the other, though. Dec 1, 2020 at 13:50
  • 2
    @Steve: A good answer to the question you posed could fill a book. Maybe more than one. Dec 1, 2020 at 14:17
  • 1
    Be sure edits to your question do not invalidate current answers. If they do, you can post a new question. Dec 1, 2020 at 20:03

3 Answers 3

5

Connecting multiple applications to the same database is often a bad idea. It's an integration anti-pattern you might call The Shared Database and it's unfortunately a very easy anti-pattern to fall into.

It's common for a database to be created as part of building an application. That application needs to store its data somewhere, right? You need a database so you create one. But then, after some time, other applications get created that might need access to some data that already exists (the usual suspects are users, customers, products, orders, etc). How do they get the data? Well, nothing simpler: just connect to the same database, right?

And now you have some problems:

  • a database is an implementation detail. You now exposed it to other applications;
  • an implementation detail can be changed because it's just that, an implementation detail. Want to change the implementation of your database, change tables structures, schemas, etc? You can't do it anymore without affecting other applications (anyone with the database connection credentials can basically reach out into your database and fetch whatever data they want - you might have applications connecting to your DB without even knowing they exist).
  • if your database structure isn't exactly how others need it, you might need to make changes to your DB for someone else's use case. Or they will do so themselves :) and break your application with the help of your own database.
  • hello tight coupling, bye bye loose coupling. That's bad however you put it.
  • you only store data, you don't store behavior. The behavior is in your application. How can others reuse your behavior? Maybe create a crap load of stored procedures to share the behavior. And now you get more and more entrenched into using that database vendor implementation. Want to change from OracleDB to MySQL? You now need approval from others.
  • etc.

A shared database is like having neighbors paying you a visit and then refusing to leave. You now have to live with them.

So exposing "your" database to "others" by using and API, a gateway, a facade, a service, or whatever, is a way to share the data and behavior without having to live with your neighbors. It's a good practice that hides the implementation details. Of course it's not without its disadvantages: it's more complex than select * from, more verbose, it still is an integration point (which needs to evolve, maybe not at the same pace for everyone using it, so you now need API versioning), etc.

When it comes to one application connecting to multiple DBs (as your title asks), things are simpler and less problematic concerning what I said above. But this is also a trade-off. Transactions might suck across multiple databases, and so will performing joins. Keeping things separated makes sense but will cause performance degradation as now you need to open connections to more databases. You might also cause problems some place else, if other applications connect to the same databases (i.e. not just "your" application to "your" own multiple databases), etc.

At the end of the day, it's not about patterns or anti-patterns, but about thinking carefully about one design decision or another (i.e. do you need one DB or more and how you will access them), trade-offs, and above all, a good dose of common sense.

5
  • 5
    Connecting multiple applications to the same database only became unfashionable when microservices came along, and all of your objections can be overcome with sensible design strategies. Dec 1, 2020 at 14:18
  • 2
    @RobertHarvey: it's something that became fashionable when microservices came along, I agree with you. But the problems existed with this way of doing things before that. I'm just mentioning some things that can be caused by connecting to multiple databases, and why one might chose to just use one database. Of course, thinking that you will only ever need one database isn't any better for a design strategy.
    – Bogdan
    Dec 1, 2020 at 14:28
  • 2
    I've never worked on a project where the database was an "implementation detail", except maybe from the frontend POV. Quite the opposite, actually. Typically, the situation where I work is that the database contains the business value of the enterprise and the applications around it are subject to frequent change. In my experience, it is much more likely that you rewrite all your client applications from scratch than to switch from Oracle to MySQL. An Oracle database may well live for decades. You shouldn't design your architecture around the totally unrealistic use case of replacing it. Dec 2, 2020 at 9:40
  • 1
    @ChristianHackl: I've switched MySql to Oracle, MSSQLServer to Postgres and wrote products with Hibernate ORM that worked with any DB (installed at multiple clients on different database engines). I've also been in one sad instance unable to upgrade a MySQL database to a newer version because other applications were connected to it and "it was not the right time for them", or "it was risky", or "they had other things to do". I agree databases are an important asset, but you need to carefully design how your systems access them or teams can hold themselves hostages with directly accessed DBs
    – Bogdan
    Dec 3, 2020 at 18:09
  • @Bogdan: Well, if that worked for you and it was the right choice at that time, then that's perfectly fine. It just doesn't match my own experience at all, which of course may be a result of working in a completely different sector or in a business with a different size and culture. I do completely disagree with the claim that accessing a database from multiple applications is an anti-pattern. A more balanced answer would consider all benefits and liabilities of both architectural choices (as a matter of fact, my own comment was probably too unbalanced as well, just in the other direction). Dec 4, 2020 at 5:30
2

The other way around - having multiple applications (services) access the same database - would be an anti-pattern which implies lots of problems such as high coupling between those applications, unwanted side-effects and potential performance problems because independent scaling per application on a database level is not possible to name a few.

Having a single application accessing multiple data stores on the other hand can be totally fine for the right reasons and if those data stores are owned by this application only. High scalable cloud services such as CDNs for cost sharing might be an exception here but in general you get the idea.

Think of some catalog microservice which is part of a web shop. It might have some sql databases for it's product information but some other more suited data stores for storing product images. This is totally fine in this case even preferable from my point-of-view.

This Polyglot persistence pattern is, for instance, a natural fit for microservices architectures.

The only thing I would look into is, if you access several data stores from the same application, make sure all these data access use cases belong to the same problem domain. Single applications (services) should have focused responsibilities. Multiple data stores could be a signal a service has too many responsibilities, could be but does not have to be of course.

1

One principle I absorbed from a huge company is that each server-side enterprise application should only have access to its own database, and if other applications need to read/write data on that database they should do so through a layer of services exposed by the application "owning" the database.

This is the philosophy adopted by microservices. Note that this philosophy comes with its own set of problems: see Cap Theorem and Eventual Consistency

The idea behind microservices is that, in a large corporation, each team is responsible for its own application and nothing else. This isn't a bad idea in and of itself, but it must be tempered with a bit of pragmatism. If the microservices are too small/granular, you will be spending a great deal of time communicating between microservices using less than ideal connection mechanisms. The tradeoff is that microservices can allow a more scalable architecture.

The opposite is also true, of course. Building a monolith can constrain you in ways that microservices cannot (although Stack Exchange seems to have done pretty well with their monolith), but your company would have to be very large for that to occur.

Further Reading
The macro problem with microservices

Your Answer

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

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