Что не так с общим Java-драйвером Neo4j, зачем нужен JDBC-драйвер, какие функции он поддерживает, а что не позволяет разработчику делать с этой графовой базой данных.
Что не так с общим Java-драйвером Neo4j и зачем нужен JDBC-драйвер
25 марта 2024 года вышла 6-я версия драйвера JDBC для графовой СУБД Neo4j, поддерживаемого с 2016 года. Хотя этот драйвер официально поддерживается и одобрен Neo4j, он не зависит от общего Java-драйвера Neo4j, обеспечивающего специфический для Neo4j способ доступа к этой БД из Java. Этот коннектор представляет собой комплексное решение, включающее пул подключений, управляемые транзакции и автоматические повторные попытки. Однако, если использовать поверх них другие драйверы или коннекторы, количество пулов многократно возрастает, поскольку JDBC-драйверы обычно помещаются в пулы соединений. Подробнее об этом мы писали здесь. Отсутствие какого-либо пула соединений и управления транзакциями является преимуществом JDBC-драйвера Neo4j по сравнению с обычным Java-драйвером. Это позволяет выбирать любую систему пула подключений к базе данных, например, HikariCP, и систему управления транзакциями, такую как Jakarta Transactions (Java Transaction AP). Этот API поддержки транзакций входит в стандарт серверной платформы для языка программирования Java (Jakarta EE) и определяет взаимодействие между менеджером транзакций и другими участниками распределённой транзакционной системы.
Кроме того, JDBC-драйвер Neo4j соответствует API JDBC 4.3, который включает пакеты java.sql и javax.sql. Этот полный API JDBC включен в Java Standard Edition (Java SE) версии 7. Пакет javax.sql расширяет функциональные возможности API JDBC от клиентского до серверного API и является важной частью технологии Java Enterprise Edition (Java EE). Пакет java.sql предоставляет API для доступа и обработки данных, хранящихся в источнике данных, с использованием языка программирования Java. Этот API включает в себя структуру, с помощью которой можно динамически устанавливать различные драйверы для доступа к различным источникам данных. Хотя API JDBC в основном предназначен для передачи SQL-операторов в базу данных, он обеспечивает чтение и запись данных из любого источника данных в табличном формате. Средство чтения/записи, доступное через группу интерфейсов javax.sql.RowSet, можно настроить для использования и обновления данных из электронной таблицы, плоского файла или любого другого источника табличных данных.
JDBC был выпущен вместе с JDK 1.1 19 февраля 1997 г как универсальный API доступа к БД. Он включает клиентские инструменты (DBeaver , IntelliJ DataGrip и пр.), ETL-инструменты (KNime, Tableau , Apache NiFi и т.д.), платформы и библиотеки программирования (Springs JDBC Template и JDBI, и т.п.). При том, что JDBC (Java Database Connectivity) означает Java-подключение к базе данных без привязки к реляционным моделям, JDBC находится под сильным влиянием стандарта SQL и существующих в реляционных СУБД терминов, определений и определенного поведения. Однако, Neo4j — это графовая база данных с совершенно другой парадигмой, что обусловливает некоторую адаптацию применения JDBC к этой СУБД.
Для JDBC-драйвера Neo4j требуется JDK 17 на стороне клиента и минимальная версия Neo4j 5.5 на стороне сервера. Чтобы использовать его в кластере Neo4j, надо включить маршрутизацию на стороне сервера. Драйвер имеет базовый уровень JDK 17 и полностью поддерживает модульную системы Java. Он соответствует JDBC 4.3 и может запускать любой Cypher-оператор. Реализует DatabaseMetaData и ResultSetMetaData с почти бессхемной базой данных и общими очень гибкими наборами результатов, позволяющими автоматически извлекать метаданные из ETL/ELT-инструментов. JDBC-драйвер предоставляет интерфейс поставщика услуг (SPI, service provider interface) для подключения перевода с SQL на Cypher и его дополнительную реализацию. Как уже было отмечено выше, JDBC-драйвер может безопасно использоваться с пулами JDBC-соединений в отличие от обычного Java-драйвера Neo4j или любого основанного на нем драйвера JDBC, поскольку он не выполняет внутреннее объединение пулов соединений и управление транзакциями, отличного от спецификации JDBC.
Варианты использования и ограничения JDBC-драйвера
Новый JDBC-драйвер 6 версии рекомендуется применять для всех приложений и инструментов, которые используют его предыдущие версии (4 или 5), а также имеют интеграции с SQL-платформами миграции данных и ETL-инструментами, которые не предлагают интеграцию на основе общего Java-драйвера Neo4j. Также он хорошо подходит для случаев, когда есть существующие интеграции, которые доступны только для чтения, но нужна и запись. Наконец, благодаря поддержке Jakarta EE, Spring JDBCTemplate и других универсальных возможностей JDBC API 4.3, он отлично пригодится при реализации распределенных транзакций.
Наконец, JDBC-драйвер Neo4j снижает порог входа в эту NoSQL-технологию для разработчиков, которые знакомы с JDBC и хотят продолжать использовать этот API, но с Cypher и графовой СУБД. При этом нет необходимости перепроектировать приложение, созданное на основе общего Java-драйвера Neo4j. Если экосистема уже обеспечивает интеграцию более высокого уровня на основе общего Java-драйвера Neo4j, например Spring Data Neo4j (SDN) для Spring, переход пройдет безболезненно. Однако, JDBC-драйвер не стоит использовать, когда приложение и так работает с общим Java-драйвером и изменения не требуются.
Также стоит отметить ограничения JDBC-драйвер Neo4j:
- метаданные базы данных извлекаются максимально эффективно с использованием существующих методов схемы Neo4j, таких как labels(), db.schema.nodeTypeProperties();
- узлы с несколькими метками не сопоставляются с названиями таблиц, в отличие от узлов с одной меткой;
- нет надежного способа всегда определять тип данных для свойств на узлах, не читая их все, чего драйвер не делает;
- некоторые функции JDBC еще не поддерживаются, например, CallableStatement(), а некоторые функции не будут поддерживаться никогда;
- транслятор SQL-запросов в Cypher поддерживает только ограниченное подмножество предложений и конструкций, которые могут быть семантически эквивалентны при переводе в Cypher;
- нет единого правильного способа сопоставить JOIN-утверждения с отношениями;
- не обеспечивается автоматическое изменение или выравнивание наборов результатов, как это было в предыдущей версии. При запросе узлов, связей, путей или сопоставлений, которые должны использовать метод getObject() в наборах результатов, их надо привести к соответствующему типу, который есть в пакете neo4j.jdbc.values. Однако, транслятор SQL в Cypher при подключении к базе данных выяснит, какие свойства имеют метки, и превратит * в отдельные столбцы узлов и связей, как это ожидается при выполнении оператора SELECT *.
Впрочем, несмотря на эти ограничения, новый JDBC-драйвер Neo4j предоставляет разработчику довольно много возможностей по работе с этой графовой СУБД. Например, другие драйверы с возможность перевода SQL в Cypher доступны только для чтения и не поддерживают операторы записи. Поэтому они не могут использоваться для сценариев использования ETL, направленных на передачу данных в Neo4j.
Узнайте больше про графовые СУБД и тонкости работы с ними для аналитики больших данных на специализированных курсах нашего лицензированного учебного центра обучения и повышения квалификации для разработчиков, менеджеров, архитекторов, инженеров, администраторов, Data Scientist’ов и аналитиков Big Data в Москве:
Источники