We are trying to fix our's company versioning of several modules and I'm not sure how to consider Database compatibility when versioning.

The same Database is used for a lot of applications and we're thinking of using something like SemVer for both, applications and database.

There are versions when maybe nothing new comes and just a few fixes to database (so, probably no breaks here). The same happens for our WebProject, for example and so on.

But also can happens that one of ours applications has something new and breaks with database compatibility. Do we need to control the compatibility in both versions?

Nowadays, we have our full-product version and inside this fullproduct there's each module version.

For example:

Full-product version: 8.0
DB: 31.2.0
Web: 5.4.3
XYZ: 2.0.1
ABC: 7.0.5

Full-product version: 8.1
DB:  31.3.0 <--- break compatibility with Web
Web: 5.5.0 <--- break compatibility with database
XYZ: 2.0.1 <--- no changes since last version
ABC: 7.0.8 <---- Only fixes, no break compatibility with any other module

So, for example, we are developping the version 9.0 and the Web project will use a new column in a table. So, there's a change in database and web project. The SemVer compatibility should chance in both modules the "middle" number?

Version 9.0
DB:  31.4.0
Web: 5.6.0

One last thing is: During the test, we see that for fix one issue we would have a break compatibility . Our RC version should be updated? Example:

Web: 5.6.1 RC1
Web: 5.6.1 RC2
Web: 5.6.1 RCX? <- this fix create a compatibility break. Should it be 5.7.0 RC3?

Should database be versioned just as common module or there's another way of doing this and control compatibility between modules?

  • Do you have a layer of indirection like a Data Access Layer (DAL) or Service Layer that would allow you to keep the data API stable while versioning the database? If you don't, I think you're in for a world of hurt. – Robert Harvey Jul 3 '20 at 18:22
  • if you mean for example having an API responsible to connect the database and be consumed by others applications, no. We don't. We have a lot of legacy projects and each one makes the conections and cosume the database direct. – Victor Bello Jul 3 '20 at 20:29

Is SemVer applicable?

  1. Software using Semantic Versioning MUST declare a public API. This API could be declared in the code itself or exist strictly in documentation. However it is done, it SHOULD be precise and comprehensive.

Can the database be subject to SemVer ?

  • The DB engine is clearly software with an API. Your DBMS probably already uses SemVer (examples here), and you probably already define compatibility requirements in your release notes.
  • Stored database code like triggers or stored functions is another layer of software that is intirectly (triggers) or directly (stored functions) exposed as API by the database engine.
  • The data stored in the database is not software. But the data definition defines de facto an API to access the data, with the tables and the columns (in an RDBMS example) that can be used in queries. In this reagard the database definition is semversionable.

How to apply it?

Once your DB released, the following applies:

  1. Once a versioned package has been released, the contents of that version MUST NOT be modified. Any modifications MUST be released as a new version.

Every change to the database definition, i.e. any DDL command or script requires a new version, must result in a new version that shall follow the semver rules. For example:

  • adding a new table causes in principle no incompatibilities, so it would be a minor version.
  • changing some table could be backwards compatible. However very quicky, DB changes might be backwards incompatible. Even a harmless increase of length of a field might cause some code that uses hardcoded length not to work anymore. So you might often change major version. This is why DBA's don't like changing the productive database.
  • some database practice might reduce such effect. For example, you could expose data via views. You may then change tables, add new columns, but make sure that the views are backwards compatible.

Some conventions might also reduce backward compatibility since you may define your API "strictly in documentation" (see Semver 1). You may therefore impose backwards compatibility requirements. For example you can impose not to assume length of columns to be fixed, or to always explicitely list the selected columns in a query, etc... I'd strongly recommend such documentation constraints to be considered part of the API.

How does it influence the other software components?

Your Web software for example may be semversioned based on the API it defines. GUI software does in principle not define an API, but often SemVer is applied by analogy.

The important point is that the versioning is based on the API provided, and not the API consumed. So if your Web software decides to query the database differently, this should not affect the software's major version since its own API remains backward compatible.

The things a more subtle for constraints and invariants:

Suppose you assume that a field should never be null, and suddenly one of the application writing in that table no longer respects this implicit constraint. This should not happen, because a minor change in one application might cause other applications to break despite the database scheme was not modified:

  • This is a strong argument in favor of declaring constraints within the database instead of assuming the applications behave well. Adopting such a strategy would cause your application to fail, and would require you to issue a new major database version if you want to allow weakened the constraint (but this time in a controlled manner).
  • But if you do not want to, or if the constraint cannot be expressed in your DB engine, you could still define such mandatory constraints and invariants in the database documentation. Weakening the constraint in one application would make it non compliant, unless you weaken the constraint in the database documentation, which would require a new database version, which would allow to better control the change propagation (or at least to be aware of it). But this is soft versioning.

Are there better alternatives?

Soft-versioning based on documentation is extremely risky. Database versionning might require frequent major changes, which require an impact assessment on all the applications depending on the database version.

A first strategy, is to version not the full database definition but schemas or namespaces in the database. This facilitates dependency management, since the granularity of change it tighter.

A second strategy is, as Robert described in his comments: to add database access layer, and manage the version for its components. The advantage is that it adds a lot of flexibility and allows a better decoupling between the data usage and the database. Nevertheless, it only shifts the problem, since you'd still need to know which version of the database access layer is compatible with what database definition. SO ieven if this approach has advantages, it shouldn't dissuade you from versioning the database :-)

  • 1
    ...since you'd still need to know which version of the database access layer is compatible with what database definition. -- Yes, but now you only break compatibility with one piece of software, and not several. – Robert Harvey Jul 4 '20 at 5:03
  • First of all, thank you for your time and answer, @Christophe, I'll discuss the possibilities with the database team and study more how mariadb does. A little bit unreleated, could you tell me if breaking compatibility (and changing version accordingly) during the release version is ok (my last question on the main post) – Victor Bello Jul 6 '20 at 14:31
  • 1
    @VictorBello First of all, for your software components (db consumers), you’d change rc version as always. If at rc test level it appears that you have to change the db, then you may change the rc suffix only if you still comply with the versioning requirements. If you had a db rc for a minor change and introduce a backwards compatible change, just update the rc. If it’s already a rc for a major release and you introduce another incompatible change, update the rc. However if it’s a db rc for a minor change and introduce a backwards incompatible change, you need a new rc for a new major. – Christophe Jul 6 '20 at 14:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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