Small systems grow with success. As these systems grow they often take on more and more functionality either directly into the main system component or into sub-systems. As the systems grow in complexity and responsibility their database requirements grow at a similar rate become more and more complex.
In these complex systems each component needs to not only have access to data but also to transitive data generated by other components. This need often leads to the database becoming the inter-component communication channel.
This design means that the components are coupled through one or more databases. In normal operation this design is simple and fairly effective. Upgrading areas of the system however becomes more and more difficult whenever database changes are required. Things become even more complex if application logic in embodied in the database in some way (Stored Procedures, Triggers etc).
So let’s consider a simple scenario where two components A and B both require the same data from a table T.
Figure 1. Simple Table dependency
Now lets suppose a change to component A requires some change to the table T. Before we can deploy the update B also needs to be updated to use updated table. Quite often development is not isolated to a single component. Business need to move quickly to take advantage of a shifting market. These changes are unlikely to be isolated to to a single component but changes are often constrained by priority and resources. This added logistical complexity has to be managed by the development team either by extending time-lines or complicating the way the team use version control etc.
Figure 2. Upgrades requiring database changes
Wrapping the database within an encapsulating layer of software that provided application level interfaces to the components we essentially break the direct implementation dependency between the components and the table implementation.
Figure 3. Encapsulating the database – single adaptor
Figure 4. Encapsulating database – multiple adaptor instances
In this configuration if component a A change requires a database change the encapsulation layer can be updated to support the new component A functionality whilst supporting the existing functionality of component B. We need to regression test both components with the new encapsulation layer but in deployment we only need to deploy the new component A and the updated encapsulation layer.
As the system grows further we can break up the database into smaller more manageable chunks with logical groupings within one or more encapsulation layering components.
Over the years I have seen lots of systems develop their integration patterns around the database. This pattern, while initially successful leads to greater and greater challenges for the development organisation. These challenges surface as elaborate proceedures, complex deployment policies and large comlicated deployments.