Главная » SQL, Базы данных » ОПРЕДЕЛЕНИЯ ТИПОВ И ФОРМАТОВ ПРЕДСТАВЛЕНИЯ

0

Выше в данной главе уже было кратко указано, что существует логическое различие между типом как таковым, с одной стороны, и физическим представлением значений этого типа в системе, с другой стороны. Фактически типы относятся к уровню модели,

3 Точнее, эта операция не может окончиться неудачей из-за ошибки во время прогона программы, связанной с несоответствием  типов.  В  этой  книге  принято  достаточно  обоснованное   предположение,   что  в  системе предусмотрена проверка типов во время компиляции (или так называемая  "статическая" проверка); очевидно, что ошибка во время прогона программы не может возникнуть, если проверка во время компиляции прошла успешно.

а форматы физического представления — к уровню реализации. Например,  номера  поставщиков могут быть физически представлены в виде символьных строк, но из этого не следует, что нам дано право выполнять над номерами поставщиков такие же операции, как над символьными строками; точнее, мы можем выполнять подобные операции, но лишь при том условии, что для данного типа определены соответствующие операторы. Кроме того, операторы,  определяемые для данного конкретного типа, должны естественным образом  зависеть от намеченного назначения рассматриваемого типа, а не от способа,  выбранного для физического представления значений этого типа; в действительности, эти физические форматы представления должны быть скрытыми от пользователя. Иными словами, различие, которое мы проводим между типом и физическим представлением, является одним из важных аспектов независимости от данных (см. главу 1).

Кстати, следует отметить, что типы данных (особенно определяемые  пользователем) в литературе иногда называют абстрактными типами данных, или сокращенно ADT (Abstract Data Type), чтобы подчеркнуть такую их особенность; дело в том, что мы обязаны различать типы и форматы их физического представления. Но в данной книге этот термин не используется,  поскольку он наводит на мысль, что могут существовать некоторые типы, не  являющиеся в этом смысле "абстрактными", а автор считает, что следует всегда учитывать различие между типом и его физическим представлением.

Определения скалярных и нескалярных типов

Любой отдельно взятый тип может быть либо скалярным, либо нескалярным. Определения этих понятий приведены ниже.

■     Нескалярным (nonscalar) называется тип, значения которого явно определены как имеющие множество видимых пользователю, непосредственно доступных компо нентов. В частности, в этом смысле являются нескалярными типы отношения (см. главу 6), поскольку отношения имеют такие видимые пользователю компоненты, как кортежи и атрибуты. (Кроме того, в свою очередь, типы кортежа также явля ются нескалярными, поскольку кортежи имеют такие видимые пользователю компоненты, как значения атрибутов.)

■     Скалярным (scalar) называется тип, который не является нескалярным (!).

Примечание. Вместо термина скалярный иногда используются также термины инкапсулированный (encapsulated) и атомарный (atomic); термин атомарный особенно часто применяется в реляционных контекстах (включая предыдущие издания этой книги). Для ознакомления с термином инкапсулированный обратитесь к главе 25.

Значения типа т являются скалярными или нескалярными в соответствии с тем, является ли скалярным или нескалярным сам тип т; поэтому нескалярное значение имеет множество видимых пользователю компонентов, а скалярное  значение не имеет такового. Аналогичные замечания относятся к переменным, атрибутам, операторам, параметрам и выражениям в целом, но с соответствующими оговорками.

Возможные форматы представления, селекторы и операторы ТНЕ_

Допустим, что т — скалярный тип. Выше было показано, что физическое представление значений типа т скрыто от пользователя. В действительности, такие представления могут быть сколь угодно сложными (в частности, они вполне могут состоять из нескольких

компонентов), но еще раз подчеркнем, что все подобные компоненты должны  быть скрыты от пользователя. Однако задача состоит в том, чтобы значения типа т имели хотя бы один возможный формат представления4 (объявленный в составе определения типа т) и чтобы любой такой возможный формат представления не был скрытым от пользователя; в частности, все эти форматы должны иметь видимые пользователю компоненты. Но следует учитывать, что  рассматриваемые  компоненты являются не компонентами типа, а компонентами  данного возможного формата представления, тогда как тип как таковой все еще остается скалярным в том смысле, какой был описан выше. В качестве иллюстрации рассмотрим определяемый пользователем тип QTY (сокращение от quantity — количество), определение которого на языке Tutorial D может выглядеть примерно следующим образом.

TYPE QTY POSSREP { INTEGER } ;

В этом определении типа, по сути, сказано, что значения количества "могут  быть представлены" с помощью целых чисел. Таким образом, объявленное  возможное представление (possible representation — possrep), безусловно, имеет  видимые пользователю компоненты (фактически оно имеет точно один такой  компонент, типа INTEGER), НО понятие количества как таковое не имеет подобного компонента.

Ниже приведен еще один пример, позволяющий более наглядно подчеркнуть эту же

мысль.

TYPE POINT     /* Геометрические точки в двухмерном пространстве */ POSSREP CARTESIAN { X RATIONAL, Y RATIONAL P} POSSREP OLAR { R RATIONAL, 0 RATIONAL } ;

Приведенное здесь определение типа POINT включает объявления двух  различных возможных форматов представления, CARTESIAN И POLAR,  отражающих тот факт, что точки в двухмерном пространстве действительно "могут быть представлены" с помощью декартовых (CARTESIAN) ИЛИ полярных (POLAR) координат. Каждый из этих возможных форматов представления имеет в свою очередь два компонента, причем оба они относятся к типу                                                                                     5. Но важно отметить, что тип POINT как таковой (еще раз подчеркнем) все еще остается скалярным — он не имеет видимых пользователю компонентов.

Примечание. Мы принимаем такое соглашение о синтаксисе, что если некоторый заданный тип т имеет возможное представление без явно  определенного имени, то это возможное представление по умолчанию принимает имя т. Мы также принимаем соглашение, что если заданное возможное представление PR имеет компонент без явного имени, то этот компонент по умолчанию получает имя PR. Кроме того, применение каждого объявления POSSREP влечет за собой автоматическое определение перечисленных ниже операторов, которые в основном не требуют пояснений.

4  За исключением того случая, когда тип Т является "фиктивным" (см. главу 20).

5  В языке Tutorial D используется тип RATIONAL, более точно определенный по сравнению с при вычным типом REAL. Следует отметить, что тип RATIONAL может также служить примером встроенного типа, имеющего больше чем одно возможное объявленное представление. Например, выражения 530.00 и 5.3Е2 вполне могут соответствовать одному и тому же значению RATIONAL; это означает, что оба они могут стать следствием разных, но эквивалентных вызовов двух различных селекторов RATIONAL (более подробно об этом будет сказано ниже).

▪      Оператор-селектор, который позволяет пользователю определять или выбирать значение рассматриваемого типа, предоставляя некоторое значение для каждого компонента возможного представления.

■     Множество операторов ТНЕ_ (по одному для каждого компонента возможного представления), которые позволяют пользователю обращаться к соответствующим компонентам возможного представления значений рассматриваемого типа.

Примечание. Под утверждением, что объявление POSSREP вызывает "автоматическое определение" этих операторов, подразумевается, что тот "деятель" (возможно система, а может быть, и какой-то пользователь), который отвечает за реализацию рассматриваемого типа, несет также ответственность за реализацию самих операторов.

Ниже в качестве примера представлены некоторые вызовы операторов-селекторов и оператора ТНЕ_ для типа POINT.

CARTESIAN ( 5.0, 2.5 )

/* Выбирает точку с координатами х = 5.0, у = 2.5 */

CARTESIAN ( X1, Y1 )

/* Выбирает точку с координатами х = X1, у = Y1, где */

/* X1 и Y1 переменные типа RATIONAL                                                                                  */

POLAR ( 2.7, 1.0 )

/* Выбирает точку с координатами r = 2.7, 8 = 1.0 */

ТНЕ_Х ( Р )

/* Обозначает координату х точки в */

/* Р, где Р переменная типа POINT */

THE_R ( P )

/* Обозначает координату r точки в Р */

THE_Y ( ехр )

/* Обозначает координату у точки, обозначенной */

/* выражением ехр (которое относится к типу POINT) */

Обратите внимание на то, что селекторы имеют такое же имя, как соответствующее возможное представление, а операторы ТНЕ_ имеют имена в форме ТНЕ_С, где с— имя соответствующего компонента соответствующего возможного представления. Обратите также внимание на то, что селекторы (или, точнее, вызовы селекторов) представляют собой обобщение более известного  понятия литерала (все литералы являются вызовами селекторов, но не все вызовы селекторов могут рассматриваться как литералы; в действительности вызов селектора является литералом, если и только если все его фактические параметры в свою очередь являются литералами).

Для того чтобы определить, как описанные выше синтаксические конструкции могут применяться на практике, предположим, что физическое представление точек фактически является множеством декартовых координат (но в общем не требуется, чтобы физическое представление было идентично любому из объявленных возможных представлений). В таком случае в системе могут быть предусмотрены некоторые в высшей степени защищенные операторы, отличающиеся тем, что за ними следует псевдокод, обозначенный курсивом, который по сути предоставляет доступ к этому физическому представлению, а

реализатор типа (type implementer) использует эти операторы для реализации необходимых селекторов CARTESIAN И POLAR. Безусловно, что такой реализатор типа является (а фактически и должен быть) исключением из того общего правила, что пользователи не обязаны учитывать физические представления. Соответствующий пример приведен ниже.

OPERATOR CARTESIAN ( X RATIONAL, Y RATIONAL ) RETURNS POINT ; BEGIN ;

VAR P POINT ;                                          /* P переменная типа POINT */

<компонент X физического представления Р := Х> ;

<компонент Y физического представления Р := Y> ; RETURN ( P ) ; END ; END OPERATOR ;

OPERATOR POLAR ( R RATIONAL, Q RATIONAL ) RETURNS POINT ; RETURN ( CARTESIAN ( R * COS ( Q ) , R * SIN ( Q ) ) ) ;

END OPERATOR ;

Отметим, что в определении POLAR используется селектор CARTESIAN, а также операторы SIN и COS (предполагается, что они являются встроенными). Иным образом, определение POLAR может быть выражено непосредственно в терминах защищенных операторов, как показано ниже.

OPERATOR POLAR ( R RATIONAL, Q RATIONAL ) RETURNS POINT ; BEGIN ;

VAR P POINT ;

<компонент X физического представления Р : = R * COS ( Q)> ;

<компонент Y физического представления Р :R * SIN ( Q )>

; RETURN ( P ) ; END ; END OPERATOR ;

В конструкции реализатора типа также используются эти защищенные операторы для реализации необходимых операторов ТНЕ_ следующим образом.

OPERATOR ТНЕ_Х ( Р POINT    ) RETURNS RATIONAL ; RETURN ( <компонент X    физического представления

Р> ) ;

END OPERATOR ;

OPERATOR THE_Y ( P POINT    ) RETURNS RATIONAL ; RETURN ( <компонент Y    физического представления

Р> ) ;

END OPERATOR ;

OPERATOR THE_R ( P POINT    ) RETURNS RATIONAL ; RETURN ( SQRT ( THE_X     ( P ) ** 2 + THE_Y ( P )

** 2 ) ) ;

END OPERATOR ;

OPERATOR THE_Q ( P POINT    ) RETURNS RATIONAL ; RETURN ( ARCTAN ( THE_Y ( P ) / THE_X ( P ) )

) ; END OPERATOR ;

Обратите внимание на то, что в определениях THE_R и ТНЕ_Q используются операторы ТНЕ_Х и THE_Y, а также операторы SQRT и ARCTAN (при этом подразумевается , что

они являются встроенными). Иным образом, операторы THE_R и ТНЕ_0 могут быть определены непосредственно в терминах защищенных операторов (их практическое осуществление оставляем читателю в качестве упражнения).

Очевидно, что пример реализации типа POINT является очень наглядным. Но важно понять, что все эти описанные концепции применимы также к более  простым типам6, например, к типу QTY. Ниже приведены некоторые примеры вызова селекторов для этого типа.

QTY ( 100 ) QTY ( N )

QTY ( N1 N2 )

А ниже приведены некоторые примеры вызова операторовТНЕ_.

THE_QTY ( Q ) THE_QTY ( Ql Q2 )

Примечание. В этих примерах предполагается, что N, N1 и N2 — переменные  типа INTEGER, что Q, Q1 и Q2 — переменные типа QTY и что "-" представляет  собой полиморфный оператор, который применяется и к целым числам, и к значениям количества.

Итак, поскольку значения всегда типизированы, высказывания, подобные  тем, "что количество в определенной поставке равно 100", являются крайне недопустимыми. Количество — это значение типа QTY, а не значение типа INTEGER! Поэтому применительно к рассматриваемой поставке мы обязаны применять более правильный способ

обозначения количества — QTY(IOO), а не просто указывать число 100 как таковое. Но в неформальном общении мы обычно не стремимся соблюдать такие  требования к точности, поэтому используем (например) 100, как удобное сокращение для QTY(100). В частности, следует отметить, что подобные сокращения применяются также в определениях баз данных поставщиков и деталей, а также поставщиков, деталей и проектов (см. рис. 3.8 и 4.5, приведенные, соответственно, на стр. 119 и 154).

Ниже приведен еще один пример определения типа.

TYPE LINESEG POSSREP { BEGIN POINT, END POINT } ;

Тип LINESEG определяет отрезки прямых. Данный пример иллюстрирует такую особенность, что любое конкретное возможное представление может быть задано в терминах определяемых пользователем типов, а не только с помощью типов, определяемых системой, как во всех предыдущих примерах (иными словами, определяемый пользователем тип является таким же полноценным, как и определяемый системой).

Наконец, следует отметить, что во всех примерах этого подраздела, касающихся возможных представлений и связанных с ними конструкций, рассматривались только скалярные типы. Но возможные представления имеют и нескалярные типы. Мы вернемся к этому вопросу в разделе 5.6.

6 Это утверждение является справедливым также и по отношению, в частности, ко встроенным типам, несмотря на то, что при определении соответствующих селекторов и операторов ТНЕ_ иногда могли  применяться немного иные синтаксические и другие правила по сравнению с описанными в этом  разделе  (отчасти это обусловлено исторически сложившимися причинами). Дополнительные сведения приведены в [3.3].

Источник: Дейт К. Дж., Введение в системы баз данных, 8-е издание.: Пер. с англ. — М.: Издательский дом «Вильямс», 2005. — 1328 с.: ил. — Парал. тит. англ.

По теме:

  • Комментарии