Как быстро загрузить в СУБД РЕД База Данных большое количество данных в формате CSV
В работе с информационными системами часто требуется загружать в базу данных большие объёмы информации из внешних источников. Один из самых популярных форматов — CSV (Comma‑Separated Values). Его поддерживает почти любое ПО для работы с таблицами. Типичные сценарии загрузки:
- экспорт из других систем;
- данные из внешних API;
- логи, телеметрия, результаты мониторинга;
- импорт справочников (номенклатура, контрагенты, сотрудники);
- периодическая загрузка от поставщиков.
Пример задачи: компания ежедневно получает от партнёров отчёты о транзакциях в CSV (2–5 млн записей, 500 МБ – 2 ГБ). Эти данные нужно быстро загружать в центральную БД для анализа и отчётности.
Проблемы при использовании традиционных подходов:
- Низкая производительность — 100–500 записей в секунду, что неприемлемо для миллионов строк.
- Сетевые накладные расходы — каждый запрос требует обмена с сервером.
- Нагрузка на ресурсы сервера — память, диск, журнал транзакций.
- Длительные блокировки и риск простоев.
- Сложность обеспечения атомарности — нужно либо загрузить все данные, либо ничего.
- Безопасность — требуется контроль доступа к файлам на уровне ОС.
В этом пособии рассмотрим решение на примере СУБД РЕД База Данных с использованием механизма внешних таблиц (External Tables) и адаптера CSV.
Загрузка внешних данных в РЕД База Данных
Для самостоятельного повторения понадобится:
- Рабочий компьютер с Windows 10/11 или Linux 64‑bit (подойдёт любой дистрибутив, но рекомендуется РЕД ОС 8).
- Установленная и настроенная СУБД РЕД База Данных версии 5.0 или выше. Если позволяет память, можно установить прямо на рабочий компьютер; если сервер удалённый — нужен доступ к его файловой системе и настроенное подключение к БД.
- Инструмент для выполнения SQL. Подойдёт штатный
isqlиз дистрибутива, но удобнее работать в графическом «РБДЭксперт» (скачивается с сайта РЕД СОФТ).
Практический пример рассмотрим для RedOS 8, и ОС Windows 10, так как настройка работы с External Files имеет заметные различия в зависимости от операционной системы сервера СУБД.
Создадим таблицу RESPONSES (отзывы покупателей) в демонстрационной БД «Marketplace» и загрузим в неё почти 400 000 записей.
Шаг 1. Создать БД и подключиться
Запустите терминал (или CMD в Windows) и выполните:
isql -u SYSDBA -p <пароль SYSDBA>
Для пароля по умолчанию:
isql -u SYSDBA -p masterkey
Увидите приглашение SQL> — вы вошли в утилиту.
Теперь создайте новую базу данных (или подключитесь к существующей).
Физически БД — это один файл, который СУБД создаёт в указанной директории на сервере.
Создание новой БД:
CREATE DATABASE "server:port/path/dbname.fdb" USER 'SYSDBA' PASSWORD 'masterkey';
Где:
server— IP‑адрес или имя сервера,port— порт сервера,path— полный путь к файлу БД на сервере,dbname.fdb— имя файла (обычно расширение.fdb, но можно любое).- Указываются имя и пароль пользователя, который станет владельцем этой БД.
Пример для локального сервера Linux:
CREATE DATABASE "localhost:/var/_db/MP_SYNT.FDB" USER 'SYSDBA' PASSWORD 'masterkey';
В конце обязательно ставится точка с запятой.
В Linux имена и команды чувствительны к регистру.
Важно: путь должен быть доступен для записи процессу сервера СУБД. Подробнее — в Руководстве администратора.
Если база уже существует, подключитесь к ней:
CONNECT "localhost:/var/_db/MP_SYNT.FDB";
Шаг 2. Создать пустую таблицу для загрузки
Выполните в isql:
CREATE TABLE RESPONSES (
RESPONSE_ID BIGINT GENERATED BY DEFAULT AS IDENTITY (START WITH 1),
PRODUCT_ID BIGINT NOT NULL,
CUSTOMER_ID BIGINT NOT NULL,
RATING DECIMAL(2,1) NOT NULL,
"COMMENT" BLOB SUB_TYPE TEXT,
RESPONSE_DATE TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT CK_INTEG_RATING CHECK (rating >= 0 AND rating <= 5),
CONSTRAINT PK_RESPONSES_TUT PRIMARY KEY (RESPONSE_ID)
);
COMMIT;
SHOW TABLE RESPONSES;
Вывод должен быть примерно таким:
RESPONSE_ID BIGINT Not Null Identity (by default)
PRODUCT_ID BIGINT Not Null
CUSTOMER_ID BIGINT Not Null
RATING DECIMAL(2, 1) Not Null
COMMENT BLOB segment 80, subtype TEXT Nullable
RESPONSE_DATE TIMESTAMP WITH TIME ZONE Nullable DEFAULT CURRENT_TIMESTAMP
CONSTRAINT PK_RESPONSES_TUT:
Primary key (RESPONSE_ID)
CONSTRAINT CK_INTEG_RATING:
CHECK (rating >= 0 AND rating <= 5)
Обратите внимание:
RESPONSE_ID— автоинкрементный ID, СУБД заполняет его сама.- Тип
COMMENT—BLOB.
Шаг 3. Настроить сервер СУБД
По умолчанию работа с внешними таблицами на сервере запрещена. Чтобы разрешить, отредактируйте файл конфигурации firebird.conf. Он лежит в корне установки Ред Базы:
- Linux:
/opt/RedDatabase/firebird.conf - Windows:
%ProgramFiles%\RedDatabase\firebird.conf
Откройте файл с правами администратора (sudo / «Запуск от имени администратора»).
Найдите параметр ExternalFileAccess и измените его:
Linux:
ExternalFileAccess = Restrict /var/ExternalCSV
Для Windows:
ExternalFileAccess = Restrict C:\Data_ext
Можно указать несколько каталогов через точку с запятой.
Значение Full допустимо, но небезопасно — не используйте в production.
После изменения перезапустите службу Ред Базы.
Шаг 4. Скопировать CSV‑файл на сервер
Служба СУБД должна иметь доступ на чтение к директории и файлам CSV. Выберите место на сервере, скопируйте туда файл responses.csv и настройте права.
Linux
# создали директорию
sudo mkdir /var/ExternalCSV
# назначили владельца и права доступа
sudo chown reddatabase:reddatabase /var/ExternalCSV
sudo chmod 770 /var/ExternalCSV
# копируем файл, например
sudo cp responses.csv /var/ExternalCSV/
sudo chmod 660 /var/ExternalCSV/responses.csv
Windows
Создайте папку, например C:\Data_ext, скопируйте в неё responses.csv.
В свойствах папки → «Безопасность» добавьте учётную запись, от которой запущена служба Ред Базы (обычно LocalSystem или специальный пользователь), и дайте ей права на чтение.
Шаг 5. Создать внешнюю таблицу
Важно: внешняя таблица не хранит данные — это лишь «окно» в CSV‑файл. Она описывает структуру, а сервер при каждом запросе читает файл с диска.
Для Windows (путь с двойными обратными слешами):
CREATE TABLE CSV_RESPONSES
EXTERNAL FILE 'C:\\Data_ext\\responses.csv'
ADAPTER 'CSV'
(
PRODUCT_ID INTEGER,
CUSTOMER_ID INTEGER,
RATING DECFLOAT(16),
COMMENT VARCHAR(8191),
RESPONSE_DATE TIMESTAMP WITH TIME ZONE
);
COMMIT;
Для Linux:
CREATE TABLE CSV_RESPONSES
EXTERNAL FILE '/var/ExternalCSV/responses.csv'
ADAPTER 'CSV'
(
PRODUCT_ID INTEGER,
CUSTOMER_ID INTEGER,
RATING DECFLOAT(16),
COMMENT VARCHAR(8191),
RESPONSE_DATE TIMESTAMP WITH TIME ZONE
);
COMMIT;
В описании нет автоинкрементного поля (в CSV оно отсутствует), а BLOB заменён на VARCHAR(8191) — внешние таблицы не поддерживают BLOB.
Шаг 6. Проверить внешнюю таблицу
-- Общее количество строк
SELECT COUNT(*) FROM CSV_RESPONSES;
-- Первые 3 записи (без COMMENT, он длинный)
SELECT FIRST 3 PRODUCT_ID, CUSTOMER_ID, RATING, RESPONSE_DATE FROM CSV_RESPONSES;
Ожидаемый вывод:
COUNT
=====================
399237
PRODUCT_ID CUSTOMER_ID RATING RESPONSE_DATE
========== =========== ====== =========================================================
2785 11278 5.0 2025-11-07 05:08:51.0000 +03:00
3733 11278 4.0 2025-11-01 05:08:51.0000 +03:00
5393 11278 5.0 2025-11-03 05:08:51.0000 +03:00
Шаг 7. Загрузить данные в регулярную таблицу
Перед загрузкой убедимся, что целевая таблица пуста:
SELECT COUNT(*) FROM RESPONSES; -- должно быть 0
Теперь пробуем вставить все данные напрямую:
INSERT INTO RESPONSES SELECT * FROM CSV_RESPONSES;
Возникает ошибка:
Statement failed, SQLSTATE = 21S01
-Count of read-write columns does not equal count of values
Причина: в целевой таблице на одно поле больше (RESPONSE_ID). Нужно явно перечислить столбцы, которые берутся из CSV:
INSERT INTO RESPONSES (PRODUCT_ID, CUSTOMER_ID, RATING, COMMENT, RESPONSE_DATE)
SELECT * FROM CSV_RESPONSES;
Загрузка 400 тысяч строк занимает несколько секунд (зависит от мощности сервера). Проверяем:
SELECT COUNT(*) FROM RESPONSES; -- 399237
COMMIT;
Шаг 8. Обработка ошибок и валидация (загрузка с проверкой дубликатов)
Если CSV содержит поле RESPONSE_ID и целевая таблица уже не пуста, можно загружать только новые записи:
INSERT INTO RESPONSES (RESPONSE_ID, PRODUCT_ID, CUSTOMER_ID, RATING, COMMENT, RESPONSE_DATE)
SELECT e.RESPONSE_ID, e.PRODUCT_ID, e.CUSTOMER_ID, e.RATING, e.COMMENT, e.RESPONSE_DATE
FROM CSV_RESPONSES e
WHERE NOT EXISTS (
SELECT 1 FROM RESPONSES t
WHERE t.RESPONSE_ID = e.RESPONSE_ID
);
COMMIT;
Осторожно: если вы вставляете
RESPONSE_IDвручную, а поле объявлено какGENERATED BY DEFAULT, конфликтов не будет, но нумерация может сбиться. Для надёжности лучше не передавать внешний ID или использоватьGENERATED ALWAYS.
Шаг 9. Очистка (опционально)
После загрузки CSV‑файл можно удалить средствами ОС:
- Linux:
rm /var/ExternalCSV/responses.csv - Windows:
del C:\Data_ext\responses.csv
Это можно сделать не прерывая сеанса isql:
Linux:
SQL>
SQL> shell rm /var/ExternalCSV/responses.csv
Windows:
SQL>
SQL> shell del C:\Data_Ext\responses.csv
Внешняя таблица CSV_RESPONSES останется в БД. Если в тот же каталог поместить новый файл с тем же именем и структурой, данные станут доступны через эту же таблицу.
Мы успешно загрузили большой объём данных. Теперь разберёмся, как это работает.
Как это работает
Что такое внешние файлы?
Внешние файлы (External Files) — механизм, позволяющий таблице БД читать данные из текстового файла, лежащего вне базы. Метаданные таблицы хранятся внутри БД, а сами данные — в файле на диске сервера.
РЕД База поддерживает два формата:
- строки фиксированной длины;
- CSV (через адаптер).
Во внешних таблицах нельзя использовать типы BLOB и массивы, а также индексы, первичные и внешние ключи.
Адаптер CSV
Этот адаптер позволяет интерпретировать CSV‑файл как набор строк и столбцов.
Принцип работы:
- При создании внешней таблицы с
ADAPTER 'CSV'СУБД сохраняет только описание структуры. - При каждом
SELECTона открывает файл, читает его построчно и преобразует строки в записи согласно описанию колонок. - Разделитель — запятая
,(без пробелов). - Пустые строки игнорируются.

Допустимые операции
Для внешних таблиц в формате строк фиксированной длины разрешены SELECT и INSERT (добавление в конец файла).
Для CSV — только SELECT. Попытка выполнить INSERT или UPDATE вызовет ошибку. CSV-файлы можно изменять только внешним приложением.
Ограничения внешних таблиц
- Типы данных — любые, кроме
BLOBи массивов. - Нельзя создавать ограничения (PRIMARY KEY, FOREIGN KEY, UNIQUE).
- Нельзя создавать индексы.
- Нельзя указать табличное пространство.
- Количество столбцов в таблице может не совпадать с числом полей в CSV:
- если меньше — недостающие поля получают
NULL; - если больше — лишние игнорируются;
- если пропущено значение (две запятые подряд) — поле становится
NULL.
- если меньше — недостающие поля получают
- При ошибке конвертации типа — выбрасывается исключение.
Требования к CSV‑файлам
| Требование | Описание |
|---|---|
| Разделитель | Только запятая ,, без пробелов |
| Кодировка | Рекомендуется UTF‑8 (должна совпадать с кодировкой сервера) |
| Заголовки | Не поддерживаются — файл должен содержать только данные |
| Пустые строки | Игнорируются |
Экранирование: значения с запятыми, кавычками или переводами строк заключаются в двойные кавычки. Внутренние кавычки удваиваются.
Пример корректного CSV:
01/03/1997,TESCO,"EVERY LITTLE HELPS"
10/05/1967,M&M,"MELTS IN YOUR MOUTH, NOT IN YOUR HANDS"
06/23/1954,Disneyland,"I'm going to ""Walt Disney World""!"
07/15/1934,,JUST DO IT,aaa,bbb
Требования к директориям и путям
- Файл должен быть доступен серверу по полному пути.
- Процесс сервера СУБД должен иметь права на чтение (для CSV этого достаточно).
Важно: пути с пробелами (даже в кавычках) не работают. Сетевые пути (UNC) также не поддерживаются.
Особенности для Windows:
- Указывайте букву диска, например
'D:\externals\table.csv'. - Можно использовать как обратный слеш
\, так и прямой/. - Права настраиваются через свойства папки (учётная запись службы).
Особенности для Linux:
- Путь в формате UNIX:
'/var/lib/reddb/import/products.csv'. - Права через
chmod/chown, пользователь обычноfirebirdилиreddatabase.
Важное замечание: путь интерпретируется на сервере БД, а не на клиенте. Если вы подключаетесь удалённо, CSV должен лежать на сервере, а не на вашей рабочей станции.
Сравнение с альтернативными подходами
| Критерий | Внешние таблицы | INSERT | ETL‑инструменты |
|---|---|---|---|
| Скорость | Высокая | Низкая | Средняя / высокая |
| Сложность реализации | Низкая | Низкая | Средняя |
| Гибкость | Средняя | Высокая | Высокая |
| Требования | Доступ к ФС сервера | Сеть | Дополнительное ПО |
| Стоимость | Бесплатно | Бесплатно | Часто платно |
Достоинства внешних таблиц
- Высокая производительность — прямое чтение с диска без буферизации, тысячи записей в секунду.
- Простота — стандартный SQL, ничего не нужно устанавливать.
- Транзакционность — загрузка происходит в рамках транзакции, возможен откат (ROLLBACK).
- Гибкость — можно фильтровать, преобразовывать и объединять с другими таблицами прямо в запросе.
- Безопасность — управляется правами СУБД и ограничением
ExternalFileAccess.
Недостатки внешних таблиц
- Только чтение — для CSV нельзя ни вставлять, ни обновлять, ни удалять.
- Зависимость от ФС — нужен доступ к файловой системе сервера и настройка прав.
- Ограничения формата — только текстовые файлы, строгие правила CSV.
- Полное сканирование — при каждом запросе читается весь файл, индексы отсутствуют.
- Слабая валидация — ошибки в данных могут прервать загрузку.
Заключение
Мы на практике применили механизм внешних таблиц CSV в РЕД База Данных для загрузки почти 400 тысяч записей. Этот подход даёт высокую скорость, простоту и транзакционную целостность.
Основные выводы:
- Внешние таблицы с адаптером CSV — эффективный инструмент для массовой загрузки.
- Требуют настройки
ExternalFileAccessи прав на файлы. - Подходят для разовых и регулярных импортов, если данные не нужно модифицировать через SQL.
Рекомендации:
- Проверяйте права доступа к каталогам и файлам.
- Тестируйте на небольших файлах перед боевой загрузкой.
- Используйте транзакции для атомарности.
- Валидируйте CSV‑файлы до импорта.
- Ограничивайте
ExternalFileAccessтолько нужными папками. - Логируйте процесс для упрощения отладки.
Типичные ошибки:
- Неправильный путь (особенно в Windows).
- Отсутствие прав на чтение у службы СУБД.
- Несоответствие типов данных.
- Неправильная кодировка (например, BOM в UTF‑8).
- Использование
ExternalFileAccess = Fullв production.
Если вы нашли этот материал полезным, поэкспериментируйте с загрузкой своих данных — и вы убедитесь, как просто и быстро можно перенести миллионы строк из CSV в базу.
Дата последнего изменения: 14.09.2026
Если вы нашли ошибку, пожалуйста, выделите текст и нажмите Ctrl+Enter.