Pull to refresh
0
InterSystems
InterSystems IRIS: СУБД, ESB, BI, Healthcare

СУБД Caché. Деревообработка — SQL доступ к многомерным структурам данных

Reading time 5 min
Views 9.1K
«Caché предоставляет программистам свободу в выборе способа хранения и доступа к данным через объекты, SQL, либо путем прямого доступа к многомерным структурам данных. Независимо от способа доступа, все данные в базах данных Caché хранятся в многомерных массивах.»
Технологический справочник Caché

«Глобалы (глобальные хранимые переменные) – абстракция B-tree структур, используемых в MUMPS для хранения больших объемов данных.»
A Universal NoSQL Engine, Using a Tried and Tested Technology

В статье — пара примеров создания SQL проекций на различные структуры глобалов.

Для новых хранимых классов Caché автоматически использует стандартный способ хранения — CacheStorage. В каких случаях может понадобиться создание собственных способов хранения (CacheSQLStorage или CustomStorage)?

  • При модернизации MUMPS ( или переходе с GlobalsDB ) приложений, построенных на глобалах. Глобал часто используется как неформализованная (динамическая) структура, смысл узлов которой определяется соглашением разработчиков. Почему бы не формализовать эти соглашения (создать описание класса), подключить для них систему контроля версий и использовать все преимущества ООП разработки?
  • Для ряда специальных задач: классы с большим количеством свойств, свои классы-проекции на системные глобалы.

Немного теории


  • CacheStorage — используется Caché при компиляции новых хранимых классов. Методы для работы через SQL и объекты генерируются системой.
  • CacheSQLStorage — используется для работы с существующими глобалами через SQL. Создается программистом. В объектных методах доступа к данным (%SaveData, %LoadData, %DeleteData) используется SQL, соответственно, срабатывают триггеры. Необходимо настраивать SQL проекцию.
  • CustomStorage — используется для реализации собственной сложной логики объектного доступа. Создается программистом. Необходимо самостоятельно реализовать методы %SaveData, %LoadData, %DeleteData. Можно настроить SQL проекцию.

Для схемы хранения CacheSQLStorage (или CustomStorage) настраивается SQL проекция (SQL storage map). Проекция содержит необходимую для компилятора информацию о используемых глобалах, их ключах (subscripts), правилах прохода по ключам и расположении данных. На основании этой информации компилятор генерирует необходимые методы доступа к данным.

Больше практики


Разомнемся на простом примере из статьи A Universal NoSQL Engine. Телефонный справочник использует два глобала ^telephone — для хранения данных и ^nameIndex — для хранения индекса по владельцу телефонного номера.

Важным моментом создания SQL проекции является установка соответствия между ключами глобала данных и идентификатором объекта. В нашем случае это телефонный номер — первый ключ ^telephone.
  • Создадим новый хранимый класс data.phones (телефонный справочник), добавляем к нему свойства name, number, address и индекс по свойству number c типом IdKey.
  • Добавим к классу способ хранения CacheSQLStorage c именем sql. Создадим карту проекции на данные в глобали ^telephone с именем data. Карту начнем заполнять с определения ключей глобала. Добавляем первый ключ, указываем, что в этом ключе хранится свойство number
  • Переходим к описанию расположения значений свойств. Добавляем проекцию на свойство address. Указываем, что значения хранятся в узле с дополнительным (вторым) ключом «address». По умолчанию система предполагает хранение свойств в строке с разделителями. В нашем случае это не так. Поэтому убираем разделитель и номер позиции. Аналогично поступаем для свойства name — значение хранится в дополнительном ключе «name». Убираем разделитель и номер позиции. Компилируем класс. Проверяем работу проекции — выполняем запрос Select.
  • Добавляем проекцию на индексную глобаль. Создадим индекс по свойству name. Добавим карту (с типом индекс) на ^nameIndex. Добавляем описание ключей — первый ключ свойство name, второй ключ свойство — number. Компилируем класс. Смотрим план запроса на выборку из телефонного справочника с фильтрацией по полю name.


После настройки хранения выполните запросы insert, update, delete к классу data.phones. Попробуйте использовать объектный доступ к экземплярам класса (%New, %Save, %DeleteId). Обратите внимание на содержимое глобалей после выполнения операций.

Рассмотрим более сложный пример, характерный для унаследованных приложений. На входе глобал вида:
^dish(3)=«КАШИ»
^dish(3,315)=«Каша рисовая вязкая*200*178.2*3.1*4.4*33.7**гр*780»
^dish(3,315,2)=«Вода*161*161»
^dish(3,315,36)=«Крупа рисовая*43.6*43.6»
^dish(3,315,50)=«Масло сливочное*5*5»
^dish(3,316)=«Каша перловая вязкая*200*178.7*4.1*4.6*32.1**пор*4744»
^dish(3,316,2)=«Вода*161*161»
^dish(3,316,34)=«Крупа перловая*43.6*43.6»
^dish(3,316,50)=«Масло сливочное*5*5»
^dish(3,317)=«Каша овсяная вязкая*200*206.5*5.8*6.9*32**пор*6282»
^dish(3,317,2)=«Вода*157*157»
^dish(3,317,33)=«Крупа овсяная*49.0*49.0»
^dish(3,317,50)=«Масло сливочное*5*5»
^dish(3,318)=«Каша геркулесовая вязкая*200*192.2*5.7*6.8*28.6**пор*2436»
^dish(3,318,2)=«Вода*161*160»
^dish(3,318,3)=«Геркулес*43.6*43.6»
^dish(3,318,50)=«Масло сливочное*5*5»

Здесь в одном глобале хранятся объекты нескольких классов: dish.kind — тип блюда, dish.dish — блюдо, dish.product — продукт блюда. Причем структура глобала предопределяет тип отношений между этими классами — parent-child.


Особенностью настройки проекции для классов dish.dish и dish.product является синтаксис описания ключей глобала

Вместо имени свойства указывается имя parent класса и, после точки, имя его свойства — идентификатора.
Ускоренный процесс создания проекции:


Советы и секреты.


Настроенную проекцию Cache сохраняет в экземплярах классов:

Соответственно, создать хранение можно и программным способом. Например, сделать свой мастер создания схемы хранения. В Студии настроенный способ хранения отображается как xml (в Cache 2013.1 автоматически, а в более ранних версиях через меню: Вид — Показать хранение).

Для каждого хранимого класса Caché создает запрос Extent и генерирует программы его выполнения. Сгенерированный код класса может помочь в настройке или отладке проекции (см. метки zExtentExecute, zExtentFetch).

Интересные примеры проекций можно посмотреть в системных классах Caché. Например, вышеперечисленные классы схемы хранения — это проекция на глобал.

Более подробную информацию по настройке проекций можно прочитать в лекции Вадима Федорова со Школы инноваций Intersystems.
Tags:
Hubs:
+2
Comments 0
Comments Leave a comment

Articles

Information

Website
www.intersystems.com
Registered
Founded
1978
Employees
1,001–5,000 employees
Location
США