Should you have one-database-to-rule-them-all setup or separated database for each bounded context?
Asked Answered
T

3

7

In DDD, as far as I understand it, it helps or guides you on how to structure complex application. Now in an application, you should identify your Bounded Context. Say you have more than 10 BCs.

I read somewhere (forgive me I cannot give any links), that its not ideal to have 1-big database for a complex application. That it should be separated for each BC. If that's the easier route to take. How should one structure an app if each BC have their own database.

I tried searching on github but cannot find one.

Tavel answered 21/4, 2016 at 17:0 Comment(9)
Here's the Bounded Context pattern, provided by none other than Martin Fowler: martinfowler.com/bliki/BoundedContext.htmlBoggers
Yes. But do you know any resources that actually implements 1database per bounded context?Tavel
I was just trying to help with the "forgive me I cannot give any links" section. I'm not qualified to provide a full answer to your question. My gut instinct is that if by "app" you mean a single solution, your solution should have a single context. The Bounded Context pattern appears to apply to enterprise management situations where you have multiple applications talking to one another.Boggers
@BoyPasmo Are you sure you mean BC's and not Aggregates ?Supplejack
@ChaimEliyah I see. But if you have a web app? And in the web app you have multiple BC? Do I need to separate them in a different solution?Tavel
There are different opinions. Google maintains that it's best to keep everything in one gigantic solution. However, that doesn't mean that you can't have submodules. Ultimately, it's about what's going to serve your team best. Are your teams isolated from each other? Will they share libraries? Consider what aim you are trying to achieve, and separate the code base appropriately.Boggers
The database question is something else entirely. This StackExchange question goes into detail on that point.Boggers
Yes. Say we want will be building a web app and to have a 1:1 ratio of a team and a boundedcontext. So basically, each team handles 1 boundedcontext only to separate things. It's still not sinking in my mind on how to do the actual implementation of separating them. Perhaps an example would be great. Though The more I read comments, the more it braine becomes clearer to me.Tavel
The actual implementation really depends on the teams. At the point where the application crosses a socket and talks to a database, it's up to them to use the proper context for their portion of the application. As far as patterns for sharing data are concerned, really that depends a lot on your platform (e.g., a Windows app might use WCF; Windows or Java apps might use SOAP; client-side apps might communicate with different contexts using a domain-specific JSON-based REST API). I really can't give an all-encompassing answer to your question, which is why I didn't post an answer...Boggers
S
7

It depends if they only share the same database or also some tables - i.e. data.

Sharing a database but not tables can be perfectly fine. Except if you aim for scalability and intend to make your BC's independently deployable and runnable units like microservices, in which case they should probably have their own data store instance.

I see a few more drawbacks to database tables shared by 2 or more Bounded Contexts :

  • Tight coupling. The reason we have distinct BC's is that they represent different domain spaces that are likely to diverge their own way. Changing a concept in one of the BC's might impact the underlying table, forcing the other BC's that use this table to change as well. You get rigidity where there should be suppleness. You might also have inconsistencies or "holes" in the data due to the multiple possible sources of change.

  • Concurrency. In highly concurrent systems, some entities and the tables underneath are subject to strong contention. Bounded Contexts are one of the ways to lighten the load by separating different types of writes, but that only works if they don't lock the same data at the end of the day. Same is true for reads in non-CQRS systems where they query the same database where writes are done.

  • ORM friendliness. Most ORMs won't allow you to map to 2 or more classes from the same database table without a lot of convolutions and workarounds.

How should one structure an app if each BC have their own database.

To some extent (e.g. that may include the UI layer or not), just as if you had multiple separate applications. Please be more specific if you have precise questions in mind.

Supplejack answered 22/4, 2016 at 13:28 Comment(9)
I see. But say I have a web app (school web app). And I have a, say, more than 5 BCs. some of which are StudentAndStaffBoundedContext (For CRUD functionalities), GradingBoundedContext, AttendanceBoundedContext. Should I still create different database for each BC? even though they are on the same app?Tavel
Did you read the beginning of my answer ? Do the BC's write to the same tables or not ?Supplejack
Forgive me. Perhaps I didn't state my question correctly. No, they don't write to the same tables. But GradingBoundedContext and AttendanceBoundedContext may need to know (read-only) about a student being inserted StudentAndStaffBoundedContext. I just can't get into my head on how to structure the web app if you have multiple databases on. Because I used to think that its ideal to have just one database for an app.Tavel
You can reasonably say that it's safe to put all the tables in the same database then. But it's not ideal 1/ for concurrency because writes to the Student table might lock it often and cause delays in Grading and Attendance BC's reading it and 2/ for scalability, because if each of these BC's start growing, they might ultimately feel cramped for space (and resources) on the same DB instanceSupplejack
Okay more clear now. Do you know any .net app that demonstrates each BCs have their own storage/database? I would like to see on how they BC communicate to one another. I understand better on concrete examples so I can trace up some code :)Tavel
Sharing a database, tables, or data are not reasons to have multiple applications use a single context. There are other ways to manage those concerns without tightly coupling multiple applications to a single database. If we're talking enterprise applications, in about five years when your user base peaks out, you're going to be paying 20 senior engineers a lot of money to sit in a room and try to figure out how to separate those concerns that should have been separated in the design stage.Boggers
@ChaimEliyah I'm not sure to see where the OP talks about "multiple applications" ?Supplejack
@BoyPasmo I'm not aware of such an app. But you might have some hints in that answer : https://mcmap.net/q/397336/-communicating-between-two-bounded-contexts-in-dddSupplejack
Good point. He does not. I guess I assumed from "How should one structure an app if each BC have their own database" that the ideal solution would be to have multiple apps.Boggers
M
5

The idea of having this vertical slice per bounded-context is so the relationship of each BC to every other BC and the communication between them should be considered and designed based on the domain knowledge and not on the technical merits of a persistence technology.

If you have a Customer in 2 different BCs it causes a kind-of actor pattern situation. If the Support BC needs to know about the new Customer when it is created in the Sales BC, then the Sales BC needs to connect up to a known interface on the Support BC and pass it this new information. One domain talking to another. It models quite closely how things work in real life when people from different departments talk to each other.

If you share a big database (you're talking bespoke enterprise software here so there won't be many examples in the wild) then the temptation is to bypass all the domain expertise that is captured in the domain layers and meddle in another BC's database. Things become a big ball of mud very quickly.

Surprisingly I see this sort of thing too often in the real world and I consider it very bad practice.

Mote answered 22/4, 2016 at 8:13 Comment(2)
Thank you. I started to understand things because of your answer. Based on your example, how should one implement the separation of SupportBC and SalesBC in a web app? how should the communicate? via Domain Events? If I can see at some concrete examples, I understand better.Tavel
Glad to have helped. The domains of the different Bounded Contexts would be separate, so you would only use Domain Events to communicate within the domain of each BC. The most popular ways of communicating between BCs or separate web apps would be either web services (something like REST using Web API, or maybe WCF) or a message bus (something like NServiceBus or MassTransit). Ideally if the boundaries of the BCs have been well identified, the communication between them should be minimal. If they're tightly linked, then it might suggest that they should be a single BC.Mote
H
3

It depends a littlebit on the reason why they are their own database. THe idea of a bounded context is that you have a set of entities that are related together and solve a problem together. if you look at the link Chaim Eliyah provided you can have a sales and a support context.http://martinfowler.com/bliki/BoundedContext.html

Now there is no reason a product for sales,and a product for support should look the same in a database. What is important is that if support wants to add a property (say "Low quality") that it can do so while sales might not want that property. Also downtime on your sales application should probably not affect your support application.

That said entities don't care where they are stored. If you already have a huge product database you can certainly build your entities for different bounded context based on the same database. The thing to remember is that database table is not the same as entity. Entities is what your business/application needs. Database is just what's needed to store things.

That said, separate if you can. If that's not feasable try to define ownerships. You make your life a lot easier if everyone agrees that product is the product as defined by sales and that support can have a "productfactsheetTable" augmenting the product. That way you avoid conflicting changes from each bounded context. (also a followup is that support can only read products but never write). Table prefixes might help here to make this clear.

And this problem already exists with 2 related bounded context. By 10 you'll have a nightmare if multiple context try to write to the same table.

Hagar answered 22/4, 2016 at 6:35 Comment(2)
Thanks for the link. But say if you have just a single web app say, School Web App and have these BCs GradingBoundedContext , AttendanceBoundedContext and StudentAndStaffBoundedContext. How should one structure these BCs and how do they communicate? Say the GradingBoundedContext needs to access Students in StudentAndStaffBoundedContext?Tavel
If they are that closely related are they bounded context or just different aggregate roots? Also The StudentAndStaffBoundedContext could expose an API that allows you to query students. That way the studentAndStaffBoundedContext is responsible for any data acess this solving your multiple bounded context access the same table problemHagar

© 2022 - 2024 — McMap. All rights reserved.