Использование Liquibase с CockroachDB

CockroachDB — это самая развитая в мире облачная база данных SQL, обеспечивающая всем вашим приложениям легкость масштабирования, пуленепробиваемую устойчивость и низкую задержку производительности для пользователей в любом месте. Как и в любой базе данных SQL, данные хранятся в таблицах, созданных с помощью языка определения данных (DDL). Одна из проблем, связанных с созданием и поддержкой базы данных SQL, заключается в том, как реализовать таблицы и затем изменить определения этих таблиц последовательным, версионным и простым в использовании способом.

Именно здесь инструмент миграции схемы, такой как Liquibase, может действительно упростить процесс. Для более подробного обсуждения преимуществ инструментов миграции схем обратитесь к этой статье в блоге.

Установка Liquibase

Установка Liquibase проста. Основные шаги состоят из…

  1. Скачать и установить двоичный файл Liquibase
  2. Скачать драйвер Postgres (CockroachDB совместим с протоколом записи Postgres, и Liquibase использует драйвер Postgres для связи с CockroachDB)
  3. Настройте файл свойств Liquibase с информацией о CockroachDB
  4. Создайте журнал изменений схемы Liquibase и добавьте один или несколько наборов изменений в журнал изменений.
  5. Запустите Liquibase, и вы в пути.

Конечно, это немного упрощенное описание. Подробные инструкции по установке можно найти на официальном сайте документации Cockroach Labs здесь.

Типы данных

Типы данных SQL можно условно разделить на 5 различных групп.

  • Числовые (десятичные, int и т.д.)
  • Символ или строка
  • Дата-время
  • Булевы
  • Разные (blob, clob, xml, jsonb и т.д.).

Конечно, каждая база данных может реализовывать эти основные типы данных немного по-разному. Экосистема баз данных не всегда может прийти к единому мнению! Поскольку инструмент миграции схем, такой как Liquibase, не зависит от базы данных, обработка этих различных реализаций типов данных является одной из задач, которую должен решить Liquibase. Liquibase позволяет пользователям определять таблицы с определенными Liquibase типами данных, а затем конвертирует эти типы данных в соответствующий тип данных в целевой базе данных. У меня было несколько пользователей Cockroach, которые просили подробно описать, как именно Liquibase преобразует свои типы данных в типы данных CockroachDB. Предоставление такого преобразования является основной причиной для написания этого блога.

Прежде чем мы перейдем к этому сопоставлению, важно также понять, что Liquibase позволяет гибко подходить к тому, как пользователь может определить свои наборы изменений для создания таблиц. Liquibase поддерживает запись наборов изменений в SQL, XML, YAML и JSON. Я сосредоточусь на SQL и XML.

При использовании набора изменений SQL, такого как показано здесь, —

<changeSet id="12" author="max" runInTransaction="false">
        <validCheckSum>ANY</validCheckSum>
        <sqlFile path="create_next.sql"/>
</changeSet>
Войдите в полноэкранный режим Выход из полноэкранного режима

Где файл create_next.sql содержит следующее —

create table balance
(
    id      int            not null primary key,
    balance numeric(19, 2) not null,
    name    varchar(128)   not null,
    type    varchar(25)    not null
);
Войти в полноэкранный режим Выйти из полноэкранного режима

Liquibase интерпретирует это как прямой DDL и создаст таблицу, как и следовало ожидать, используя указанные типы данных. Это означает, что только типы данных, поддерживаемые Cockroach, могут быть указаны в наборах изменений SQL. Поддерживаемые CockroachDB типы данных можно найти здесь. Таблица базы данных CockroachDB, которая получается в результате выполнения liquibase update для этого набора изменений, имеет вид -…

root@localhost:26257/liquibase> show create table balance;
  table_name |                create_statement
-------------+-------------------------------------------------
  balance    | CREATE TABLE public.balance (
             |     id INT8 NOT NULL,
             |     balance DECIMAL(19,2) NOT NULL,
             |     name VARCHAR(128) NOT NULL,
             |     type VARCHAR(25) NOT NULL,
             |     CONSTRAINT "primary" PRIMARY KEY (id ASC),
             |     FAMILY "primary" (id, balance, name, type)
             | )
Вход в полноэкранный режим Выход из полноэкранного режима

При использовании наборов изменений XML, Liquibase поддерживает другие «не-тараканьи стандарты» типов данных и будет конвертировать их для вас, когда набор изменений будет выполнен. В таблице ниже показан тип данных Liquibase, который необходимо указать, во втором столбце показан тип данных, созданный в Cockroach при использовании SQL changeset, а в третьем — результирующий тип данных Cockroach, когда тип данных Liquibase используется в XML changeset. Если вам действительно интересно, как Liquibase сопоставляет типы данных, вы можете просмотреть их код, но я надеюсь, что эта таблица покажется вам более удобной для восприятия.

Тип данных Liquibase SQL Changeset XML Changeset
bigint int8 инт8
блоб байты oid (bytea в postgres)
булево bool bool
char char(x) char(x)
clob п/п строка
валюта п/п десятичная дробь
время даты н/д временная метка
дата дата дата
десятичная дробь десятичная(x,x) десятичная(x,x)
двойной п/п float8
float float8 float8
int инт8 инт8
mediumint н/а н/д
nchar n/a n/a
ncharvar n/a н/а
число n/a десятичная дробь
smallint инт2 инт2
время время время
временная метка временная метка метка времени
tinyint п/п инт2
uuid uuid uuid
varchar varchar() varchar
jsonb jsonb jsonb
последовательный int8 unique_rowid() int8 unique_rowid()

Например, обратите внимание, что тип данных currency не является поддерживаемым типом данных CockroachDB, поэтому его нельзя использовать в SQL changeset. Однако, если валюта используется в XML changeset, Liquibase создаст столбец как десятичный тип данных. Поскольку CockroachDB совместим с Postgres wire, вы заметите, что преобразования типов данных в целом соответствуют тому, что вы ожидаете от Postgres.

Первичные ключи

В любой распределенной базе данных получение равномерного распределения данных по всем узлам кластера является важным моментом для создания сбалансированного и производительного кластера. CockroachDB хранит данные в слое ключ/значение, упорядоченные лексикографически по ключу. Это означает, что последовательные ключи могут привести к перегрузке конкретного узла, который является арендатором данного диапазона данных. Cockroach рекомендует определять первичные ключи, используя значимый непоследовательный бизнес-ключ или UUID.

Создание первичного ключа UUID в Liquibase с помощью SQL changeset не представляет сложности. Набор изменений будет выглядеть следующим образом

create table uuid_key
(
    id      UUID           not null primary key DEFAULT gen_random_uuid(),
    field1  varchar(25)    not null
);
Вход в полноэкранный режим Выход из полноэкранного режима

А сгенерированная таблица выглядит следующим образом —

root@localhost:26257/liquibase> show create table uuid_key;
  table_name |                create_statement
-------------+--------------------------------------------------
  uuid_key   | CREATE TABLE public.uuid_key (
             |     id UUID NOT NULL DEFAULT gen_random_uuid(),
             |     field1 VARCHAR(25) NOT NULL,
             |     CONSTRAINT "primary" PRIMARY KEY (id ASC),
             |     FAMILY "primary" (id, field1)
             | )
Войти в полноэкранный режим Выход из полноэкранного режима

Однако создание такой таблицы с помощью XML changeset не так интуитивно понятно. При использовании следующего набора изменений XML будет создана точно такая же таблица —

<changeSet  id="15"  author="max">
        <createTable  tableName="uuid_key">
            <column  name="id"  type="uuid"  defaultValueComputed="gen_random_uuid()">
                <constraints  primaryKey="true"  nullable="false"/>
            </column>
            <column  name="field1"  type="varchar(25)"/>
        </createTable>
</changeSet>
Вход в полноэкранный режим Выход из полноэкранного режима

В ситуациях, когда вы не хотите использовать UUID, следующим лучшим вариантом для случайного распределения ключей является использование серийного типа данных в Cockroach. Тип данных serial — это сокращение для объявления поля INT8 со значением по умолчанию, присваиваемым функцией unique_rowid(). Набор изменений SQL будет выглядеть следующим образом —

create table serial_key
(
    id      serial         not null primary key,
    type    varchar(25)    not null
);
Войти в полноэкранный режим Выход из полноэкранного режима

А результирующая таблица будет выглядеть следующим образом

root@localhost:26257/liquibase> show create table serial_key;
  table_name |                create_statement
-------------+-------------------------------------------------
  serial_key | CREATE TABLE public.serial_key (
             |     id INT8 NOT NULL DEFAULT unique_rowid(),
             |     type VARCHAR(25) NOT NULL,
             |     CONSTRAINT "primary" PRIMARY KEY (id ASC),
             |     FAMILY "primary" (id, type)
             | )
Вход в полноэкранный режим Выход из полноэкранного режима

При использовании следующего набора изменений XML будет создана точно такая же таблица —

<changeSet  id="17"  author="max">
        <createTable  tableName="serial_key2">
            <column  name="id"  type="serial">
                <constraints  primaryKey="true"  nullable="false"/>
            </column>
            <column  name="type"  type="varchar(25)"/>
        </createTable>
    </changeSet>
Вход в полноэкранный режим Выход из полноэкранного режима

Последние мысли

Последняя проблема, с которой сталкиваются пользователи Cockroach при работе с Liquibase, связана с выполнением нескольких наборов изменений для одной и той же таблицы в быстрой последовательности. Одной из уникальных особенностей CockroachDB является возможность выполнять изменения схемы в режиме онлайн, не требуя времени простоя. Для этого CockroachDB асинхронно реплицирует изменение схемы на все узлы кластера. Однако все узлы должны завершить изменение схемы, прежде чем таблица может быть изменена снова. На локальном тестовом кластере это, вероятно, не будет проблемой, но в более крупном многорегиональном развертывании это может занять немного больше времени и привести к ошибке, если несколько изменений пытаются внести друг за другом, например, в конвейере CI/CD. По возможности старайтесь сохранять все изменения в таблице в одном наборе изменений!

Целью этой статьи было осветить и ответить на некоторые распространенные вопросы, которые я задавал при использовании Liquibase с CockroachDB для управления схемой базы данных. Надеюсь, вы нашли его интересным и полезным.

Оцените статью
devanswers.ru
Добавить комментарий