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

0

В языке Tutorial D новые типы могут быть введены либо с помощью оператора TYPE, применение которого уже было показано в некоторых примерах  предыдущего раздела, либо с помощью определенного генератора типа. Отложим обсуждение генераторов типа и связанного с этим вопроса о том, как следует определять нескалярные типы, до раздела 5.6, а в этом разделе рассмотрим более подробно оператор TYPE. Ниже в качестве примера приведено определение скалярного типа WEIGHT.

TYPE WEIGHT POSSREP { D DECIMAL (5,1)

CONSTRAINT D > 0.0 AND D < 5000.0 } ;

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

Примечание. Приведенное выше предложение в целом представляет собой ограничение типа для типа WEIGHT. В общем ограничение типа для типа т представляет собой не что иное, как определение множества значений, из которых состоит тип т. Если какое-то объявление POSSREP не содержит явной спецификации CONSTRAINT, то по умолчанию

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

Но пример определения типа WEIGHT наводит еще на одну мысль. В раздел 3.9 главы

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

TYPE WEIGHT

POSSREP LBS { L DECIMAL (5,1)

CONSTRAINT L > 0.0 AND L < 5000.0

} POSSREP GMS { G DECIMAL (7,1)

CONSTRAINT G > 0.0 AND G < 2270000.0

AND MOD ( G, 45.4 )= 0.0 };

Следует отметить, что оба объявления POSSREP включают спецификацию CONSTRAINT и эти две спецификации являются логически эквивалентными (MOD — это оператор, который принимает два числовых операнда и возвращает остаток от деления первого операнда на второй; в целях упрощения предполагается, что 1 фунт = 454 грамма). Из этого определения следуют приведенные ниже выводы.

■   Если W— выражение типа WEIGHT, то оператор THE_L(W) возвратит  значение DECIMAL( 5 , 1),  представляющее  соответствующий  вес  в  фунтах,  а  оператор THE_G(W) возвратит значение DECIMAL ( 7 , 1),  представляющее тот же вес в граммах.

176    Часть II. Реляционная модель

■     Если  N—   выражение  типа  DECIMAL ( 5 , 1),   то  оба  выражения,   LBS(N)   и

GMS (454*N), возвращают одно и тоже значение WEIGHT.

Ниже приведены описания синтаксиса Tutorial D, применяемого для определения

скалярного типа.

<type def>                                             ::= TYPE <type name>

<possrep def list>  ;

<possrep  def>

: : =   POSSREP  [  <possrep name>  ]

{   <possrep  component  def commalist>

[  <possrep constraint  def>  ]   }

<possrep  component   def>

::=   [  <possrep component name>  ]  <type name>

<possrep  constraint  def>

: : =   CONSTRAINT <bool

exp>

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

1.         В этом синтаксисе используются и списки (list), и списки, разделенные запяты ми (commalist). Термин разделенный запятыми список был определен в главе 4 (раздел 4.6); термин список определяется аналогично, следующим образом. Пред положим, что <xyz> обозначает произвольную синтаксическую категорию (т.е. всё, что может находиться в левой части некоторого порождающего правила в форме Бэкуса-Наура). В таком случае выражение <xyz  list> обозначает после довательность от нуля или больше категорий <xyz>, в которой каждая пара смеж ных категорий <xyz> разделена одним или несколькими пробелами.

2.         Список <possr ер def I is t> должен содержать по меньшей мере одно определе ние возможного представления <possrep  def>, а разделенный запятыми список

<possrep  component  def  commalist> должен содержать по меньшей мере одно определение компонента возможного представления <possrep component

def>.

3.         Квадратные скобки " [" и " ] " показывают, что заключенный в них материал явля ется необязательным (как обычно принято в системе обозначений в форме БэкусаНаура). В отличие от этого, фигурные скобки "{" и "}" обозначают сами себя; иначе говоря, они являются синтаксическими символами в определяемом языке, а не (как обычно) символами метаязыка. Вернее, фигурные скобки используются для включения разделенных запятыми списков элементов, если разделенный за пятыми список предназначен для обозначения множества определенного рода (при этом, кроме всего прочего, подразумевается, что порядок, в котором элемен ты присутствуют в разделенном запятыми списке, является несущественным, а также подразумевается, что ни один элемент не может появиться в списке больше одного раза).

4.         В общем выражение <bool  ехр> (сокращение от "boolean expression" — логиче ское выражение) обозначает истинностное значение (TRUE или FALSE). В данном контексте выражение <bool   ехр> не должно указывать на какие-либо перемен ные, но конструкции с обозначением имен компонентов возможного представле ния <possrep  component  name> из содержащего их определения <possrep

def> могут использоваться для обозначения соответствующих компонентов при менимого возможного представления произвольного значения рассматриваемого скалярного типа.

Примечание. Логические выражения называются также условными, истинностными

или булевыми выражениями.

5.         Отметим, что в определениях типа < type  def> абсолютно ничего не сказано о физических представлениях. Вместо этого подобные представления должны быть определены в составе "концептуального-внутреннего" отображения (см. главу 2, раздел 2.6).

6.         Определение нового типа вынуждает систему внести в свой каталог запись с опи санием этого типа (сведения о каталоге приведены в главе 3, раздел 3.6). Анало гичные замечания относятся также к определениям операторов (см. раздел 5.5).

Ниже приведены определения скалярных типов, используемых в базе  данных  поставщиков и деталей, которые будут широко использоваться в дальнейшем (за исключением типа WEIGHT, который уже рассматривался выше). В целях упрощения спецификации CONSTRAINT ОПущеНЫ.

TYPE S#  POSSREP { CHAR } ; TYPE NAME POSSREP { CHAR } ; TYPE P#   POSSREP { CHAR } ;

TYPE COLOR                                        POSSREP    {    CHAR } ;

TYPE QTY POSSREP { INTEGER } ;

(Как было указано в главе 3, атрибут поставщика STATUS и атрибуты CITY поставщика и детали определены в терминах встроенных типов, а не определяемых пользователем типов, поэтому определения типов, соответствующие этим атрибутам, не показаны.)

Безусловно, должна быть также предусмотрена возможность избавиться от некоторого типа, если его применение в дальнейшем не предусмотрено, как показано ниже.

DROP TYPE <type name> ;

Здесь конструкция < type name> должна обозначать определяемый пользователем, а не встроенный тип. Эта операция вызывает удаление из каталога записи с описанием этого типа, а это означает, что в дальнейшем рассматриваемый тип становится неизвестным  для  системы.  В  целях  упрощения  предполагается,  что  операция  DROP  TYPE оканчивается неудачей, если рассматриваемый тип все еще где-то используется, в частности, если на его основе определен некоторый атрибут некоторой переменной отношения в той или иной базе данных.

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

значения типа INTEGER). Поэтому единственное, что происходит при  выполнении  так называемой операции "определения типа" (например, оператора TYPE языка Tutorial D), представляет собой не что иное, как введение некоторого имени, с помощью которого в дальнейшем можно будет ссылаться на это множество значений. Аналогичным образом, оператор DROP TYPE фактически  уничтожает не соответствующие значения, а просто имя, введенное с помощью соответствующего оператора TYPE.

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

По теме:

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