schema while conserving the existing data. While this sounds useful in theory, in fact it is very limited
for anything other than noncritical development environments. In particular, these tools do not handle
data migration well. For example, if you rename a column in your database, the update process will
simply create a new column: it will not copy the data from the old column into the new column, nor
will it remove the old column from the updated table.
Fortunately, this is not the only approach you can use. Another tool that attempts to tackle the thorny
problem of database updates is Liquibase^1. Liquibase is an open source tool that can help manage and
organize upgrade paths between versions of a database using a high-level approach.
Liquibase works by keeping a record of database updates applied in a table in the database, so that it is
easy to bring any target database to the correct state for a given version of the application. As a result,
you don’t need to worry about running the same update script twice—Liquibase will only apply the
update scripts that have not already been applied to your database. Liquibase is also capable of rolling
back changes, at least for certain types of changes. However, since this will not work for every change
(for example, data in a deleted table cannot be restored), it is best not to place too much faith in this
particular feature.
In Liquibase, you keep track of database changes as a set of “change sets,” each of which represents
the database update in a database-neutral XML format. Change sets can represent any changes you
would make in a database, from adding and deleting tables, to creating or updating columns, indexes
and foreign keys:
<databaseChangeLog
xmlns="http://www.liquibase.org/xml/ns/dbchangelog/1.6"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog/1.6
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-1.6.xsd">
<changeSet id="1" author="john">
<createTable tableName="department">
<column name="id" type="int">
<constraints primaryKey="true" nullable="false"/>
</column>
<column name="name" type="varchar(50)">
<constraints nullable="false"/>
</column>
<column name="active" type="boolean" defaultValue="1"/>
</createTable>
</changeSet>
</databaseChangeLog>
Change sets can also reflect modifications to existing tables. For example, the following change set
represents the renaming of a column:
<changeSet id="1" author="bob">
<renameColumn tableName="person" oldColumnName="fname" newColumnName="firstName"/>
</changeSet>