PHP с начала своих времён славен (и критикуем) тем, что поддерживает интеграцию с массой библиотек, а также с практически со всеми СУБД существующими на рынке. Однако в силу каких-то странных причин в нём не было поддержки иерархических баз данных на глобалах.
Глобалы — это структуры для хранения иерархической информации. Они чем-то напоминают базы «key -> value» только с тем отличием, что ключ может быть многоуровневым:
В этом примере на встроенном языке ObjectScript в глобал ^inn, который хранится на жёстком диске (об этом говорит значок ^ перед названием глобала), сохраняется разноуровневая информация.
Естественно, для работы с глобалами из PHP нам потребуются новые функции, которые добавит PHP-модуль, о котором речь пойдёт ниже.
Глобалы поддерживают множество функций для работы с иерархичностью: обход ключей на каждом уровне отдельно, удаление, копирование и вставка целых деревьев и отдельных узлов. Ну а также как и любая хорошая БД ACID транзакции. Всё это происходит чрезвычайно быстро (порядка 105-106 операций вставки в секунду на обычном железе), по двум причинам:
Подробнее о глобалах в цикле статей «Глобалы — мечи-кладенцы для хранения данных»:
Деревья. Часть 1.
Деревья. Часть 2.
Разреженные массивы. Часть 3.
В этом мире глобалы нашли своё основное место применения в системах хранения малоструктрированной и разреженной информации такой как: медицинская, персональные данные, банковская сфера и т.п.
Я люблю PHP (и разрабатываю на нём) и хотел поиграться с глобалами. Готового модуля не было. Я написал в InterSystems c просьбой создать его. Ожидание ни к чему не привело, и в итоге мы (я вместе со своим студентом-дипломником) сделали модуль сами. InterSystems проспонсировала разработку в рамках образовательного гранта.
Вообще говоря, InterSystems IRIS — это мультимодельная СУБД, поэтому из PHP с ней можно работать через ODBC, используя SQL, но меня интересовали именно глобалы, а такого коннектора не было.
Итак, модуль доступен для PHP 7.x (тестировался под 7.0-7.2). На текущий момент он может работать только с InterSystems IRIS и Cache, установленной на том же хосте.
Страница модуля на OpenExchange (каталог проектов и дополнений для разработчиков на InterSystems IRIS и Cache).
Там есть полезный раздел DISCUSS, в котором люди делятся опытом использования.
Скачать тут:
Инструкция по установке модуля на английском и русском языках.
Функции модуля:
Если вы хотите самостоятельно поиграться с модулем, то:
В docker-контейнере на своём персональном компьютере (AMD FX-9370@4700Mhz 32GB, LVM, SATA SSD) для интереса я сделал два примитивных теста на скорость вставки новых значений в БД.
Понятно, что эти тесты не могут претендовать на точность и полезность, так как примитивны, сделаны в контейнере. На более мощном железе с дисковой системой на PCIe SSD можно добиться десятков миллионов вставок в секунду.
Для продакшена текущий модуль, пожалуй, ещё не готов: не было тестов под высокие нагрузки и на утечки памяти. Однако если это кому-то потребуется, то обращайтесь ко мне (Сергей Каменев updates@mail.ru).
Долгое время миры PHP и иерархических баз на глобалах практически не пересекались, хотя глобалы предоставляют сильный и быстрый функционал на специфических типах данных (медицинские, персональные).
Надеюсь, что этот модуль послужит толчком для экспериментов программистов PHP с глобалами и программистам ObjectScript для простой разработки веб-интерфейсов на PHP.
P.S. Спасибо за внимание!
Глобалы — это структуры для хранения иерархической информации. Они чем-то напоминают базы «key -> value» только с тем отличием, что ключ может быть многоуровневым:
Set ^inn("1234567890", "city") = "Moscow"
Set ^inn("1234567890", "city", "street") = "Req Square"
Set ^inn("1234567890", "city", "street", "house") = 1
Set ^inn("1234567890", "year") = 1970
Set ^inn("1234567890", "name", "fisrt") = "Vladimir"
Set ^inn("1234567890", "name", "last") = "Ivanov"
В этом примере на встроенном языке ObjectScript в глобал ^inn, который хранится на жёстком диске (об этом говорит значок ^ перед названием глобала), сохраняется разноуровневая информация.
Естественно, для работы с глобалами из PHP нам потребуются новые функции, которые добавит PHP-модуль, о котором речь пойдёт ниже.
Глобалы поддерживают множество функций для работы с иерархичностью: обход ключей на каждом уровне отдельно, удаление, копирование и вставка целых деревьев и отдельных узлов. Ну а также как и любая хорошая БД ACID транзакции. Всё это происходит чрезвычайно быстро (порядка 105-106 операций вставки в секунду на обычном железе), по двум причинам:
- Глобалы — это более низкоуровневая абстракция, чем SQL,
- Базы на глобалах уже в продакшене десятки лет и за это время код их успели вылизать и досконально оптимизировать.
Подробнее о глобалах в цикле статей «Глобалы — мечи-кладенцы для хранения данных»:
Деревья. Часть 1.
Деревья. Часть 2.
Разреженные массивы. Часть 3.
В этом мире глобалы нашли своё основное место применения в системах хранения малоструктрированной и разреженной информации такой как: медицинская, персональные данные, банковская сфера и т.п.
Я люблю PHP (и разрабатываю на нём) и хотел поиграться с глобалами. Готового модуля не было. Я написал в InterSystems c просьбой создать его. Ожидание ни к чему не привело, и в итоге мы (я вместе со своим студентом-дипломником) сделали модуль сами. InterSystems проспонсировала разработку в рамках образовательного гранта.
Вообще говоря, InterSystems IRIS — это мультимодельная СУБД, поэтому из PHP с ней можно работать через ODBC, используя SQL, но меня интересовали именно глобалы, а такого коннектора не было.
Итак, модуль доступен для PHP 7.x (тестировался под 7.0-7.2). На текущий момент он может работать только с InterSystems IRIS и Cache, установленной на том же хосте.
Страница модуля на OpenExchange (каталог проектов и дополнений для разработчиков на InterSystems IRIS и Cache).
Там есть полезный раздел DISCUSS, в котором люди делятся опытом использования.
Скачать тут:
https://github.com/intersystems-community/php_ext_irisСкачать репозиторий из командной строки:
git clone https://github.com/intersystems-community/php_ext_iris
Инструкция по установке модуля на английском и русском языках.
Функции модуля:
PHP-функция | Описание |
Работа с данными | |
---|---|
Установка узла.
|
|
Чтение узла. Возвращает: значение (число или строка), NULL (значение не определено) или FALSE (при ошибке).
|
|
Удаление значения узла. Возвращает: TRUE или FALSE — при ошибке. Важно отметить, что эта функция удаляет только значение в узле и не трогает нижележащие ветви.
|
|
Удаление узла и всех ветвей-потомков. Возвращает: TRUE или FALSE — при ошибке.
|
|
Обход ветвей глобала на заданном уровне Возвращает: массив, в котором содержится полное имя следующего узла глобала или FALSE (при ошибке).
|
|
Обход ветвей глобала на заданном уровне в обратном порядке Возвращает: массив, в котором содержится полное имя предыдущего узла глобала на этом же уровне или FALSE (при ошибке).
|
|
Обход ветвей глобала c заходом в низлежащие уровни Возвращает: массив, в котором содержится полное имя нижележащего узла (при наличии) или следующего узла глобала (при отсутствии вложенного узла).
Порядок отличается от порядка в котором мы устанавливали, так как в глобале автоматически при вставке всё сортируется по возрастанию. |
|
Сервисные функции | |
Установка директории с БД Возвращает: TRUE или FALSE — при ошибке.
Нужно выполнить перед соединением с базой. |
|
Выполнить команду БД Возвращает: TRUE или FALSE — при ошибке.
|
|
Подключиться к БД | |
Разорвать соединение с БД | |
Получить код ошибки | |
Получить текстовое описание ошибки |
Если вы хотите самостоятельно поиграться с модулем, то:
Специально для пользователей Хабра был создан Dockerfile для сборки образа.
Тестируем демо-страницу на localhost:52080 в браузере.
PHP файлы, которые можно править и играться с ними лежат в папке php/demo и будут подмонтированы внутрь контейнера.
Чтобы потестировать IRIS используйте логин admin, пароль SYS.
Чтобы войти в настройки IRIS используйте следующий УРЛ:
localhost:52773/csp/sys/UtilHome.csp
Чтобы войти в консоль IRIS этого контейнера используем команду:
git clone https://github.com/intersystems-community/php_ext_iris
cd php_ext_iris/iris
docker-compose build
docker-compose up -d
Тестируем демо-страницу на localhost:52080 в браузере.
PHP файлы, которые можно править и играться с ними лежат в папке php/demo и будут подмонтированы внутрь контейнера.
Чтобы потестировать IRIS используйте логин admin, пароль SYS.
Чтобы войти в настройки IRIS используйте следующий УРЛ:
localhost:52773/csp/sys/UtilHome.csp
Чтобы войти в консоль IRIS этого контейнера используем команду:
docker exec -it iris_iris_1 iris session IRIS
Специально для пользователей Хабра и InterSystems Cache была поднята виртуалка с php-модулем.
Для самостоятельной установки модуля под InterSystems Cache
- Иметь Linux. Я тестировал под Ubuntu, под Windows модуль тоже должен работать, но я не тестировал.
- Скачать бесплатную версию:
- InterSystems Cache (требуется регистрация). Из линуксов из коробки поддерживаются Red Hat и Suse, но поставить можно и на другие дистрибутивы.
- Установить модуль cach.so в PHP по инструкции.
В docker-контейнере на своём персональном компьютере (AMD FX-9370@4700Mhz 32GB, LVM, SATA SSD) для интереса я сделал два примитивных теста на скорость вставки новых значений в БД.
- Вставка 1 миллиона новых элементов в глобал заняла 1.81 секунды или 552К инсертов в секунду.
- Обновление значения в одном и том же глобале 1000000 раз заняла 1.98 секунды или 505K обновлений в секунду. Интересный факт, что вставка происходит, чем обновление. Видимо это следствие изначальной оптимизации базы данных под быструю вставку.
Понятно, что эти тесты не могут претендовать на точность и полезность, так как примитивны, сделаны в контейнере. На более мощном железе с дисковой системой на PCIe SSD можно добиться десятков миллионов вставок в секунду.
Что можно доделать и текущее состояние
- Можно добавить полезные функции для работы с транзакциями (их и сейчас можно использовать через iris_exec).
- Не реализована функция возврата всей структуры глобала, чтобы из PHP не заниматься обходом глобала.
- Не реализована функция сохранения PHP-массива как поддерева.
- Не реализован доступ к локальным переменным базы. Только через iris_exec, хотя лучше через iris_set.
- Не реализован обход глобала в глубь в обратном направлении.
- Не реализован доступ к БД через объект с использованием методов (аналогичным текущим функциям).
Для продакшена текущий модуль, пожалуй, ещё не готов: не было тестов под высокие нагрузки и на утечки памяти. Однако если это кому-то потребуется, то обращайтесь ко мне (Сергей Каменев updates@mail.ru).
Заключение
Долгое время миры PHP и иерархических баз на глобалах практически не пересекались, хотя глобалы предоставляют сильный и быстрый функционал на специфических типах данных (медицинские, персональные).
Надеюсь, что этот модуль послужит толчком для экспериментов программистов PHP с глобалами и программистам ObjectScript для простой разработки веб-интерфейсов на PHP.
P.S. Спасибо за внимание!
rjhdby
А почему именноiris_kill
? Неdelete
, неremove
?А, понял.