[
Выше] [Начало_этой_части] [Конец_этой_части] [Далее]===========================================
Глава 7 – Проецирование объекта в SQL
Эта глава содержит следующие темы:
Наследование и SQL
Выполнение проецирования
Проецирование в рамках класса
Мощная особенность Cache для объектов – способность взаимодействия объектов и SQL. Эта глава описывает, как проектировать объекты для доступа SQL (предполагается знание и опыт работы с SQL). Проецирование класса в SQL – это устанавление отношения между классом непосредственно и его представлением в виде таблицы (см. Глава 3, "Спецификация класса" для получения дополнительной информации о классах и их определении). Отмеченные функциональные возможности реализуются через единую архитектуру данных Cache, которая делает данные видимыми и в форме объектов, и в реляционной форме. В реляционной форме можно манипулировать данными, используя Cache SQL (высокоэффективная реляционная система базы данных, встроенная в ядро Cache).
Интеграция объектов Cache и Cache SQL позволяет приложению обращаться к классу или как к специфическому объекту, или как к части реляционной таблицы. Когда выполняется реляционное проецирование, то определение класса – это таблица: реализации – строки таблицы, а
свойства – столбцы таблицы. Это иллюстрируется на приводимом ниже рисунке:
Примечание: Некоторые особенности определения класса Cache не могут быть доступны, и как объекты, и как реляционные таблицы, скорее, из-за различий в природе объектных и реляционных моделей, чем из-за ограничений Cache или любых других инструментальных средств.
Так как наследование не поддерживается реляционной моделью, компилятор класса проектирует "плоское" представление класса в виде реляционной таблицы. Проектируемая таблица содержит все соответствующие поля для класса, включая те, которые унаследованы. Следовательно, проекция подкласса – таблица, содержащая:
Все столбцы в проекции суперкласса (это те, что базируются на всех атрибутах суперкласса)
Дополнительные столбцы, базирующиеся на атрибутах только подкласса
Подмножество строк в таблице суперкласса, которые состоят только из экземпляров подкласса
Например, проекция независимо хранимого класса по имени Пациент (который получен из класса Человек) - таблица, содержащая все поля, определенные и для класса Пациент, и для класса Человек:
Чтобы создать класс, который будет автоматически доступным в SQL, определяется класс, основанный на классе %Persistent, и используется класс в памяти, который включает проекцию таблицы, типа %CacheStorage или %CacheSQLStorage. Когда класс компилируется, компилятор класса Cache автоматически генерирует информацию, необходимую для реляционного доступа во время выполнения. Экземпляры класса становятся доступными как строки реляционной таблицы.
Хотя Cache не накладывает ограничений на использование специфических слов для имен классов, классы приложения не могут работать с SQL, если их имена – зарезервированные слова SQL. Если нужно, чтобы класс имел имя, которое является зарезервированным словом SQL, следует таблице, в которую будет помещен класс, дать другое имя. Чтобы выполнить это, следует использовать модификатор SQLTABLENAME, который имеет следующий синтаксис:
SQLTABLENAME = classnameforSQL;
Cписок зарезервированных слов SQL см. в разделе Зарезервированных слов SQL документации Cache.
В этом разделе описывается способ, с помощью которого различные объектные элементы класса переносятся в SQL. Короче говоря, проекция:
Из (объектная концепция) |
В (реляционная концепция) |
OID |
Поле идентификатора |
Атрибут типа данных |
Поле |
Встроенные (embedded) объекты |
Поля |
Атрибут списка |
Поле списка |
Атрибут массива |
Дочерняя (порожденная) таблица |
Ссылочный атрибут |
Ссылочное поле |
Индекс |
Индекс |
Метод |
Хранимая процедура (только методы класса) |
См. соответствующий раздел ниже для получения дополнительной информации.
Если приложение использует заданную по умолчанию структуру хранения, поддерживаемую классом памяти Cache Direct, и пользователь разрешает Cache назначать ID экземплярам класса, то все идентификаторы объекта (OID) автоматически проецируются в формат SQL.
Каждый хранимый класс проецируется в уникальную таблицу SQL, а каждая составляющая такого класса – в специфическую строку этой таблицы. Объект уникально идентифицирован его OID; в проекции класса в SQL, каждый экземпляр уникально определяется значением его положения в сгенерированном столбце (ID) идентификатора в таблице класса. Значение ID экземпляра в столбце – такое же как его OID.
Примечание: столбец идентификатора имеет имя "ID", если объект не имеет атрибут по имени ID; если объект имеет ID (с разницей в регистре), столбец идентификатора имеет имя "ID1". (Если имеется ID и атрибуты ID1, столбец идентификатора имеет имя "ID2" и так далее.)
Хотя в проекции (таблице) ID появляется как столбец, нет никакой необходимости в создании основанного на ID индекса – это уже IDKEY для таблицы; далее, ID не имеет эквивалентного атрибута, так что индекс, созданный специально для проекции класса SQL, не значим для класса непосредственно.
Следует отметить дополнительно, что нельзя выполнять операции UPDATE или INSERT на ID, так как Cache генерирует значения ID автоматически.
Например, чтобы добавить новый экземпляр класса в его проекцию, можно использовать такой синтаксис:
INSERT INTO PERSON
(FNAME, LNAME)
VALUES (:fname, :lname)
и нельзя:
INSERT INTO PERSON
(ID, FNAME, LNAME)
VALUES (:id, :fname, :lname)
Этот пример предполагает, что столбец ID для таблицы создан из OID класса.
Когда проецируется таблица, большинство свойств отображаются в ней как столбцы (поля), берущие имена от свойств объекта; исключение – массивы, которые по умолчанию проецируются как дочерние (порожденные) таблицы.
Все свойства класса (часто упоминаемые как атрибуты) проецируются со следующими исключениями:
Прозрачные атрибуты (Transient attributes)
Вычисляемые атрибуты (Calculated attributes)
Частные атрибуты (Private attributes)
Многомерные атрибуты (Multidimensional attributes) Имена свойств и имена столбцов
Если проецируемому столбцу свойства нужно дать другое (отличное от имени свойства объекта) имя, следует использовать модификатор свойства SQLFIEL
DNAME.Например, если бы имелось свойство, называемое "select", то его проецируемое имя можно определить так:
SQLFIELDNAME = selectfield;
Если имя свойства совпадает с зарезервированным словом SQL, нужно дать ему другое имя для проекции.
Cache автоматически назначает уникальный номер столбцу для каждого свойства. Если нужно управлять назначениями номера столбца, можно определить требуемый (не тот, что назначил Cache) номер столбца для проекции свойства. Чтобы сделать это, используется модификатор свойства SQLCOLUMNNUMBER, который имеет следующий синтаксис:
SQLCOLUMNNUMBER = 3
Значение, которое определяется для SQLCOLUMNNUMBER, должно быть целыи положительным числом, определяющим номер столбца свойства в проецируемой таблице. Если используется модификатор SQLCOLUMNNUMBER без параметра, Cache назначает столбцу номер, который не сохраняется и не имеет никакой постоянной позиции в столбцах таблицы.
Если любое из свойств класса имеет назначенный номер столбца SQL, то для других свойств номер столбца назначает Cache. Начальное значение для назначенных номеров столбца – номер после самого высокого указанного номера столбца SQL.
Значение модификатора SQLCOLUMNNUMBER наследуется.
Атрибуты-типы_данных объекта проецируются как поля, использующие категорию атрибута SQL (определяемую модификатором SQLCATEGORY) и любые из его параметров. И для реляционного, и для объектного доступа используются одинаковые классы типа данных, вызываются одинаковые методы типа данных, выполняющие проверку правильности и преобразования данных, и значения параметра типа данных используются одинаково. Это справедливо и для поставляемых в составе системы, и для пользовательских классов типа данных.
Например, следующее определение атрибута:
ATTRIBUTE Name {TYPE = %String(MAXLEN=30);}
проецируется как поле в реляционной таблице, содержащее строку с максимальной длиной 30 символов.
Атрибуты-ссылки (то есть ссылки к другим независимо хранимым объектам) проецируются как поля, содержащие часть OID упомянутого объекта.
Например, предположим, что объект "заказчик" имеет атрибут Rep, который обращается к объекту SalesRep (коммерческий представитель заказчика). Если "заказчик" имеет коммерческого представителя с ID 12, то вход в столбец Rep для этого заказчика – также 12. Так как это значение - cпецифическая строка столбца ID упомянутого объекта, можно использовать это значение при выполнении любых объединений (JOINs) или другой обработки.
Атрибуты встраиваемого объекта
Проекция атрибута встраиваемого объекта приводит к образованию множественных столбцов в таблице. Один столбец в проекции содержит полный объект, преобразованный в последовательную форму (включая все разделители и управляющие символы); остальная часть столбцов – каждый для одного атрибута объекта.
Имя столбца для объектного атрибута – такое же как у соответствующего атрибута объекта. Другие имена столбцов составлены из имени объектного атрибута, символа подчеркивания и атрибута в рамках встраиваемого объекта.
Например, предположим, что встраиваемый объект – тип Adress с атрибутом по имени Home; сам Home имеет атрибуты, которые включают Street и Country. Проекция встраиваемого объекта тогда включает столбцы по имени Home_Street и Home_Country. (Обратите внимание, что имена столбцов получены из атрибута Home, а не из типа Adress.)
Встраиваемые объекты могут также включать другие комплексные формы данных:
Проекция атрибута ссылки имеет поле только для чтения, которое включает объектную ссылку.
Проекция массива – это одиночный, недоступный для редактирования столбец, который является частью таблицы класса.
Проекция списка – как поле списка одного из его проецируемых полей. Атрибуты массива
Проекция атрибута массива – дочерняя (порожденная) таблица. Имя этой дочерней (порожденной) таблицы – конкатенация имени класса, содержащего атрибут массива, и имени атрибута массива (если контейнерный класс или атрибут массива не объявляют имя SQL).
Например, класс Person (человек) с атрибутом массива, имеющим имя Siblings, имеет проекцию как дочернюю (порожденную) таблицу по имени Person_Siblings.
В дочерней (порожденной) таблице имеются по крайней мере три столбца:
Столбец, содержащий ID каждого объекта в классе; его имя – как у класса, содержащего массив (Person, в примере).
Столбец, содержащий идентификатор для каждого элемента массива; его имя – всегда element_key.
Столбец, содержащий членов массива для всех объектов класса; его имя – имя атрибута массива класса (Siblings, в примере).
Продолжая пример класса Person с атрибутом массива по имени Siblings, проекция Person включает дочернюю (порожденную) таблицу Person_Siblings со следующими входами:
Person (ID) |
element_key |
Siblings |
10 |
C |
Claudia |
10 |
T |
Tom |
12 |
B |
Bobby |
12 |
C |
Cindy |
12 |
G |
Greg |
12 |
M |
Marsha |
12 |
P |
Peter |
Следует обратить внимание, что в родительской таблице нет столбца Siblings.
Для столбца (цов), содержащего членов массива, номер и содержание столбца (цов) зависит от вида массива:
Проекция массива атрибутов типа данных – одиночный столбец данных.
Проекция массива атрибутов ссылки – одиночный столбец объектных ссылок.
Проекция массива встраиваемых объектов – множественные столбцы в дочерней (порожденной) таблице.
Суммируя выше сказанное, важно отметить следующее: ID каждого объекта и идентификатор каждого элемента массива имеет уникальный индекс для дочерней (порожденной) таблицы. Также, если объект не имеет никакого массива, связанного с ним, то нет никаких связанных входов в дочерней (порожденной) таблице.
Атрибуты списка проецируются как поля списка, что означает, что все элементы в пределах совокупности связаны и проецируются как одиночная строка.
Например, пусть класс Person имеет атрибут списка Cars, где Cars – список строк, которые являются номерными знаками автомобиля. Этот атрибут появляется как одиночный столбец по имени "Car" и мог бы появляться в проекции Person следующим образом:
ID |
Cars |
1 |
324WLI,395BCE,974HFK |
2 |
209NLE |
3 |
263AKF,253COM |
Поле списка содержит строку, полученную путем конкатенации индивидуальных элементов списка:
New cars
&sql(SELECT Cars
INTO :cars
FROM Person
WHERE ID = :id)
Принимая значение идентификатора 3, автомобили имеют эквивалент значения списка: строки "263AKF" и "253COM".
И символьные атрибуты потока, и двоичные атрибуты потока проецируются как объекты BLO (binary large objects – двоичные большие объекты).
Прозрачные (Transient) и вычисляемые (Calculated) атрибуты
Так как прозрачный процесс и вычисляемые атрибуты не хранятся на диске, по умолчанию, они не имеют проекции SQL
.Например, на диаграмме ниже, атрибут RevDate класса Employee прозрачный, и он не включается в проекцию класса:
Чтобы включить эти столбцы в проекцию, используется модификатор SQLCOMPUTED, который позволяет определять код, который вычисляет значение вычисляемого поля SQL для атрибута; можно тогда добавлять код к определению атрибута, которое вычисляет значение проецируемого поля. Атрибут, проецируемый как вычисляемое поле, может обеспечивать параллельный объект и функциональные возможности SQL через параллельные вычисления.
Имеются два способа включения кода для атрибута вычисляемого поля SQL:
Записать код, который выполняет вычисления, требуемые для определения значения вычисляемого поля и сопоставиь его с модификатором SQLCOMPUTEDCODE. Записать код, который выполняет вычисления, требуемые для определения значения вычисляемого поля и разместить его в методе класса. Вызвать этот метод класса из кода, связанного с модификатором SQLCOMPUTEDCODE (для проекции SQL) и из атрибута метода Get() (для объекта непосредственно).
С любым подходом, этот код может включать значения, основанные на других атрибутах и системно- основанных значениях. Можно вызывать методы класса и внешние функции.
Методы класса доступны только через объектное представление класса. Методы, определенные некоторыми классами, не доступны через SQL потому, что запрос SQL не делает объекты открытыми для доступа (следовательно, их методы не доступны). Методы класса, однако, являются доступными для использования с кодом вычисляемого поля.
Поскольку SQL Cache поддерживает триггеры, любой триггер, связанный с классом, включается как часть проекции класса в SQL.
===========================================
[
Содержание_документа] [Конец_документа][
Выше] [Начало_этой_части] [Конец_этой_части] [Далее]===========================================
По вопросам поддержки любых продуктов InterSystems Corporation обращайтесь:
Россия 121019, Москва, Волхонка, 6, #14
Тел
.: +7 095 203-4649Факс
: +7 095 956-8268 info@intsys.dol.ru http://www.intersystems.ru
Copyright © 1999, InterSystems Corporation. Все права защищены.