Brief: исполнение
Хранимые данные и материализации
В базе данных хранятся первичные (DATA) свойства — все, кроме локальных, которые хранят значения только в рамках сессии, — и вычисляемые свойства, помеченные опцией MATERIALIZED: их значения лежат в поле таблицы, автоматически обновляются при изменении данных, от которых свойство зависит, и читаются прямо из базы. Отдельными полями хранятся принадлежность объекта классу (_CLASS_ИмяТаблицы) и признак полноты таблицы (_FULL_ИмяТаблицы) — последний только там, где полнота не обеспечена уже самим содержимым таблицы: таблица, хранящая принадлежность классу для всех потомков класса своего ключа, помечается полной сама и такого поля не получает.
Материализовать свойство можно тогда и только тогда, когда наборов объектов с не NULL значением у него конечное число. Материализация переносит стоимость с чтения на запись: значение не вычисляется при каждом обращении, но обновляется при каждом изменении исходных данных. Механизм — материализации.
sum = GROUP SUM sum(OrderDetail od) BY order(od) MATERIALIZED;
Аналогия: материализованное представление базы данных, обновляемое сразу при изменении исходных данных.
Таблицы и имена в БД
Таблица объявляется инструкцией TABLE:
TABLE name [dbName] (className1, ..., classNameN) [FULL | NODEFAULT];
Классы задают ключевые поля key0, ..., key(N-1) — по одному на класс, с нумерацией от нуля, — остальные поля — значения свойств. Таблицу свойства задаёт опция TABLE; без неё свойство попадает в ближайшую по классам ключей таблицу, NODEFAULT исключает таблицу из выбора, а без подходящей создаётся таблица _auto_.... FULL означает, что таблица содержит все объекты классов своих ключей, и влияет только на выполнение запросов. Механизм — таблицы.
Имена зависят от политики именования (db.namingPolicy):
| Политика | Таблица | Поле |
|---|---|---|
| С сигнатурой (умолчание) | Пространство_Таблица | Пространство_Свойство_Класс1_..._КлассN |
| Без сигнатуры | Пространство_Таблица | Пространство_Свойство |
| Краткая | Таблица | Свойство |
Индексы
Индекс по одному свойству создаётся опцией INDEXED, индекс по произвольному списку полей одной таблицы — инструкцией INDEX:
INDEX [dbName] [indexType] field1, ..., fieldN;
Индексировать можно только материализованные свойства. В составной индекс входят и материализованные свойства, и параметры, указывающие на ключевые поля; он должен содержать хотя бы одно материализованное свойство, а все свойства в нём — храниться в одной таблице и использовать один и тот же набор параметров. Типы LIKE и MATCH сохраняют обычный индекс и пытаются добавить специализированные — LIKE добавляет индекс LIKE, а MATCH на строковом поле добавляет сразу MATCH и LIKE, — что на строковых полях происходит только если у текущего адаптера БД включена поддержка триграмм / полнотекстового поиска, а на одиночном поле TSVECTOR MATCH создаёт только специализированный GIN-индекс. Уникальный индекс по всем ключам таблицы и индексы по суффиксам ключей keyK, ..., keyN создаются автоматически. Механизм — индексы.
orderDate = DATA DATE (Order) INDEXED;
INDEX supplier(Sku s, DATE d), s, price(s, d), d;
Пересчёт материализаций
Оператор RECALCULATE создаёт действие, которое заново вычисляет хранимые значения материализованного свойства из его определения:
RECALCULATE [CLASSES | NOCLASSES] propertyId(expr1, ..., exprN) [WHERE whereExpr]
К пересчёту обращаются, когда хранимые значения могли разойтись с определением, — после изменения определения свойства или прямого исправления данных в базе. WHERE ограничивает пересчитываемые наборы аргументов, CLASSES пересчитывает только данные о классах, NOCLASSES — только значения.
recalculateSum() {
RECALCULATE sum(Order o);
}