Liquibaseは、データベースのスキーマ変更をバージョン管理するためのツールです。

ここでは、Liquibaseの基本的な使い方をステップごとに説明します。

詳しい情報やオプションについては、Liquibase公式ドキュメントを参照してください。

データベースマイグレーションツール比較表

まず、他のDDLと比較してこのような感じかなと思いました。

特徴 / ツール MyBatis Migration Flyway 無料版 Flyway 有料版 Liquibase
複数環境のDB管理
バージョン管理
ロールバック機能 ×
価格 無料 無料 有料 無料(基本版)
カスタマーサポート × × ×
DBからファイル作成 × × ×
  • MyBatis Migrationのロールバックは何でもできるが、手動でロールバックコードをマイグレーションファイルに書いていかないといけないのがイマイチ。
  • Flywayの無料版はロールバックできず、有料版はそこそこの値段がする。

なんと、Liquibaseは既存のDBから、ある程度のマイグレーションファイルを作成できるとのことで調べてみることにした。

ひとまず、ここではLiquibaseの使用方法をまとめる。

MyBatis Migrationについてはこちらで調べてます。

Flywayについてはこちらで調べてます。

Liquibaseのインストール手順

  1. Javaのインストール:
    • LiquibaseはJavaで動作するため、Java Runtime Environment (JRE) または Java Development Kit (JDK) が必要です。Java 8 以上が推奨されます。
  2. Liquibaseのダウンロード:
    • Liquibaseの公式サイトから最新バージョンのLiquibaseをダウンロードします。
    • ZIPファイルをダウンロードし、解凍して任意のディレクトリに配置します。
    • 環境変数PATHにLiquibaseの実行ファイルがあるディレクトリを追加します。
  3. データベースドライバーのセットアップ:
    • 使用するデータベースに接続するためのJDBCドライバーをダウンロードし、Liquibaseのlibディレクトリにコピーします。

Liquibaseの使い方

データベースマイグレーションの実行

  1. チェンジログファイルの作成:
    • データベースの変更を記述するチェンジログファイルを作成します。チェンジログファイルはデータベースの変更リストのようなものです。XML、YAML、JSON、またはSQLで記載できる。
    • チェンジログファイルの中の一つ一つのタスクとしてチェンジセットがあります。例えば、「テーブルを作る」というタスクが一つのチェンジセットになります。各タスクは、番号と作成者の名前で特定されます。
  2. XML 形式

            <databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
                               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                               xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
                                   http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.8.xsd">
                <changeSet id="1" author="developer">
                    <createTable tableName="new_table">
                        <column name="id" type="int" autoIncrement="true">
                            <constraints primaryKey="true" nullable="false"/>
                        </column>
                        <column name="name" type="varchar(255)">
                            <constraints nullable="false"/>
                        </column>
                    </createTable>
                </changeSet>
                <changeSet id="2" author="developer">
                    <addColumn tableName="new_table">
                        <column name="description" type="text"/>
                    </addColumn>
                </changeSet>
            </databaseChangeLog>
        

    複数のチェンジセットが書かれたチェンジログファイルでマイグレーションを実行すると、それらのチェンジセットは順番に実行されます。そして、データベースにその履歴が残ります。

    このように記述されたチェンジログファイルをマイグレーションすると、changeSet id="1"changeSet id="2" が順番に実行されます。

    JSON 形式

            {
              "databaseChangeLog": [
                {
                  "changeSet": {
                    "id": "1",
                    "author": "developer",
                    "changes": [
                      {
                        "createTable": {
                          "tableName": "new_table",
                          "columns": [
                            {
                              "column": {
                                "name": "id",
                                "type": "int",
                                "autoIncrement": "true",
                                "constraints": {
                                  "primaryKey": "true",
                                  "nullable": "false"
                                }
                              }
                            },
                            {
                              "column": {
                                "name": "name",
                                "type": "varchar(255)",
                                "constraints": {
                                  "nullable": "false"
                                }
                              }
                            }
                          ]
                        }
                      }
                    ]
                  }
                },
                {
                  "changeSet": {
                    "id": "2",
                    "author": "developer",
                    "changes": [
                      {
                        "addColumn": {
                          "tableName": "new_table",
                          "columns": [
                            {
                              "column": {
                                "name": "description",
                                "type": "text"
                              }
                            }
                          ]
                        }
                      }
                    ]
                  }
                }
              ]
            }
        

    YAML 形式

            databaseChangeLog:
              - changeSet:
                  id: "1"
                  author: "developer"
                  changes:
                    - createTable:
                        tableName: "new_table"
                        columns:
                          - column:
                              name: "id"
                              type: "int"
                              autoIncrement: true
                              constraints:
                                primaryKey: true
                                nullable: false
                          - column:
                              name: "name"
                              type: "varchar(255)"
                              constraints:
                                nullable: false
              - changeSet:
                  id: "2"
                  author: "developer"
                  changes:
                    - addColumn:
                        tableName: "new_table"
                        columns:
                          - column:
                              name: "description"
                              type: "text"
        

    SQL 形式

            --liquibase formatted sql
    
            --changeset developer:1
            CREATE TABLE new_table (
                id INT AUTO_INCREMENT PRIMARY KEY,
                name VARCHAR(255) NOT NULL
            );
    
            --changeset developer:2
            ALTER TABLE new_table ADD COLUMN description TEXT;
        

データベースからのチェンジログの生成

Liquibaseは、データベースの現在のスキーマからチェンジログを生成するためのコマンドを提供しています。 この機能を使用するには、以下のコマンドを実行します:

liquibase generateChangeLog --changeLogFile=dbchangelog.xml

このコマンドにより、現在のデータベーススキーマがdbchangelog.xmlというファイルに出力されます。 他の形式(JSON、YAML、SQL)に変換するためには、手動で編集する必要があります。

  • マイグレーションの実行:
    • コマンドプロンプトまたはターミナルを開き、以下のコマンドを実行してデータベースを更新します。
    liquibase --changeLogFile=mychangelog.xml update
  • データベースのロールバック

    rollbackCount コマンドを使用すると、指定した数のチェンジセットをロールバック(元に戻す)することができます。

    liquibase --changeLogFile=mychangelog.xml rollbackCount 1

    例えば、id1とid2つのチェンジセットがマイグレーションされた状態で、

    上記のコマンドを実行すると、最後の1つのチェンジセットが取り消され、changeSet id="1" の状態にデータベースが戻ります。

    Liquibaseでの複数環境に応じたDDL管理

    単一のチェンジログファイルを使用する方法

    単一のチェンジログファイルにすべての環境の変更を記録し、contextslabelsを使用して環境に応じたマイグレーションを制御します。

    例:開発環境専用の変更を定義

    <databaseChangeLog>
        <changeSet id="1" author="dev" context="development">
            <!-- 開発環境でのみ実行される変更 -->
        </changeSet>
        <changeSet id="2" author="dev" context="production">
            <!-- 本番環境でのみ実行される変更 -->
        </changeSet>
    </databaseChangeLog>
    

    マイグレーション実行時にコンテキストを指定

    liquibase --contexts=development update

    環境ごとに異なるチェンジログファイルを使用する方法

    各環境ごとに異なるチェンジログファイルを用意し、環境に特化した変更をそのファイルに記述します。

    例:開発環境用のチェンジログファイル

    <databaseChangeLog>
        <changeSet id="1" author="dev">
            <!-- 開発環境での変更 -->
        </changeSet>
    </databaseChangeLog>
    

    マイグレーション実行時にチェンジログファイルを指定

    liquibase --changeLogFile=developmentChangelog.xml update

    どの方法を選択するかは、プロジェクトの要件やチームの運用スタイルに依存します。一つのチェンジログを使う場合は管理が集中されるためシンプルですが、環境ごとにファイルを分けたほうが、環境固有の設定が明確になり、運用ミスのリスクを減らすことができます。

    詳しい情報やオプションについては、Liquibase公式ドキュメントを参照してください。