---
metadata:
  - name: generator
    content: Diplodoc Platform v5.50.6
alternate:
  - https://ydb.tech/docs/en/integrations/data-migration/import-jdbc.md
  - https://ydb.tech/docs/ru/integrations/data-migration/import-jdbc.md
sourcePath: ru/core/integrations/data-migration/import-jdbc.md
---
> **Documentation Index:** Fetch the complete configuration index at https://ydb.tech/docs/ru/llms.txt

# Импорт структуры таблиц и данных из источников JDBC

## Введение {#intro}

Задача импорта в YDB структуры таблиц и содержащейся в таблицах информации для источников данных, поддерживающих доступ через JDBC-интерфейс, может быть решена с помощью [специально разработанной утилиты](https://www.github.com/ydb-platform/ydb-importer/). Это может быть полезно для перехода с других систем управления базами данных на YDB или, к примеру, для импорта ваших реальных данных для запуска тестов производительности на YDB.

Импорт данных осуществляется в следующем порядке:

1. Утилита импорта подключается к БД-источнику, и определяет состав таблиц и SQL-запросов для импорта.
2. Производится формирование структуры целевых таблиц YDB, которые опционально могут быть сохранены в виде YQL-скрипта.
3. Над БД-получателем производится проверка наличия там целевых таблиц, с созданием недостающих таблиц и с опциональным пересозданием уже существующих таблиц.
4. Осуществляется импорт данных путём чтения из БД-источника с помощью SQL-запроса и вставки в БД-получатель YDB с помощью механизма Bulk Upsert.

Извлечение метаданных из БД-источника, создание таблиц в БД-получателе и импорт данных производится в параллельном режиме, с использованием нескольких конкурентных потоков и одновременно открытых соединений к БД-источнику и БД-получателю. Максимальная степень параллелизма регулируется специальной настройкой, при этом фактическое количество конкурентных операций не может превышать количества импортируемых таблиц.

## Установка утилиты импорта {#install}

Для работы утилиты импорта требуется JDK 8 или более поздней версии, исполняемый файл `java` должен быть доступен в путях поиска программ. Сборка и тестирование утилиты выполнялись с использованием OpenJDK 8.

Для установки утилиты импорта рекомендуется использовать последнюю версию, доступную на [странице релизов](https://github.com/ydb-platform/ydb-importer/releases). Дистрибутив представляет собой архив в формате ZIP, который необходимо распаковать в локальный каталог сервера, на котором предполагается запускать утилиту.

В состав дистрибутива включены примеры файлов настроек, пример скрипта запуска и набор архивов `lib/*.jar`, содержащих собственно исполняемый код утилиты и её зависимости, включая [YDB Java SDK](https://ydb.tech/docs/ru/reference/ydb-sdk/index.md).

Перед запуском утилиты импорта драйверы JDBC для исходных баз данных следует разместить в виде файлов `*.jar` в подкаталоге `lib` каталога инсталляции утилиты.

## Порядок использования утилиты импорта {#use}

При запуске утилита считывает настройки из файла в формате XML, указанного в качестве аргумента командной строки. Имя файла настроек передается в командной строке при запуске утилиты импорта. В настройках указывается:

* тип БД-источника и параметры подключения к источнику;
* параметры подключения к БД-получателю YDB;
* (опционально) имя файла для сохранения YQL скрипта со структурой таблиц для YDB;
* правила отбора таблиц для импорта из БД-источника;
* перечень явно указанных SQL запросов на выборку данных из БД-источника (может использоваться для импорта результата запроса вместо конкретных таблиц);
* правила формирования имён импортируемых таблиц в БД-получателе;
* степень параллелизма операций (размер пула рабочих потоков, количество соединений с источником и получателем).

Файл настроек необходимо подготовить перед запуском утилиты на основе представленных примеров.

Пример команды запуска утилиты импорта приведён в файле [ydb-importer.sh](https://github.com/ydb-platform/ydb-importer/blob/main/scripts/ydb-importer.sh), который можно использовать для запуска, как показано ниже:

```bash
./ydb-importer.sh my-import-config.xml
```

## Особенности и ограничения импорта {#limitations}

На текущий момент протестирована работа утилиты импорта со следующими видами источников данных:

* [PostgreSQL](https://www.postgresql.org/),
* [MySQL](https://www.mysql.com/),
* [Oracle Database](https://www.oracle.com/database/),
* [Microsoft SQL Server](https://www.microsoft.com/sql-server/),
* [IBM Db2](https://www.ibm.com/products/db2),
* [IBM Informix](https://www.ibm.com/products/informix).

Утилита импорта может оказаться работоспособной для многих не протестированных источников данных JDBC, поскольку в ней используются стандартные вызовы JDBC для доступа к данным и метаданным.

Импорт вторичных индексов не осуществляется.

Некоторые типы данных и виды табличных структур не поддерживаются, включая:

* вложенные таблицы Oracle Database,
* пространственные типы данных Microsoft SQL Server,
* все объектные типы данных Informix.

### Особенности импорта таблиц без первичного ключа {#nopk}

В каждой таблице YDB должен быть определён первичный ключ. При наличии у исходной таблицы первичного ключа (или, как минимум, уникального индекса) утилита импорта создаёт первичный ключ для соответствующей таблицы YDB с теми же колонками и в том же порядке, что и у исходной таблицы. При отсутствии первичного ключа и наличии нескольких уникальных индексов утилита выбирает индекс с минимальным количеством используемых колонок.

В случае отсутствия в исходной таблице явно определённого первичного ключа состав его колонок можно определить явным образом в настройках импорта соответствующей таблицы в виде элементов `key-column` раздела `table-ref` (см. далее пример в разделе с описанием формата файла настроек).

Если первичный ключ явно не указан в настройках, и отсутствует в определении исходной таблицы в БД-источнике, то утилита импорта автоматически добавляет в целевую таблицу колонку `ydb_synth_key` и создаёт первичный ключ на её основе. Значения колонки синтетического ключа вычисляются как хеш-код по алгоритму "SHA-256" над всеми значениями всех колонок строки таблицы, за исключением колонок типа BLOB.

При наличии в исходной таблице нескольких строк с полностью одинаковыми значениями, в целевую таблицу для каждого набора дубликатов будет в итоге записана одна строка. Это также означает, что утилита импорта не позволяет корректно загрузить данные из исходной таблицы, все колонки которой имеют тип BLOB.

### Особенности импорта больших объектов (BLOB, XML) {#blob}

Для каждого поля BLOB на источнике создаётся дополнительная таблица YDB следующей структуры:

```yql
CREATE TABLE `blob_table`(
    `id` Int64,
    `pos` Int32,
    `val` String,
    PRIMARY KEY(`id`, `pos`)
)
```

Формат имени дополнительной таблицы определяется настройкой `table-options` / `blob-name-format`.

Данные из исходного BLOB-поля сохраняются в виде последовательности записей созданной дополнительной таблицы.
Для каждого исходного BLOB-значения генерируется уникальное число, хранимое в поле `id`.
Ссылка на значение сохраняется в основной таблице в поле, имя которого соответствует имени исходного BLOB-поля.
Каждая запись хранит не более 64 Кбайт данных в поле `val`, последовательность блоков данных определяется значением поля `pos`.

Для PostgreSQL работа с данными BLOB в варианте `EXTENSION lo` может требовать явного предоставления специальных полномочий для учётной записи, используемой для подключения к БД-источнику.
Альтернативный вариант - установка режима совместимости на уровне базы данных PostgreSQL:

```yql
ALTER DATABASE dbname SET lo_compat_privileges TO on;
```

## Формат файла настроек {#config}

Примеры файлов настроек с комментариями:

* [для PostgreSQL](https://github.com/ydb-platform/ydb-importer/blob/main/scripts/sample-postgres.xml);
* [для MySQL](https://github.com/ydb-platform/ydb-importer/blob/main/scripts/sample-mysql.xml);
* [для Oracle Database](https://github.com/ydb-platform/ydb-importer/blob/main/scripts/sample-oracle.xml);
* [для Microsoft SQL Server](https://github.com/ydb-platform/ydb-importer/blob/main/scripts/sample-mssql.xml);
* [для IBM Db2](https://github.com/ydb-platform/ydb-importer/blob/main/scripts/sample-db2.xml);
* [для IBM Informix](https://github.com/ydb-platform/ydb-importer/blob/main/scripts/sample-informix.xml).

Пример и описание формата файла настроек приведены ниже.

```xml
<?xml version="1.0" encoding="UTF-8"?>
<ydb-importer>
    <workers>
        <!-- Количество рабочих потоков (целое число от 1 и выше).
             Также соответствует максимальному устанавливаемому количеству соединений с источником
             и максимальному количеству сессий с получателем.
         -->
        <pool size="4"/>
    </workers>
    <!-- Параметры подключения к БД-источнику.
         type - обязательный атрибут, влияющий на логику взаимодействия с источником
      -->
    <source type="generic|postgresql|mysql|oracle|mssql|db2|informix">
        <!-- Имя основного класса драйвера JDBC. Типичные значения:
              org.postgresql.Driver
              com.mysql.cj.jdbc.Driver
              org.mariadb.jdbc.Driver
              oracle.jdbc.driver.OracleDriver
              com.microsoft.sqlserver.jdbc.SQLServerDriver
              com.ibm.db2.jcc.DB2Driver
              com.informix.jdbc.IfxDriver
        -->
        <jdbc-class>driver-class-name</jdbc-class>
        <!-- URL JDBC для подключения к источнику. Примеры значений:
              jdbc:postgresql://hostname:5432/dbname
              jdbc:mysql://hostname:3306/dbname
              jdbc:mariadb://hostname:3306/dbname
              jdbc:oracle:thin:@//hostname:1521/serviceName
              jdbc:sqlserver://localhost;encrypt=true;trustServerCertificate=true;database=AdventureWorks2022;
              jdbc:db2://localhost:50000/SAMPLE
              jdbc:informix-sqli://localhost:9088/stores_demo:INFORMIXSERVER=informix
        -->
        <jdbc-url>jdbc-url</jdbc-url>
        <username>username</username>
        <password>password</password>
    </source>
    <!-- Параметры подключения к БД-получателю. -->
    <target type="ydb">
        <!-- Выгрузить скрипт создания таблиц для YDB в указанный файл.
             Может использоваться в том числе при отсутствии указания
             connection-string для генерации схемы без фактического создания
             таблиц.  -->
        <script-file>sample-database.yql.tmp</script-file>
        <!-- Строка подключения: protocol + endpoint + database. Примеры значений:
            grpcs://ydb.serverless.yandexcloud.net:2135?database=/ru-central1/b1gfvslmokutuvt2g019/etn63999hrinbapmef6g
            grpcs://localhost:2135?database=/local
            grpc://localhost:2136?database=/Root/testdb
         -->
        <connection-string>ydb-connection-string</connection-string>
        <!-- Режим аутентификации:
            ENV      использование переменных окружения для настройки аутентификации
            NONE     анонимное подключение к БД - не для продуктивных систем
            STATIC   аутентификация по логину и паролю
            SAKEY    Аутентификация по ключу сервисного аккаунта (управляемый сервис YDB)
            METADATA Аутентификация по метаданным виртуальной машины облака (управляемый сервис YDB)
        -->
        <auth-mode>ENV</auth-mode>
        <!--
            В режиме ENV данные аутентификации необходимо установить в переменных окружения,
            как описано в документации: https://ydb.tech/ru/docs/reference/ydb-sdk/auth#env
            Если аутентификация по ключу сервисного аккаунта (явно либо через указание переменной
            окружения YDB_SERVICE_ACCOUNT_KEY_FILE_CREDENTIALS), то файл ключа надо
            генерировать как написано здесь:
            https://cloud.yandex.ru/docs/iam/operations/authorized-key/create
        -->
        <!-- Логин и пароль для auth-mode: STATIC -->
        <static-login>username</static-login>
        <static-password>password</static-password>
        <!-- Удалять ли уже существующие таблицы с теми же именами, что предполагается заливать -->
        <replace-existing>false</replace-existing>
        <!-- Заливать ли данные в таблицы после их создания или пересоздания -->
        <load-data>true</load-data>
        <!-- Максимальная порция заливки обычных данных, в строках
             (используется при записи данных в основную таблицу) -->
        <max-batch-rows>1000</max-batch-rows>
        <!-- Максимальная порция заливки BLOB-данных, в строках
             (используется при записи данных в дополнительные таблицы для BLOB-полей) -->
        <max-blob-rows>200</max-blob-rows>
    </target>
    <!-- Настройки преобразования структуры исходных таблиц.
         Устанавливаются централизованно с присвоением имени,
         затем используются для конкретной группы отбираемых таблиц.   -->
    <table-options name="default">
        <!--  Возможные значения case-mode: ASIS (по умолчанию), LOWER, UPPER.
              Влияет на регистр подставляемых в шаблоны имён.  -->
        <case-mode>ASIS</case-mode>
        <!-- Шаблон полного имени таблицы, включая каталог размещения.
             Используются подстановочные имена ${schema} и ${table},
             соответствующие схеме и имени копируемой исходной таблицы. -->
        <table-name-format>oraimp1/${schema}/${table}</table-name-format>
        <!-- Шаблон полного имени таблицы, включая каталог размещения.
             Используются подстановочные имена ${schema}, ${table} и ${field},
             соответствующие схеме, имени копируемой исходной таблицы и имени
             поля типа BLOB. -->
        <blob-name-format>oraimp1/${schema}/${table}_${field}</blob-name-format>
        <!-- Возможные значения: DATE (по умолчанию), INT, STR.
             Вариант DATE не позволяет сохранить даты ранее 1 января 1970 года,
                 при попытке импорта неподдерживаемых значений будут возникать ошибки
             Вариант INT хранит дату как 32-битное целое в формате ГГГГММДД,
                 а для меток времени сохраняет количество миллисекунд как 64-битное целое
             Вариант STR хранит дату как строку в формате ГГГГ-ММ-ДД,
                 а для меток времени в формате "ГГГГ-ММ-ДД чч:мм:сс.xxx"
         -->
        <conv-date>INT</conv-date>
        <conv-timestamp>STR</conv-timestamp>
        <!-- Если указано значение true, колонки таблиц неподдерживаемых типов пропускаются
             с выводов в лог соответствующего предупреждения. В противном случае генерируется
             ошибка импорта, и соответствующая таблица пропускается целиком. -->
        <skip-unknown-types>true</skip-unknown-types>
    </table-options>
    <!-- Фильтр для отбора копируемых таблиц с источника -->
    <table-map options="default">
        <!-- Включаемые схемы -->
        <include-schemas regexp="true">.*</include-schemas>
        <!-- Исключаемые схемы -->
        <exclude-schemas>SOMESCHEMA</exclude-schemas>
        <!-- Также могут присутствовать include-tables и exclude-tables,
             для явного указания фильтра по именам таблиц
             и/или регулярным выражениям над именами таблиц. -->
    </table-map>
    <!-- Конкретный запрос или указание ссылки на конкретную таблицу -->
    <table-ref options="default">
        <schema-name>ora$sys</schema-name>
        <table-name>all_tables</table-name>
        <!-- Если указан запрос, он выполняется как написано -->
        <query-text>SELECT * FROM all_tables</query-text>
        <!-- Для запроса желательно явно определить ключевые колонки.  -->
        <key-column>OWNER</key-column>
        <key-column>TABLE_NAME</key-column>
    </table-ref>
</ydb-importer>
```
