Коль скоро COPY – ваш лучший друг, присмотритесь к бинарному формату. В среднем он на 30% меньше, чем текстовый и CSV. Числа хранятся компактно, а не по принципу “байт на разряд”. Строки не экранируются. Это очень удобно: не нужно бежать по строке и проверять, есть ли обратный слэш и что-то за ним. Прочитал байтовый массив, обернул в (new String) и готово.

Бинарный формат COPY в целом прост. Первые 19 байтов можно пропустить – это заголовок и резерв под флаги, которые в данный момент не используются. Далее идет набор строк. Каждая строка – это пара (int2, content), где int2 – число колонок. Оно одинаково для всех строк, но дублируется. Последняя строка содержит -1, а за ней ничего нет.

С свою очередь content – это набор пар (int4, field) – длина поля и его содержимого. Если длина -1, то значение null, а содержимого нет. В зависимости от типа поле читают по-разному. Перечислять все типы и их особенности я не буду: для этого есть библиотеки. Радует, что библиотек для бинарного формата Postgres все больше: в Гугле находятся версии для Python, Node.js, Go и так далее. Среди прочих есть и мои реализации: pg-bin на Кложе и модуль org.pg.codec на Джаве в составе pg2.

Возня с бинарным форматом помогла мне понять, как лучше хранить данные, передавать по сети, как ускорить их обработку. В целом, поковыряться с байтами – хорошее дело: развивает кодерские навыки, поддерживает форму.