Текст
                    ПРЕДЛОЖЕНИЯ
КОДАСИЛ
ПО УПРАВЛЕНИЮ
БАЗАМИ ДАННЫХ

Т, В. ОЛЛЕ ПРЕДЛОЖЕНИЯ КОДАСИЛ ПО УПРАВЛЕНИЮ БАЗАМИ ДАННЫХ Перевод с английского В. И. Филиппова и С. М. Круговой МОСКВА «ФИНАНСЫ И СТАТИСТИКА» 1981
THE CODASYL APPROACH TO DATA BASE MANAGEMENT T. WILLIAM OLLE A. Wiley-Interscience Publication JOHN WILEY & SONS CHICHESTER , NEW YORK * BRISBANE « TORONTO
ББК 32Й73 0-53 х EC804-iO I ° oio(oi)-si s03"81 2405000000 © 1978, by John Wilev and Sons, Ltd. © Перевод на русский язык, предисловие к русскому изданию, «Финансы и ста-, тистика», В 981,
ПРЕДИСЛОВИЕ К РУССКОМУ ИЗДАНИЮ Советский читатель уже имел возможность познакомиться с основ- ными концепциями предложений КОДАСИЛ — Ассоциации по язы- кам систем обработки данных (Conference on DAta SYstems Languages) по книгам «Информационные системы общего назначения» (М., Ста- тистика, 1975) и «Организация баз данных в вычислительных систе- мах» Дж. .Мартина (М., Мир, 1980). Недавно вышел в свет на рус- ском языке и Отчет Комитета по языку описания данных (КЯОД) КОДАСИЛ 1978 г., содержащий последнюю версию спецификаций язы- ка описания данных и проект спецификаций языка описания хранения данных (Язык описания данных КОДАСИЛ. М., Статистика, 1981). Кроме того, в различных сборниках и научных журналах за послед- ние годы опубликован ряд статей, которые посвящены отечественным и зарубежным системам управления базами данных (СУБД), основан- ным на предложениях КОДАСИЛ. Однако все перечисленные выше работы предназначены, скорее, для специалистов по СУБД, тогда как широкий круг читателей-пользователей испытывает острую необхо- димость в пособии, полно и подробно комментирующем формальные тексты предложений. Таким «введением» в базы данных КОДАСИЛ, удачно дополняющим как его формальные спецификации, так и ру- ководства по конкретным системам, и является настоящая книга. Пользователь чаще всего знакомится с концепциями баз данных именно через руководство по конкретной системе, отражающее лишь выбранные разработчиком для реализации свойства. Но даже эти свойства в подобном руководстве не могут быть раскрыты полностью, так как составитель должен для этого исследовать историю их возник- новения, сравнить с другими подходами, оценить сегодняшнее состоя- ние и указать возможное развитие. Работы исследовательского характера чаще всего лишь слегка ка- саются истории вопроса, бегло излагают текущее положение дел и пе- реходят к основному — к критике и предложениям по улучшению. В отличие от таких работ в книге Т. В. Олле достаточно полно пред- ставлен исторический обзор, обстоятельно и наглядно изложено се- годняшнее состояние и крайне осторожно рассмотрены наиболее ве- роятные перспективы на будущее. Основная часть книги посвящена изложению предложенных КОДАСИЛ средств структуризации данных — Язык?! описания дан- ных (ЯОД) схемы и подсхемы, и средств манипулирования данными — Языка манипулирования данными (ЯМД). В первых двух главах да- ется исторический обзор развития предложений КОДАСИЛ и рассмат- ривается общая архитектура современных СУБД. В третьей главе вводятся основные структурирующие понятия — тип записи и тип набора, а з последующих восьми главах детально изучаются различ- ные стороны синтаксического представления и практического ис- пользования этих понятий для определения структур баз данных. Из- 5
ложение иллюстрируется примерами наиболее часто встречающихся структур и соответствующих синтаксических описаний. Глава 12 по- священа концепции подсхемы, т. е. средствам определения подструк- тур данных, и хотя синтаксическое оформление этих средств здесь су- щественно связано с Коболом, все основные понятия и возможности легко переносятся на другие включающие языки программирования. В главах 13—17 рассматриваются общие аспекты применения и кон- кретные варианты операторов ЯМД, причем для каждого оператора исследуются различные способы использования в зависимости от тех или иных определений схемы. Средства контроля доступа к базам дан- ных вынесены в отдельную главу, и автор здесь не только представля- ет идеи КОДАСИЛ, но и выдвигает собственные предложения по «язы- ку защиты данных». Наконец, главы 19 и 20 посвящены «языку опи- сания хранения данных» и проблемам реструктуризации (изменения структуры уже функционирующих баз данных). Читатель заметит, что формальные спецификации в предлагаемой книге несколько отстают от предложений Отчета КЯОД 1978 г. Од- нако подобное пособие и не может претендовать на полное соответствие не только потому, что предложения КОДАСИЛ быстро развивались за последние годы, а для написания и издания книги требуется опре- деленное время, но также и потому, что в ней должен учитываться и обобщаться опыт реализации и эксплуатации конкретных СУБД, соз- данных по предложенным спецификациям. Рассмотрение же таких понятий, как «способ размещения записей» и «вид представления на- бора», не в главе, посвященной языку описания хранения данных, а в разделах, относящихся к языку описания данных, уже не может из- менить i ix роли в общей системе концепций баз данных, тем более что и сам автор неоднократно обращается к проблеме классификации пред- лагаемые возможностей с точки зрения обеспечения «независимости представления данных». И все-таки, читая книгу, полезно сравнивать ее положения со спецификациями Отчета КЯОД 1978 г., чтобы выявить общее направление развития предложений КОДАСИЛ. Начинающе- му читателю рекомендуется сначала освоить книгу Т. В. Олле, а уже потом знакомиться с текущим состоянием формальных спецификаций. Значительным достоинством рассматриваемой работы является концептуально и терминологически единое изложение языков описания и манипулирования данными, а также подробное исследование средств контроля доступа к базе данных и реструктуризации. Это осо- бенно важно в связи с тем, что предложения КОДАСИЛ по определе- нию поде хем и языку манипулирования данными в нашей стране пол- ностью етде не опубликованы. Болытой интерес представляют последние главы книги, посвящен- ные другжпм подходам, а именно системам TOTAL, IMS, ADABAS и ре- ляционной модели. Заметим, что сравнительное описание хотя бы двух различных систем является нелегкой задачей. Дело в том, что, несмот- ря на концептуальную общность подходов, среди конкретных СУБД царит «терминологический Вавилон» — практически совпадающие по- нятия обозначаются разными терминами и, что еще хуже, один и тот же центральный термин иногда означает существенно различные поня- 6
тия (например, «запись» в спецификациях КОДАСИЛ и IMS). Поэтому многие работы обзорного характера ограничиваются лишь изложени- ем возможностей рассматриваемых систем с использованием специфи- ческой терминологии данной системы. Читателю при этом трудно выяснить, что общего у предлагаемых систем и чем они различаются. Т. В. Олле выбрал более эффективный метод описания. Представ- ляя то или иное свойство рассматриваемой системы (в терминах этой системы), он тут же указывает его концептуальный и терминологичес- кий эквивалент в подходе КОДАСИЛ, подчеркивая имеющиеся рас- хождения и ограничения, а в заключение проводит общий анализ из- ложенных средств, вновь сравнивая их с комплексом средств предло- жений КОДАСИЛ. Тем самым все рассмотренные подходы приводят- ся к единой концептуально-терминологической «шкале» КОДАСИЛ, что не только обеспечивает возможность их сравнения, ио и позволяет выявить положительные и отрицательные стороны каждого из подхо- дов. Как известно, предложения КОДАСИЛ на сегодняшний день яв- ляются единственным претендентом на стандарт в области описания структур данных, и соответствующий комитет ISO (International Stan- dart Organisation) уже занимается этой проблемой. Все средства представляются автором в исторической перспективе развития, приводятся варианты их синтаксиса и сеУЙнтики в различ- ных документах КОДАСИЛ, даются рекомендации, как и когда сле- дует их применять или, напротив, воздержаться от применения. Из- ложение сопровождается многочисленными примерами, оценочными классификациями и замечаниями о возможной реализации. Хорошему усвоению материала немало способствует и общая структура книги: понятия рассматриваются не в последовательности их представления в формальных спецификациях, а в соответствии с логической связью «от простого к сложному». Каждая глава начинается с обзора уже рас- смотренных ранее средств, имеющих отношение к данной тематике, и заканчивается общим обзором обсуждавшихся в ней средств. В кон- це книги дается критический анализ подхода КОДАСИЛ в целом. Следует отметить, что некоторые выводы и оценки ряда свойств, приводимых в книге, очевидно, субъективны, но, может быть, этим они и интересны. Автор, конечно, не всегда мог предугадать дальнейшее развитие вопроса, поэтому в соответствующих местах даны примечания. Книга Т. В. Олле предназначена в первую очередь для непосредст- венных пользователей (администраторов баз данных и прикладных программистов) и разработчиков СУБД, базирующихся на предло- жениях КОДАСИЛ, но будет чрезвычайно полезной и для пользова- телей других систем обработки данных. Она представит интерес для определенной категории «конечных» пользователей — администрато- ров и экономистов, применяющих автоматизированные системы обра- ботки данных, — в тех случаях, когда им необходимо получить пред- ставление о потенциальных возможностях СУБД для обоснованного принятия решений при организации или внедрении банков данных. Наконец, книга будет полезна аспирантам и студентам, занимаю- щимся системным программированием и обработкой данных. В. И Филиппов 7
ПРЕДИСЛОВИЕ Настоящая книга представляет один из подходов к управлению базами данных, который был предложен организацией КОДАСИЛ в период 1967—1971 гг. Этот подход освещался в многочисленных от- четах КОДАСИЛ, опубликованных между 1968 и 1975 гг.1 Практи- чески он уже реализован в нескольких системах, в частности в DMS-1100 фирмы Univac, IDS/2 фирмы Honeywell, IDMS фирмы Culli- nane (доступна на ЭВМ фирмы IBM и фирмы ICL) и UDS фирмы Sie- mens. Данная книга ни в коей мере не претендует заменить руковод- ства по этим системам, но. как вспомогательное пособие она пригодит- ся пользователям любой реализации предложений КОДАСИЛ. Изложенный здесь материал может также служить основой учеб- ных курсов в высших учебных заведениях. Я убежден, что большинст- во информационных систем 80-х годов будет разрабатываться с исполь- зованием технологии управления базами данных и что последняя вы- теснит со временем традиционные методы, сложившиеся на первом этапе развития автоматизированной обработки данных в результате широкого использования магнитных лент в качестве внешней памяти. Многим читателям известно, что по поводу сравнительных досто- инств различных подходов к управлению базами данных велась ожес- точенная полемика как среди пользователей, так и среди исследова- телей-разработчиков. Рынок систем предлагает пользователю доста- точно широкий выбор. Однако принять решение при выборе системы управления базами данных (СУБД), как правило, совсем не просто. Для облегчения процесса выбора в книгу были включены главы, по- священные другим подходам (системам TOTAL, IMS и ADABAS). С этой же целью здесь дан сравнительный анализ предложений КОДА- СИЛ и реляционного подхода. Работу над книгой я начал еще в 1974 г. и большая ее часть была написана довольно быстро, поскольку я мог посвящать ей дни, сво- бодные от проведения консультаций и лекций. Однако занятость моя возросла, в связи с чем (как это часто бывает и при составлении про- грамм для ЭВМ) последние 10% планируемой работы потребовали 90% общего затраченного времени. Фактор времени представляет здесь определенную проблему, так как спецификации КОДАСИЛ с течением лет регулярно изменяются. В книге по возможности отражены спецификации, содержащиеся в самых последних отчетах. Указанные в ней средства реализуются во многих широко распространенных системах. Одной из основных за- дач данной книги является неформальное изложение идей и принци- пов, лежащих в основе конкретных реализаций предложений КОДА- СИЛ. Эти идеи изменяются медленнее спецификаций и поэтому можно надеяться, что они еще долго будут интересны как студентам, так и пользователям соответствующих систем. 8
ГЛАВА I ИСТОРИЧЕСКИЙ ОБЗОР 1.1. ВВЕДЕНИЕ История развития деятельности КОДАСИЛ в области управления базами данных освещается в разд. 1.2 июньского выпуска «Журнала развития языка описания данных» 1973 г. Комитета по языку описания данных (КЯОД) [11. В настоящей главе кратко излагаются предпо- сылки возникновения КОДАСИЛ и комментируются наиболее значи- тельные события, имевшие место за последние 15 лет. 1.2. ПРОИСХОЖДЕНИЕ ТЕРМИНОВ Происхождение терминов база данных, и управление базами данных полностью не выяснено, хотя можно с уверенностью сказать, что КОДАСИЛ не является их автором. Здесь важно различать возникно- вение идей и терминологии. Известно, что одним из пионеров в области, которая сегодня назы- вается управлением базами данных, является Ч. Бахман. Однако в его ранних работах [2, 31 термин «база данных» не употребляется. Об основном направлении исследований Бахмана дают представление названия его статей: «Универсальная система программирования для запоминающих устройств с произвольным доступом» и «Программное обеспечение для работы с устройствами произвольного доступа». Иными словами, цель этих исследований — обеспечение эффектив- ного использования запоминающих устройств прямого доступа. В ос- нову подхода Бахмана положена гибкая схема организации связей между записями различного типа с применением метода ссылок, ко- торая и сейчас еще называется цепочной структурой В своей первой публикации [21 Бахман указывает, что его система IDS (Integrated Data Store — Интегрированный архив данных) работает с начала 1963 г. и ссылается при этом на внутреннюю публикацию фирмы GE (General Electric), датируемую январем 1962 г. Чтобы выяснить про- исхождение термина «база данных», необходимо обратиться к рабо- там, проводимым в начале 60-х годов по заказу некоторых военных организаций. В июне 1963 г. фирма SDC (System Development Corpo- ration) организовала в Санта Моника симпозиум по теме «Разработка и использование машинно-управляемых баз данных». На симпозиуме было представлено семь докладов, связанных с военной тематикой [41. В некоторых из этих докладов упоминалось о базах данных (Дж. X. Брайэн «Опыт AIDS в управлении операциями над базами данных», А. К. Свэнсон «Машинно-управляемая база данных учета личного состава ВВС США», Р. Л. Пэтрик «Применение массовых за- поминающих устройств для управления базой данных»). Здесь AIDS 9
(Aerospace Intelligence Data Systems) — система данных для службы космической аэроразведки. В двух докладах рассматривались самые ранние СУБД, а именно системы ADAM (Automated Data Management— Автоматизированное управление данными) и LUCID (Language Used to Communicate Information System Design — язык для описания структуры информационных систем). Кроме того, в программу симпозиума входили четыре рабочих за- седания. Названия тем этих заседаний вполне подходят для рабочих секций сегодняшней конференции: А. Факторы, определяющие требования к содержимому баз данных. Б. Критерии, влияющие на структуру и проектирование баз дан* ных. В. Методика сбора данных и поддержки баз данных. Г. Экономические аспекты управления базами данных. На втором заседании было предложено следующее определение базы данных: 1. База данных есть набор файлов. 2. Файл представляет собой упорядоченную совокупность статей (записей). 3. Статья состоит из ключа или нескольких ключей и данных. И отчет данного заседания еще утверждает, что это определение не является достаточно широко признанным! Тем не менее здесь впервые вводится понятие о базе данных. В материалах симпозиума большое внимание уделяется проблеме извлечения информации из файлов и в некоторых случаях термин «ба- за данных» используется для обозначения самих хранимых файлов, из которых извлекалась информация. Как правило, в качестве запоми- нающих устройств применялись магнитные ленты. Все это показыва- ет, что ориентация упомянутых разработок существенно отличается от направления ранних работ Бахмана. В сентябре 1965 г. фирма SDC (совместно с ARPA и Управлением систем ВВС) организовала второй симпозиум по машинно-управляе- мым базам данных. Программа этого симпозиума интересна тем, что его участникам была предложена некоторая весьма сложная проблема и нес кол ъко фирм продемонстрировали, как их системы смогут ее ре- шить Одно из решений — система IDS — представлено Чарльзом Бахманош. В материалах симпозиума [51 приводится полное описание данной ггроблемы и указываются пять подходов к ее решению. В целом 1965 г. был годом первых результатов в области управле- ния базагми данных. В этом же году к данной теме подключился КО- ДАСИЛ. 1.3. РАННИЙ ПЕРИОД ДЕЯТЕЛЬНОСТИ КОДАСИЛ Одним из инициаторов деятельности КОДАСИЛ в области управ- ления базами данных является У. Симмонс — представитель фирмы US Steel йз Питтсбурге. Изучая материалы 1965 г. по аппаратному и программному обеспечению, он познакомился с системой IDS фирмы GE. и»
Фирма US Steel была сторонницей Кобола с момента его создания и принимала активное участие в работе различных комитетов КОДА- СИЛ, занимающихся поддержкой и развитием этого языка. У. Сим- монс представлял данную фирму в Комитете по языку программиро- вания Кобол. Именно благодаря ему организовалась Рабочая секция по обработке списков. Использование термина «обработка ^писков» требует некоторого пояснения. В системе IDS для обеспечения связей между записями в памяти прямого доступа применялась концепция «цепочек». Эти «це- почки» являются частным случаем списков, а термин «обработка спис- ков» получил широкое распространение в начале и середине 60-х го- дов. Первое заседание Рабочей секции по обработке списков состоялось в Атланте (штат Джорджия) в октябре 1965 г. В последующий период, до мая 1967 г., секция провела еще несколько заседаний, не меняя свое- го названия. В мае 1967 г. состоялось заседание в Миннеаполисе, на котором, по странному стечению обстоятельств, почти половина при- сутствующих были новыми членами секции. В их числе оказался и я, представляя компанию, которая тогда называлась Radio Corpora- tion of America. На протяжении всего 1967 г. заседания проводились регулярно каждые четыре—шесть недель и продолжались около недели каж- дое. Дискуссии часто носили очень активный характер. В процессе обсуждения рождались новые идеи, которые исходили в основном от Ч. Бахмана и Дж. Додда. Последний также впервые присутствовал на этом заседании. Он разработал в Исследовательской лаборатории фирмы General Motors систему APL (Associative Programming Lan- guage [61 — ассоциативный язык программирования), во многом ана- логичную IDS, но базирующуюся на языке ПЛ/1, а не на Коболе (за- метим, что APL Додда и APL-360 Айверсона не имеют ничего общего). Историческое заседание в мае 1967 г. постановило исключить из названия секции термин «обработка списков», так как он не соответ- ствовал практическим аспектам Кобола, которые данная секция пы- талась расширить. Возникли возражения и против термина «рабочая секция». После длительных споров было принято новое название— Рабочая группа по базам данных (РГБД). Под этим названием рабо- чая группа работала вплоть до своего формального расформирования в 1971 г. Дискуссии 1967—1968 гг. отражали два принципиально различных подхода, которые определялись предшествующим опытом их участни- ков. Одни члены группы, например Бахман, Додд и Симмонс, акценти- ровали внимание на экономических применениях и отмечали необхо- димость использования более развитых структур, предлагаемых в системах IDS и APL (Додда). Другие же (в первую очередь участники симпозиума SDC 1963 г., и в частности я) настаивали на создании простых в использовании языков запросов, облегчающих доступ к данным для пользователей-непрограммистов. Указанное различие подходов формализовалось в концепции вклю- чающего языка в противоположность замкнутым системам. Этой теме 11
было посвящено заседание в августе 1968 г. [7], на котором я имел честь Сныть председателем. Единственно правильное, как теперь оче- видно, отношение к рассматриваемым подходам высказал Бахман: «Каждый по-своему полезен, оба необходимы». К счастью, РГБД форсировала работу в направлении включаю- щего яз?ыка, хотя в первое время имелись определенные затруднения. Некоторые члены группы (в том числе и я) не были уверены в перспек- тивности подхода IDS. Представители конкурирующих фирм-произ- водител ей ЭВМ считали, что General Electric пытается включить свой подход в стандарт Кобола, чтобы получить преимущество на рынке. Первый отчет РГБД «Расширение Кобола для работы с базами дан- ных» появился в январе 1968 г. 18]. Для иллюстрации тенденций того времени приведем две выдержки из него. В частности, рекомендова- лось «ввести возможность определения связей между основными и вспомогательными записями с использованием кольцевых цепочек как средства обеспечения файловых структур любой степени сложности». Далее, «отчет выдвигает некоторые рекомендации лишь после иссле- дования различных способов взаимодействия с базами данных и об- суждение методов управления данными, применяемых в настоящее время для решения проблем программирования. В результате сравне- ния известных методов организации и доступа к данным принято ре- шение в пользу замкнутых цепочек и кольцевых структур». Вскоре после выхода в свет этого отчета У. Симмонс оставил пост председателя РГБД по личным мотивам. В отчете КЯОД отмечается, что его сменил Г. Дюран из фирмы Southern Railway System, но фак- тически на заседаниях 1968 г. председательствовал Д. Л. Рапп из Traveller’s Insurance. Это был трудный год для РГБД, так как ян- варский отчет 1968 г. получил значительный резонанс и вызвал боль- шой интерес к работе группы. В конце 1968 г. Д. Рапп вышел из Traveller's Insurance и одновременно из РГБД. После ухода Д. Раппа пост председателя РГБД занял Т. Метакси- дес, принятый в РГБД осенью 1967 г. Он отличался активностью и ре- шительностью Конечно, следует отдать должное Бахману и Додду, выдвинувшим большинство первоначальных идей, а также Симмон- су, организовавшему работу над проектом, но именно Метаксидесу принадлежит заслуга его завершения. В октябре 1969 г. был сформулирован первый набор спецификаций языка и введена концепция подсхемы. Тогда же возникла мысль о том, что предлагаемый подход не должен ограничиваться Коболом. Между 1965 и 1969 гг. ПЛ/1 несколько потеснил Кобол и обнаружилось, что программисты, использующие Фортран и ПЛ/1, также хотят обраба- тывать данные, содержащиеся в базах данных. Тем не менее октябрь- ский отчет КЯОД 1969 г. вызвал большие разногласия. Возражения в основном исходили от фирмы IBM, представившей свой «Отчет мень- шинства», в котором отвергался подход РГБД и вносились альтерна- тивные предложения. Некоторые аргументы указанного отчета объ- яснялись тем, что фирма IBM в этот период активно продвигала ПЛ/1 для замещения Кобола. Возможно, именно последнее обстоятельство стимулировало появление концепции подсхемы, но и она не удовлет- 12
верила IBM. По мнению данной фирмы, предложенный подход все еще слишком ориентировался на Кобол, в связи с чем РГБД не могла пре- тендовать на обеспечение одинаково удобного взаимодействия со все- ми языками программирования. Действительно, типы записи баз данных в октябрьском отчете 1969 г. весьма походили на типы записи в Коболе. Типы записи в ПЛ/1 гораздо более развиты, и поэтому РГБД перед выпуском апрельского отчета 1971 г. заменила существующие типы записи схемы на типы записи ПЛ/1. Типы записи подсхемы Кобола остались, естественно, без изменений. 1.4. СОБЫТИЯ 1971 — 1976 гг. В 1971 г. произошли два события, имевших чрезвычайно важное значение для развития предложений КОДАСИЛ по базам данных. В мае в Вашингтоне на заседании «головного комитета», который на- зывался уже Комитетом по языку программирования (КЯП), был принят апрельский отчет РГБД 1971 г. При голосовании мнения раз- делились, причем возражения исходили опять-таки от IBM. Эти воз- ражения были сформулированы в документе, автором которого счи- тался Ингл ес [9], но, по-видимому, в его составлении участвовали мно- гие специалисты фирмы. Следует напомнить, что к 1971 г. фирма IBM сделала довольно большие капиталовложения в свою собственную сис- тему (IMS) и с коммерческой точки зрения ее, очевидно, не устраивала возможная перспектива стандартизации принципиально иного подхода. В мае же 1971 г. КОДАСИЛ принял решение, которое, как выяс- нилось позднее, имело некоторые нежелательные последствия. По- скольку ЯОД схемы, которым должен пользоваться администратор данных для определения базы данных, не является частью Кобола, был образован специальный Комитет по языку описания данных (КЯОД), занимающийся проблемами описания баз данных. В то же время язык описания части базы данных, доступной программе на Коболе (ЯО/Х подсхемы Кобола), а также язык манипулирования данными (ЯМД), в который входили операторы, добавляемые в раздел процедур Кобо- ла и позволяющие программисту манипулировать данными, формально отошли к компетенции Комитета по языку программирования для дальнейшего развития как расширений Кобола. Комитет по языку программирОхВания немедленно сформировал небольшую рабочую группу, получившую название Рабочей группы по языку базы данных (РГЯБД). В ее задачи входило продолжение работы РГБД и представление результатов в форме, пригодной для включения в «Журнал развития Кобола». Рабочая группа выполнила эти задачи и представила свой первый отчет [10] на рассмотрение поль- зователям Кобола. В 1976 г. этот отчет был одобрен и опубликован з «Журнале развития Кобола» КОДАСИЛ. В настоящей книге сделана попытка изложить концепции КЯОД и РГЯБД. В тех случаях, когда требовалось пояснить отдельные положения, признанные этими ко- митетами неудовлетворительными, но встречающиеся в используемых конкретных системах, приходилось обращаться к отчету РГБД 1971 г. 13
1.5. ТЕКУЩЕЕ положение дел Исто рия создания спецификаций баз данных в КОДАСИЛ дале- ко не окончена. Действительно, если КОДАСИЛ и дальше собирается играть ведущую роль в развитии технологии баз данных, то всю про- деланную им работу следует рассматривать лишь как начальный этап. Теперь и этой сфере деятельности подключились органы формальной стандартизации, в частности ANSI (Американский Национальный ин- ститут стандартов). Комитет ANSI X3J4, ответственный за стандар- тизацию Кобола, в настоящее время изучает возможность включения в последний средств работы с базами данных Кобола КОДАСИЛ. Ис- следовательская группа ISO, находящаяся в ведении Комитета TC97/SC5, проводит заседания, на которых обсуждаются широкие ас- пекты стандартизации баз данных. ЛИТЕРАТУРА 1. CODASYL Data Description Language Committee.—Journal of Develop- ment, June 1973. Available from British Computer Society, IFIP Applied Informa- tion Processing Group (IAG) HQ, Amsterdam and ACM HQ, New York. 2. Ba c h m a n C. W., W i 1 1 i a m s S. B. A general purpose programming system for random access memories.— Proc. Fall Joint Computer Conference, Oc- tober 1964, 26, p. 411—422. 3. BachmanC. W. Software for random access process-— Datamation, April 1965. 4. Proceedings of the Symposium on Development and Management of a Computer-centered Data Base, June 1963. January 1964, System Development Corporation, Santa Monica, California. 5. Proceedings of the Second Symposium on Computer-centered Data Base Systems, September 1965. December 1965, System Development Corporation, No ТМ-2624/100/00. 6. DoddG. G. APL — a language for associative data handling in PL/1, Proc. Fall Joint Computer Conference 1966, 29, p. 677—684. 7. The Large Data Base: its organization and user interface. Transcript of a Panel Session at ACM Conference August 1968. — DATA BASE (Newsletter of ACM’s Special Interest Group in Business Data Processing), vol. 1, No 3, Fall 1969. 8. Report to the CQDASYL COBOL Committee. COBOL extensions to handle data bases. — Newsletter of ACM Special Interest Group in Business Data Proces- sing, April 1968. 9. E n g 1 e s R. W. An analysis of the April 1971 DBTG report. A position paper presented to the Programming Language Committee by the IBM Repre- sentative to the Data Base Task Group. Appendix in Proc, of BCS Symposium on CODASYL DBTG report, October 1971. of ACM SIGFIDET Workshop on Data Access and Control, November 1971, p. 68—91. 10. CODASYL Data Base Language Task Group. Proposal for a data base facility in COBOL,_ January, 1973. Technical Services Branch, Dept, of Supply and Services, Ottawa, Canada. IL CODASYL COBOL Journal of Development 1976, Technical Services Branch, Dept, of Supply and Services, Ottawa, Canada. 14
ГЛАВА 2 КОМПОНЕНТЫ СУБД 2 1. ВВЕДЕНИЕ Разделение СУБД, базирующихся на предложениях КОДАСИЛ, на компоненты производится в конкретных реализациях по-разному. В одних случаях в основу такого разделения положены чисто терми- нологические критерии, в других — более фундаментальные. Мы вы- делим следующие пять основных компонент: 1. Язык описания данных схемы. 2. Язык описания данных подсхемы. 3. Язык манипулирования данными. 4. Резидентный модуль системы управления базами данных. 5. Язык управления размещением на внешних носителях. Рассмотрим каждую из этих компонент в отдельности. 2.2, ПОНЯТИЕ СХЕМЫ Слово «схема» (schema) не получило широкого распространения в английском языке. Оно проникло в терминологию обработки данных лишь в конце 60-х годов в результате деятельности Комитета систем КОДАСИЛ и РГБД. Краткий Оксфордский словарь определяет это слово как существительное, имеющее следующие значения: конспект, диаграмма, контур; (логика) силлогический символ; (риторика) фигу- ральное выражение; (кантианская философия) общий тип, основная форма, концепция явления, общая для всех членов некоторого клас- са. В нашем конспекте наиболее подходящим является последнее зна- чение, РГБД определила схему как описание базы данных. Теоретически одной конкретной схеме могут соответствовать не- сколько баз данных, но на практике, как правило, допускается лишь одна. И наоборот, каждой базе данных соответствует обычно одна схе- ма. 2.2.1. Понятие базы данных Определив схему как описание базы данных, мы уже не можем оп- ределить базу данных как то, что описывается схемой, хотя это и со- ответствует действительности. Было бы желательно ввести понятие базы данных, не привлекая широко известную концепцию файла. В от- личие от файла база данных содержит перекрестные ссылки между сво- ими отдельными частями. Это распространяется и на индексирован- ный файл, к различным частям которого обеспечивается одинаковый внешний доступ. 15
Чтобы не усложнять вопрос, предлагается определить базу данных как совокупность записей различного типа, содержащую перекрестные ссылки, а файл — как совокупность записей обычно одного типа, в ко- торой перекрестные ссылки отсутствуют. Будем надеяться, что эти определения не подрывают основ сущест- вования многотипных файлов Кобола, которые, конечно, нельзя рас- сматрив ать как базу данных. Важно отметить, что базы данных вводятся в обработку данных не вместо (файлов, а как новое дополнительное понятие. Они призваны заменить «основные файлы данных», но не претендуют на файлы ввод- ной, выводной, выдачи на печать, транзакций, архивный и т. п. Точ- нее, баз^ данных заменяет несколько основных файлов. К сожалению, термин хсбаза данных» используется иногда в тех ситуациях, когда, очевидно, имеются в виду обычные файлы. 2.3. ЯЗЫК ОПИСАНИЯ ДАННЫХ СХЕМЫ (ЯОД СХЕМЫ) Язык описания данных схемы является самостоятельным языком, и применяется для определения структуры базы данных (т. е. схемы) За единственным, но существенным исключением, которое будет рас- смотрено позднее, ЯОД схемы не определяет процессы обработки дан- ных. Он даже не позволяет сформулировать предложения, касающие- ся объема содержимого базы данных или размеров внешней памяти, выделяемой для хранения последних. Предполагается, что база дан- ных размещается в памяти прямого доступа и отсюда — акцент на пе- рекрестные ссылки, которые были бы невозможны при использовании носителей с последовательным доступом, например магнитных лент. Итак, ЯОД схемы служит для ее определения. При его правиль- ном однократном использовании возникает одна схема, представляю- щая собой последовательность предложений, близких к выраженным на естественном языке, которые могут быть написаны на бумаге или выведены на экран видеотерминала. ЯОД схемы позволяет создать не саму базу данных, а лишь ее описание. Чтобы появилась база данных, необходимо выполнить еще несколь- ко действий. Прежде всего, схему нужно преобразовать в машиночи- таемое представление, если у нее таковое еще отсутствует. Затем она должна быть транслирована в объектное представление, которое РГБД называет объектной схемой. Во избежание недоразумений под- готовленное человеком описание называется исходной схемой (ср. с исходной и объектной программами). Наконец, требуется написать программы загрузки данных в базу данных. Рабочие группы КОДАСИЛ (РГБД и КЯОД) не дали названия про- цессу преобразования исходной схемы в объектную. В результате одни разработчики выбрали термин «Компилятор схемы (ЯОД)», а другие — «Транслятор схемы (ЯОД)». Поскольку при таком преобра- зовании не генерируется никакой выполняемый машинный код (т. е. нет компиляции), в настоящей книге предлагается использовать по- следний 'термин. 16
2.4, ПОНЯТИЕ ПОДСХЕМЫ Происхождение понятия подсхемы до сих пор еще не выяснено. Это понятие не используется в январском отчете РГБД 1968 г., но в октябрьском отчете 1969 г. оно уже полностью определено. Правильнее всего определить подсхему как часть схемы. Не сле- дует называть подсхемой часть базы данных, потому что при этом на- рушается идентификация выделяемой части. Например, если в баз§ данных имеются семь типов записи, то подсхема может включать три из них, а не записи — реализации конкретного типа. (Это — упро- щенное представление. Более подробно указанное свойство будет рас- смотрено в одной из следующих глав.) Для одной и той же схемы можно специфицировать несколько под- схем. Последние имеют способность перекрываться, т. е. один и тот же тип записи допускается включать в две и более подсхемы. Более того, подсхема может соответствовать всей базе данных или сводиться к од- ному типу записи. Соотношение между схемой и подсхемой удобно выразить следую- щим образом. Схема есть глобальное представление логической струк- туры базы данных с точки зрения лица (или некоторой группы лиц), ответственного за всю базу данных. Это ответственное лицо обычно на- зывается администратором данных или администратором базы данных. Подсхема же является «взглядом» на базу данных прикладного про- граммиста, которого далее будем называть просто программистом. Та- ким образом, одно из назначений подсхемы — облегчить его работу. Концепция подсхемы позволяет ограничить сферу деятельности программиста лишь теми частями базы данных, к которым имеет отношение его программа, что гарантирует от случайных изменений в тех частях базы данных, к которым он не должен обращаться. 2.4.1. Язык описания данных подсхемы (ЯОД подсхемы) Подсхема определяется с помощью языка описания данных (ЯОД подсхемы). Объектная подсхема получается из исходного описания точно так же, как объектная схема из схемы — в процессе соответст- вующей трансляции. Однако объектная подсхема не может быть полу- чена ранее объектной схемы, а подсхема обязательно «принадлежит» своей схеме. Так, не представляется возможным часть одной схемы (например, два типа записи) объединить в одной подсхеме с частью некоторой другой схемы (еще три типа записи). По различным причинам, которые далее станут очевидными, ЯОД подсхемы считается принадлежащим определенному языку програм- мирования. Например, можно говорить о ЯОД подсхемы Кобола или о ЯОД подсхемы Фортрана. Напротив, ЯОД схемы принципиально не относится к какому-либо языку программирования. С другой стороны, нельзя рассматривать процессор, обрабатываю- щий предложения, написанные, например, на ЯОД подсхемы, как часть компилятора Кобола. Правильнее назвать его «транслятором ЯОД под- 17
схемы Кобола», который должен использоваться после транслятора ЯОД схемы, но до расширенного компилятора Кобола, трансли- рующего программы обработки данных в базе данных. Возникает вопрос: кто же фактически пользуется ЯОД подсхемы? РГБД уклонилась от прямого ответа на этот вопрос, ограничившись замечанием, что «за определение подсхемы может отвечать администра- тор данных». Администратор данных, действительно, чаще всего не- сет такую ответственность, однако следует помнить, что для этого ему необходимо иметь представление о функциях, выполняемых програм- мами по данной подсхеме. Прежде чем завершить рассмотрение подсхем, заметим, что нес- колько программ могут пользоваться одной подсхемой, причем даже одновременно. Другими словами, две программы могут выполняться одновременно и при этом обрабатывать данНке в одной и той же части базы данных, в частности, по одной и той же подсхеме. Далее, програм- ма может пользоваться только одной подсхемой2. Более того, ей нуж- на какая-либо подсхема, чтобы обращаться к базе данных. Могут ли одновременно выполняться программы, обращающиеся к базе данных и не обращающиеся к ней, — зависит обычно от свойств операционной системы. Как правило, это возможно. 2.5. ЯЗЫК МАНИПУЛИРОВАНИЯ ДАННЫМИ (ЯМД) Языком манипулирования данными РГБД назвала набор типов операторов, добавляемый к некоторому существующему языку прог- раммирования и позволяющий использовать последний для обработки данных в базе данных, определенной с помощью ЯОД схемы. Вообще говоря, язык манипулирования данными не вполне отвечает своему на- званию. Он не является и не может быть самостоятельным полным язы- ком. Как правило, ЯМД сочетает в себе два-три расширенных опера- тора из числа существующих и приблизительно 15 новых. Он не дуб- лирует возможности, уже имеющиеся в языке программирования. Термин включающий язык (host language) был, по-видимому, впер- вые применен автором настоящей работы в 1969 г. [1] для обозначения определенного класса СУБД, хотя еще в 1968 г. [21. Фрэй и Гозден, говоря о системах с включающим П0$ (процедурно-ориентированным языком), указывали на особое значение этого класса. Подход РГБД к управлению базами данных ориентирован на СУБД с включающим языком. В настоящее время несколько таких СУБД находятся в эксплуатации, и еще целый ряд ранних реализаций не получил достаточного распространения. Как указывалось в гл. 1, первоначальной целью РГБД было расширение Кобола, так что не удивительно, что в результате она пришла к СУБД с включающим язы- ком. Различие между СУБД, основанными на предложениях PI БД, и другими СУБД с включающими языками состоит в том, что в пер- вом случае, с точки зрения программиста, модифицируется существую- щая версия Кобола, а во втором — программист вынужден обращать ся к резидентному модулю СУБД с помощью операторов CALL 18
2.5.1. Метод реализации ЯМД На практике различие между двумя типами СУБД с включающим языком несущественно в отношении их реализации. Разумеется, ЯОД подсхемы Кобола и его ЯМД в конце концов должны быть включены в стандартный Кобол. В момент написания данной книги они уже введены в Кобол КОДАСИЛ и рассматривается возможность их вве- дения в Кобол ANSI. Со временем различие между существующими операторами Кобола и «новыми» операторами ЯМД будет иметь чисто историческое значение. Разработчик компилятора с Кобола может подходить к операторам ЯМД так же, как к оператору SORT (СОРТИРОВАТЬ) или к опера- торам обеспечения передачи данных. В настоящее время при реализа- ции операторов ЯМД часто применяют более экономичный и осторож- ный метод. Вместо модификации существующего компилятора с Ко- бола разрабатывается так называемый предтранслятор ЯМД в Кобол. Этот предтранслятор считывает исходную программу, в которой операторы Кобола перемежаются с операторами ЯМД, распознает каждый ЯМД-оператор и преобразует его в оператор CALL. В резуль- тате получается новая исходная программа, которую можно передать обычному компилятору с Кобола. 2.5.2. Системы с несколькими включающими языками В предыдущих параграфах основной акцент делается на Кобол, поскольку именно он послужил исходным пунктом работ РГБД в об- ласти баз данных. Но уже в результате обсуждения октябрьского от- чета 1969 г. принимается решение по возможности снять подобную Кобол-ориентацию. С этой целью вносятся изменения в ЯОД схемы, в частности внутренняя структура записи заимствуется из ПЛ/1 (она будет рассматриваться позднее). И хотя ЯОД и ЯМД подсхемы дейст- вительно являются Кобол-ориентированными, они могут использо- ваться для разработки аналогичных средств в других языках. С апре- ля 1971 г. деятельность РГБД по поддержке других языков програм- мирования развивается крайне медленно. В университетских кругах появилось несколько публикаций [3], и в 1975 г. КОДАСИЛ учредил Комитет по языку манипулирования базами данных Фортрана, первый журнал развития которого вышел в свет в 1976 г. [4]. Сформулированная в 1971 г. идея РГБД состоит в том, что к базе данных, определенной с помощью ЯОД схемы, могут обращаться про- граммы, написанные на Коболе, Фортране, ПЛ/1 и Алголе. Каждая программа должна пользоваться подсхемой, написанной на соответ- ствующем ЯОД подсхемы языка программирования. На практике большинство разработчиков ограничились Коболом в качестве включающего языка, хотя уже имеются экспериментальные системы на базе Фортрана. Вопрос о коммерческой пригодности и жиз- неспособности интерфейсов с несколькими включающими языками может решить только будущее3. 19
2.6. РЕЗИДЕНТНЫЙ ИСПОЛНИТЕЛЬНЫЙ МОДУЛЬ СУБД Прежде чем перейти к обсуждению различных средств описания структур в ЯОД схемы, необходимо полностью разобраться в том, что происходит во время выполнения прикладной программы. В распоря- жении пользователя СУБД имеется несколько языков (или подъязы- ков), ЯОД схемы, ЯОД подсхемы Кобола, ЯМД Кобола и, возможно, ЯОД подсхемы и ЯМД для других языков программирования. Разработчик может реализовать, по крайней мере, следующие «ви- димые» компоненты: транслятор ЯОД схемы; транслятор ЯОД подсхемы; предтранслятор ЯМД/Кобол (или модифицированный компилятор с Кобола}. Однако большая часть его усилий затрачивается на реализацию ис- полнительной компоненты, которую РГЯБД назвала управляющей системой €азы данных (Data Base Control System). В отчете РГБД об этой компоненте часто упоминается как о СУБД, что приводит к неоднозначности, поскольку так называется вся система, включая трансляторы. Указанный недостаток был замечен уже первыми разра- ботчиками, которые назвали эту компоненту программой управления данными, или модулем базы данных. В настоящей книге для нее ис- пользуется термин «резидентный модуль СУБД», а термином «СУБД» обозначается вся система (включая резидентный модуль). Рис, 2.1. Диаграмма взаимодействий при выполне- - нии прикладных программ: ------------------только считывание *----> считывание и запись *—* передача управления 2.6.1. Выполнение прикладной программы На рис. 2.1 представ- лена диаграмма взаимо- действий при выполне- нии прикладной прог- раммы. Как видно из этой диаграммы, все про- цессы доступа к базе данных проходят через резидентный модуль СУБД. Так как послед- ний используется одно- временно несколькими прикладными програм- мами, он должен иметь реентерабельный код. Резидентный модуль СУБД включает систем- ные буфера, в которых размещаются физиче- ские блоки данных, пере- даваемых между СУБД 20
и прикладной программой. В прикладной программе (которую РГБД называет исполняемым процессом) должна быть выделена рабочая об- ласть для каждого типа записи применяемой подсхемы. Эта область ни- же будет рассмотрена подробнее. Здесь же необходимо заметить, что в ЯМД используется принцип «операции над одной записью». При вы- полнении какого-либо оператора ЯМД между областью записи в программе и системным буфером перемещается не более чем одна запись, так как в программе отводится место только для одного экземп- ляра записи каждого типа. Во время выполнения некоторых операто- ров ЯМД возможны обращения к нескольким (и даже к нескольким ты- сячам) записям в базе данных, но перемещение данных в программную область записи и из нее ограничивается только одним экземпляром записи. 2.7. ЯЗЫК УПРАВЛЕНИЯ РАЗМЕЩЕНИЕМ НА ВНЕШНИХ НОСИТЕЛЯХ (ЯУВН) Язык управления размещением на внешних носителях является компонентой СУБД, которую каждый разработчик должен специфи- цировать самостоятельно4. Эта компонента может выполнять несколь- ко задач. В ее функции, например, входят: взаимодействие с операционной системой; отображение частей базы данных на запоминающие устройства пря- мого доступа различного типа; упаковка записей в базе данных; средства восстановления базы данных. Можно сказать, что ЯУВН обеспечивает второй уровень процес- са определения данных (первый соответствует ЯОД схемы). Некото- рые разработчики включают операторы ЯУВН в ЯОД схемы. Теорети- чески для написания своей программы программисту не требуется что-либо а»нать о предписаниях, сделанных администратором данных <з помощью ЯУВН. Однако иногда ЯМД специфицируют таким образом, что программист может добиться большей эффективности, если он знает предписания ЯУВН. ЛИТЕРАТУРА 1. О 1 1 е Т. W. An Analysis of Generalized Data Base Management Systems. Proceedings of Founding Conference of Society for Management Information Sys- tems. Minneapolis, September 1969. 2. Fry J. p.v Gosden J. A. Survey of Management Information Sys- tems and other Languages.— In: Critical Factors in Data Management (ed. F. Gruenberger). Prentice Hall, 1969. 3. Stacey G. M. A FORTRAN Interlace to the CODASYL DBTG Specifications.— The Computer Journal, 17, May 1974, № 2, p. 124—129. 4. FORTRAN Data Base Facility Journal of Development 1976. Available from Dr. Chester M. Smith. Pennsylvania State University, University Park, PA 16802. 21
ГЛАВА- 3 ОСНОВНЫЕ СРЕДСТВА ОПРЕДЕЛЕНИЯ СТРУКТУР 3.1. ТИП ЗАПИСИ Для любого пользователя Кобола тип записи является основным и хорошо известным понятием. Каждый используемый в программе тип записи должен быть описан в ее разделе данных. Программист мо- жет определить тип записи как часть файла, расположенного на не- котором внешнем носителе, или как часть своей рабочей памяти; при этом в оперативной памяти резервируется область, в которой будут размещаться записи указанного типа. Понятие типа записи было перенесено из Кобола в ПЛ/1 и несколь- ко расширено, так что пользователи ПЛ/1 также имеют полное пред- ставление о том, что означает термин тип записи. Пользователям Ал- гола и Фортрана, которым это понятие может быть не известно, ниже дается его краткое объяснение. 3.2. ТИП ЗАПИСИ ДЛЯ ПОЛЬЗОВАТЕЛЕЙ АЛГОЛА И ФОРТРАНА Наименьшая именуемая единица данных называется в Коболе эле- ментом данных, или, короче, элементом. Это приблизительно соответ- ствует понятию безразмерной переменной в Фортране или простой пе- ременной в Алголе. Элементу присваивается имя (ср. имя переменной или идентификатор переменной), и он может принимать различные значения. Несколько каким-либо образом связанных между собой элементов могут быть определены как принадлежащие одному типу записи. Сама запись при этом аналогична строке двухмерного массива Фортрана. Заметим, что в обработке экономических данных существенно большее внимание уделяется работе с буквенно-цифровыми данными. Если тип записи определяется в части описания данных (раздела данных), называемой секцией файлов, то несколько экземпляров этого типа записи будет содержаться в файле. Способ размещения отдельных записей в файле может иметь, а может и не иметь значения для про- граммиста . Файл включает записи либо только одного типа, либо не- скольких различных типов. В первом случае он называется файлом однотипных записей, а во втором — многотипным файлом. Применяя в своей программе оператор READ, программист знает, что при его выполнении одна из записей считывается из файла в опе- ративную память, где над ней можно выполнять дальнейшие действия. При использовании многотипного файла программисту, как правило, не известно, какого типа запись будет считана, и поэтому формат опе- ратора READ имеет вид: READ имя-сфайла RECORD. Помещая запись в выходной файл, обычно указывают имя типа за- писи, так как по нему определяется файл, в который должна быть по- 22
ставлена эта запись. Здесь можно провести аналогию с Фортраном, в котором при выполнении операторов READ и WRITE может переме- щаться целый массив элементов данных. Поскольку чаще всего приходится иметь дело с обработкой буквен- но-цифровых строк, одним из самых употребительных в Коболе явля- ется оператор MOVE (ПЕРЕСЛАТЬ), позволяющий программисту переместить значение некоторого элемента или группы элементов из одного места оперативной памяти в другое. (Кроме того, этот оператор можно использовать для изменения формата значений.) В типичной программе на Коболе производится очень много перемещений, но за- писываются они не так, как в Фортране. Если требуется взять значе- ние из памяти, отведенной для Y, и поместить его в память, отведен- ную для X, оставив в Y прежнее значение, в Фортране нужно написать: X = Y. В Коболе же подобная запись имеет вид: MOVE Y ТО X. 3.2.1. Групповые элементы Чтобы обеспечить возможность перемещения группы элементов одним оператором MOVE, необходимо ввести для нее сокращенное обозначение. Эта проблема решается с помощью описания внутренней именующей структуры записи, являющейся частью общего описания последней. Два или более расположенных подряд элементов могут быть объявлены групповым элементом. В него могут входить не толь- ко простые элементы данных, но и другие групповые элементы, что дает пользователю возможность построения многоуровневой именую- щей структуры. Во избежание путаницы уровни этой структуры нуме- руются сверху вниз, как это показано на рис. 3.1. 01 КЛИЕНТ. 02 НОМЕР-КЛИЕНТА. 03 ИД-КЛИЕНТА; PICTURE IS 99. 03 ПОСЛЕДОВ-НОМЕР-КЛИЕНТА; PICTURE IS 9(6). 02 ФАМИЛИИ-КЛИЕНТА; PICTURE IS X(24). 02 ГОРОД-КЛИЕНТА; PICTURE IS X(24). Рис. 3.1. Описание записи Кобола В этом примере КЛИЕНТ на уровне 01 есть имя типа записи, НО- МЕР-КЛИЕНТА — имя группового элемента, содержащего два эле- мента данных, а ФАМИЛИЯ-КЛИЕНТА и ГОРОД-КЛИЕНТА — два других элемента данных. На любом уровне могут быть определены как групповые, так и простые элементы данных. Для каждого просто- го элемента необходимо объявить его тип или «шаблон» (PICTURE). В программе можно написать: MOVE КЛИЕНТ ТО XI ИЛИ MOVE НОМЕР-КЛИЕНТА ТО Х2 23
или MOVE ИЛ-КЛИЕНТА ТО Y. Таким образом, мы пояснили понятия не только типа записи, по и уровней и групповых элементов в типе записи Внутренняя структура типа записи может быть и более сложной, поскольку имеются также средства определения таблиц и записей переменной длины. 3.2.2. Работа с таблицами Таблица аналогична массиву Фортрана—она может иметь размер- ность 1, 2 или 3, и программист указывает определенный элемент в ней с помощьео индексов (так же, как и в Фортране). Таблица Кобола пред- ставляет собой внутреннюю структуру записи, а общая длина записи, как правило, ограничена. Особенность такой таблицы заключается еще и в том, что, если тип записи определен как принадлежащий фай- лу, может существовать несколько экземпляров данной записи. Од- нако таблгицы могут определяться и в записях, объявленных частью рабочей п амяти программы. В Фортране же массивы не имеют ничего общего с записями просто потому, что там нет записей в смысле Кобо- ла. Кроме- того, элементы массива Фортрана представляют собой пере- менные одного и того же типа. На рис. 3.2 дается пример определения простой одномерной таб- лицы. 01 КЛИЕНТ4. 02 НОМЗЕР-КЛИЕНТА, 03 ИД-КЛИЕНТА; ... 03 ПОСЛЕДОВ-НОМЕР-КЛИЕНТА; ... 02 ФАМИЛИИ-КЛИЕНТА; ... 02 ГОРОД-КЛИЕНТА; ... 02 ЗАКАЗАННЫЙ-ПРОДУКТ; ... 02 МЕСЯЧНЫЕ-ЗАКАЗЫ; OCCURS 12 TIMES. 03 ЗА КАЗАННОЕ-КОЛИЧЕСТВО; ... Рис. 3.2. Одномерная таблица Здесь определена простая одномерная таблица фиксированного размера. В каждой записи выделено место ровно для 12 повторений значения элемента ЗАКАЗАННОЕ-КОЛИЧЕСТВО. Что именно под- разумевается под каждым из этих 12 значений — оставляется на усмот- рение программиста. В Коболе также возможно определить одну из размерностей таб- лицы (независимо от того, является ли она одномерной, двухмерной или трехмерной) как размерность с переменной длиной. По отношению к приведенному выше примеру это означает, что число месячных зака- зов не одинаково в записях различных клиентов. Например, новый клиент будет иметь только один или два элемента месячных заказов, а постоянный — 30—40. Точное число конкретных повторений долж- но содержаться в самой записи. Описание записи клиента в рассмат- риваемом случае представлено на рис. 3.3. 24
01 КЛИЕНТ. 02 НОМЕР-КЛИЕНТА. 03 ИД-КЛИЕНТА; ... 03 ПОСЛЕДОВ-НОАДЕР-КЛИЕНТЛ; ... 02 ФАМИЛИЯ-КЛИЕНТА; ... 02 ГОРОД-КЛИЕНТА; ... 02 ЗАКАЗАННЫЙ-ПРОДУКТ; ... 02 ЧИСЛО-МЕСЯЧН-ЗАКАЗОВ; ... 02 МЕСЯЧНЫЕ-ЗАКАЗЫ; OCCURS 1 ТО 60 TIMES DEPENDING ON ЧИСЛО-МЕСЯЧН-ЗАКАЗОВ. 03 ЗАКАЗАННОЕ-КОЛИЧЕСТВО; ... Рис. 3.3. Одномерная таблица переменной длины Заметим, что программист определяет максимальный размер запи- си, указывая максимальное число повторений в ней элемента ЗАКА- ЗгАННОЕ-КОЛИЧЕСТВО. Различные экземпляры записи имеют разную длину в зависимости от числа повторений этого элемента в каж- дом из них. Для обращения к отдельным значениям ЗАКАЗАННОЕ-КОЛИ- ЧЕСТВО в программе используются индексы, аналогичные индексам в Фортране. Точно так же пользователь обращается к таблицам, имею- щим размерность 2 или 3. 13.2.3. Квалификация Следует отметить еще одно важное свойство Кобола, отсутствую- щее в Фортране, — возможность квалификации (уточнения) имен. В программе может быть определено два или более типа записи, состоя- щих из нескольких элементов. В качестве примера рассмотрим два типа записи на рис. 3.4. 01 ЗАПИСЬ-ЗАКАЗА. 02 ПОСЛЕДОВ-НОМЕР-ЗАКАЗА; ... 02 КОД-ПРОДУКТА; ... 02 ДАТА-ПОЛУЧЕНИЯ; ... 02 КОЛИЧЕСТВО; ... 01 ЗАПИСЬ-ИСПОЛНЕНИЯ-ЗАКАЗА. 02 ПОСЛЕДОВ-НОМЕР-ЗАКАЗА; ... 02 КОД-ПРОДУКТА; ... 02 ДАТА-ИСПОЛНЕНИЯ; ... 02 КОЛИЧЕСТВО; ... Рис. 3.4. Пример квалификации имен В тексте своей программы программисту приходится обращаться к элементам КОЛИЧЕСТВО, содержащимся в обоих типах записи. Чтобы различить эти элементы, он должен написать КОЛИЧЕСТВО IN ЗАПИСЬ-ЗАКАЗА или КОЛИЧЕСТВО OF ЗАПИСЬ-ЗАКАЗА. В этом примере имя элемента КОЛИЧЕСТВО квалифицируется (уточ- няется) именем типа записи. Квалификация применяется на всех уровнях именования в типе записи и распространяется также на имя файла, содержащего эти за- 25
писи. Таким образом, элемент данных может быть квалифицирован именем группового элемента, частью которого он является, и далее именами записи и файла. 3.2.4. Заключительные замечания Понятия групповых элементов, внутренних таблиц записи и ква- лификации представляют собой средства определения внутренней структуры записи в Коболе, которые были перенесены в ПЛ/1 и ис- пользованы РГБД в ее предложениях для СУБД. На самом деле пред- ложения по структуре записи в ЯОД схемы ближе к ПЛ/1, чем к Ко- болу. Однако большинство разработчиков по различным причинам ограничилось структурой записи Кобола. В некоторых случаях исклю- чалась даже возможность работы с таблицами переменной длины, т. е. в ЯОД схемы допускалось определение типов записи лишь фиксиро- ванной длины. 3.3. СРАВНЕНИЕ ВНУТРЕННИХ И ВНЕШНИХ СТРУКТУР ЗАПИСЕЙ Сохранение исторически сложившейся внутренней структуры запи- си представляет собой один из важных моментов в предложениях КО- ДАСИЛ. Однако главное достоинство этих предложений состоит в введении новых «внешних» структур, т. е. структур связей между запи- сями, к детальному обсуждению которых мы и переходим. Основным структурирующим средством, заимствованным РГБД из системы IDS фирмы Honeywell (и разработанным Бахманом в фир- ме GE в начале 60-х годов), является определение связи между запи- сями посредством типа набора. Сг&пуея признать, что этот термин не слишком удачен ввиду распространенного математического значения слова «набор» (set-множество). Тип набора лучше всего определить как взаимосвязь между двумя или более типами записи. Например, если рассматривать два типа запи- си, из которых первая содержит основные сведения о служащем, а вторая — сведения о его образовании, то их взаимосвязь очевидна. Все данные об образовании какого-либо служащего могут быть поме- щены в одну запись, но удобнее разместить их в нескольких записях в соответствии с различными ступенями полученного образования. Другими словами, число записей «образование», относящихся к одно- му служащему, оказывается неодинаковым у разных служащих. Это пример отношения (связи) один ко многим, на котором базируются предложения КОДАСИЛ. Здесь полезно сравнить подход с установлением внешних связей между записями с традиционным подходом использования внутренней структуры записи. При традиционном подходе все данные об образо- вании будут, вероятно, включены в тип записи служащего, так как, хотя объем этих данных и различается от служащего к служащему, степень различия не может быть слишком высокой. Размещение све- дений о наиболее образованном служащем потребует не более чем в 26
пять раз больше места по сравнению с тем, которое требуется для све- дений о наименее образованном. Таким образом, при традиционном подходе наш пример можно программировать с использованием запи- сей переменной длины или даже записей фиксированной длины, в ко- торых резервируется место для максимального объема данных. Оба эти подхода иллюстрируются рис. 3.5. Подход базы данных Традиционный подход Рис. 3.5. Сравнение внешних и внутренних структур Каждый прямоугольник здесь представляет некоторый тип записи. Стрелка между записями СЛУЖАЩИЙ и ОБРАЗОВАНИЕ показы- вает, что, во-первых, между ними определено отношение типа набора, во-вторых, данному типу набора присвоено имя СО, и, наконец, в этом отношении любой служащий может не иметь ни одной либо иметь одну или более запись об образовании. При этом каждая из них принадле- жит одному и только одному служащему. К сожалению, в 1971 г. РГБД называла тип набора просто набором что вызывало большие затруднения у тех, кто впервые пытался по- знакомиться с этим структурным понятием. В 1973 г. РГБД ввела термин тип набора и заменила экземпляр набора набором. Такой же подход был принят КЯОД в отчете 1973 г. Новая терминология ока- залась менее громоздкой и наиболее соответствующей терминам тип записи и запись. В настоящей работе иногда для смыслового выделения будут использоваться выражения «экземпляр записи» и «экземпляр набора». Многие разработчики систем, следуя отчету РГБД 1971 г., применяют слово «набор» для обозначения типа набора. Однако если различия между этими основными понятиями хорошо усвоены, напри- мер с помощью данной книги, то смысл терминов в описаниях конкрет- ных систем обычно становится ясен из контекста. 3.4. ТИПЫ НАБОРА Приведенный выше пример иллюстрирует часто встречающийся случай, когда тип набора может использоваться вместо записей пере- менной длины. Очевидно, что в рассмотренном отношении структур- ная роль типов записи СЛУЖАЩИЙ и ОБРАЗОВАНИЕ существенно различна. В терминологии КОДАСИЛ СЛУЖАЩИЙ есть тип запи- совладельца набора, а тип записи ОБРАЗОВАНИЕ является членом этого набора. Данный тип набора принадлежит к наиболее распростра- ненному классу, который называется типом набора с одним членом (или одночленным). 27
Рис. 3.6. Тип набора с несколькими членами Можно определить и типы набора с несколькими члена- ми (многочленные), т. е. отно- шение между тремя или более типами записи, один из кото- рых объявляется владельцем, а все остальные — членами. Пример типа набора с не- сколькими членами приведен на рис. 3.6. Как и ранее, здесь каждый прямоугольник обозначает некоторый тип записи, а стрелки указывают направление связи от владельца к членам. Наконец, имеется еще один класс так называемых сингулярных (особых) типов набора, в которых владельцем является сама система. Подобный тип набора без владельца представлен на рис. 3.7. Значение сингулярных наборов поясняется в гл. 5 при рассмотре- нии представления наборов во внешней памяти. | СИСТ-СЛУЖ СЛУЖАЩИЙ Рис. 3.8. Пример именования типа набора состоит-из Рис. 3.7. Сингулярный тип набора Заметим, что каждому типу набора должно быть присвоено имя, которое составляется по правилам именования, приведенным в специ- фикациях. Можно предложить, три метода выбора имени. Согласно первому методу оно складывается из первых букв имен владельца и члена. Такой подход часто применяется в данной книге (см. рис. 3.5, 3.6 и 3.7). Имя, выбранное вторым методом, поясняет читателю смысл отно- шения, представленного данным типом набора. Например, на рис. 3.8 отношение между записями ИЗДЕЛИЕ и ДЕТАЛЬ, представляющее детали, из которых состоят изделия, называется СОСТОИТ-ИЗ. Не- достатком этого метода является то, что часто приходится либо созда- вать слишком длинные имена, либо ограничиваться такими, как ИМЕ- ЕТ, ПРИНАДЛЕЖИТ, ИСПОЛЬЗУЕТ. Третий метод излагается здесь лишь для полноты представления. Он заключается в выборе любого имени, например X, Y, Р или Q. При- менять такие имена не рекомендуется по тем же причинам, что и при выборе имени типа записи. Программы должны быть написаны в виде, удобном для последующего чтения. Появившаяся в научных кругах тенденция использовать короткие и мало информативные имена кри- тикуется во всех курсах экономического программирования., 28
3.4.1. Наборы (экземпляры наборов) Представление типа набора во внешней памяти подробно рассмат- ривается ниже. Здесь же мы остановимся лишь на некоторых основных свойствах наборов. Каждому типу набора (кроме сингулярных) может соответствовать во внешней памяти несколько конкретных наборов. Их число точно соответствует числу записей-владельцев этого типа набора в базе дан- ных. Если в последней имеются три записи-владельца, то должно быть и три экземпляра набора. При наличии 2743 экземпляров владельца существует 2743 соответствующих набора. Каждый набор может быть пустым или непустым, причем слово «пустой» здесь нельзя понимать в математическом смысле. С владель- цем пустого набора в базе данных не связана ни одна запись-член. Од- нако в большинстве случаев владелец набора «соединяется» с несколь- кими (с одной или с несколькими тысячами) записями-членами. Как именно это происходит и как принимается решение, к которому из нескольких экземпляров набора должна быть присоединена запись- член, излагается позднее. Важно отметить, что запись может быть включена только в один набор данного типа либо в два (и более) набора различных типов. 3.5. НАЗНАЧЕНИЕ ТИПА НАБОРА Тип набора был определен выше как отношение «один ко многим» между двумя или более типами записи, каждый из которых содержит элементы данных, характеризующие в совокупности некоторый «тип объекта реального мира». В так называемом реальном мире между ти- пами объектов существуют многочисленные и разнообразные отноше- ния, и наша задача — попытаться представить эти отношения в базе данных. Однако такое представление (в частности, представление сети от- ношений между объектами) стало возможным лишь при появлении за- поминающих устройств большого объема с прямым доступом. Имев- шиеся ранее ограничения, связанные с размещением записей данных на последовательных запоминающих носителях, в основном на маг- нитной ленте, существенно затрудняли его реализацию. Некоторые энтузиасты баз данных преувеличивают значение воз- можности представления отношений. Так, у начинающего пользова- теля может сложиться впечатление, что определение структуры базы данных сводится к распознаванию отношений реального мира и к иден- тификации их как типов набора через ЯОД схемы. К сожалению, hi практике приходится учитывать и другие соображения. Поэтому реше- ние о введении того или иного типа набора можно принять лишь пос- ле рассмотрения программ, которые будут обращаться к базе данных. С точки зрения эксплуатации введение любого типа набора связи но с некоторыми расходами. Как будет показано позднее, для его реали- зации требуется дополнительная внешняя память, а при добавлении или изменении данных — и дополнительное время. ЭВМ. С другой сю- 29
роны, 'тип набора предоставляет путь доступа к записям базы данных. Дакии образом, необходимость введения какого-либо типа набора пол- ностью определяется необходимостью обеспечения соответствующего пути доступа в базе данных. 3.6. ПОСТРОЕНИЕ СТРУКТУР С ПОМОЩЬЮ ТИПА НАБОРА Тип набора является основным элементом, с помощью которого строится структура всей базы данных. На способы его использования не накладываются почти никакие ограничения. Наиболее типичные примеры возможных структур показаны на рис. 3.9—3.13. ЗАКАЗЫ ИСПОЛНЕНИЙ Рис. 3.9. Два типа набора между двумя типами записи ЗАКАЗЫ СОДЕРЖИТ Рис. 3.10. Мини-цикл между двумя типами записи8 ТОВ-ЗАК ЗАК-СТ Рис. 3.11. Иерархическая структура При построении структуры базы данных применяются следующие правила: 1. Тип записи может быть владельцем и одновременно членом не- скольких типов набора. 2. Между двумя типами записи может быть определено любое число типов набора. 30
Рис. 3.12. Y-образная структура СУБКОНТРАКТЫ Рис. 3.13. Структура базы данных, включающая цикл и тип набора с несколькими типами записей-членов 3. База данных может содержать любое число типов набора и ти- пов записи. 4. Допускаются циклические структуры (см. рис. 3.10 и 3.13). Приведенные на рис. 3.9—3.13 диаграммы, которые часто называ- ют схемами или диаграммами Бахмана 11], иллюстрируют графичес- Рис. 3.14, Три экземпляра одночленного типа набора 31
кий метод изображения структур базы данных. Каждый прямоуголь- ник здесь соответствует типу записи, а каждая стрелка — типу набо- ра. Типы записи и типы набора должны быть каким-то образом пред- ставлены во внешней памяти. Этим представлениям и посвящены сле- дующие главы книги. Тип записи как более фундаментальное понятие будет рассматриваться в первую очередь. В заключение приведем пример некоторого расширения схем Бах- мана для изображения экземпляров наборов. На рис. 3.14 показаны три экземпляра одночленного типа набора, схематически представлен- ного на рис. 3.5. Заметим, что окружности здесь соответствуют экземп- лярам записей, а соединяющие их линии указывают, что данные запи- си «связаны» в набор одним из способов, которые будут обсуждаться в гл. 5. ЛИТЕРАТУРА 1. В a chman С. W. Data Structure Diagrams. Data Base, 1, 1969 № 2* (Publication of ACM Special Interest Group on Business Data Processing). ГЛАВА 4 ПРЕДСТАВЛЕНИЕ ТИПОВ ЗАПИСИ ВО ВНЕШНЕЙ ПАМЯТИ 4.1. ВВЕДЕНИЕ Представление типов записи во внешней памяти имеет несколько аспектов, большая часть которых может быть рассмотрена без де- тального обсуждения соответствующего представления типов набора. Наиболее важным моментом процесса отображения типов записи во внешнюю память является спецификация способа размещения (lo- cation mode)6 каждого из них и области или областей, в которых долж- ны размещаться записи данного типа. Но прежде чем перейти к обсуж- дению этих понятий, необходимо полностью уяснить концепцию клю- ча базы данных. 4.2. КЛЮЧ БАЗЫ ДАННЫХ Концептуально ключ базы данных представляет собой элемент данных, который играет роль однозначного внутрисистемного иденти- фикатора, используемого СУБД для отличения одной записи от дру- гой. Каждой хранимой в базе данных записи соответствует определен- ное значение этого элемента. Ключ базы данных не является элементом, который администратор данных должен определять с помощью ЯОД схемы, хотя такая воз- можность и имеется в любом типе записи. Понятие ключа базы данных настолько органично связано со всем подходом КОДАСИЛ, что без достаточно четкого представления его роли невозможно эффективное 32
выполнение функций администратора данных или даже прикладного программиста. Каждой записи, впервые помещаемой в базу данных, выделяется некоторое значение ключа базы данных. Это значение сохраняется и при модификации записи вплоть до ее удаления из базы данных. В ка- ком-то смысле по отношению к записи ключ базы данных аналогичен личному идентификационному номеру человека. Хотя программисту в любом случае должна быть известна концеп- ция ключа базы данных, степень ее фактического использования дале- ко не всегда одинакова. Можно вообще не применять ключи базы данных и составлять тем не менее достаточно эффективные программы. С другой стороны, если необходимо добиться абсолютно минимального времени работы про- граммы, то, манипулируя ключами базы данных, можно обеспечить повышенную эффективность системы. Методы использования (или, напротив, игнорирования) ключей базы данных будут изложены в соответствующих разделах данной книги. В заключение рассмотрим (хотя в этом и нет особой необходимости), что представляет собой зна- чение ключа базы данных. Теоретически оно выражается просто це- лым числом от единицы, соответствующей самой первой помещаемой в базу данных записи, до /V, где N — число записей в ней после началь- ной загрузки. Однако, поскольку на практике ключ базы данных слу- жит для локализации записи, при использовании описанного выше под- хода пришлось бы хранить и просматривать очень длинные таблицы значений таких ключей и соответствующих адресов. Поэтому почти все разработчики так или иначе связывают пред- ставление ключа базы данных с физическим расположением в ней за- писи. Это вовсе не означает, что в качестве ключа применяется номер цилиндра и дорожки на диске. Чаще всего его значение складывается из нескольких компонент (обычно трех или четырех), позволяющих СУБД уменьшить число вычислений и просмотров таблиц при локали- зации соответствующей записи. 4.3. ПОНЯТИЕ О СПОСОБЕ РАЗМЕЩЕНИЯ Опыт преподавания показывает, что для данного понятия выбрано не совсем удачное название. Слово locate (размещать, находить) в английском языке может выражать как идею поиска, так и идею раз- мещения. Появление этого термина связано с системой IDS/1. В ней сущест- вовали понятия и способа помещения, и способа выборки. РГБД вполне резонно решила, что совершенно излишне иметь два различных по- нятия и от последнего фактически отказалась. Оставшийся же термин определяет исключительно размещение. Некоторые специалисты в области традиционной обработки данных восприняли способ размещения как новое обозначение для метода до- ступа, но это абсолютно неправильная интерпретация. Администратору данных предоставляется на выбор несколько спо- собов размещения. Он должен указать какой-либо из них для каждого 2 Зак. 145 33
типа записи. Предложения РГБД предусматривают следующие спосо- бы размещения: CALC (ВЫЧИСЛЯЕМЫЙ) DIRECT (ПРЯМОЙ) VIA SET (ЧЕРЕЗ НАБОР) Кроме того, ИхМеется возможность не указывать способ размещения для некоторого типа записи. Синтаксис соответетвующехХ^ определе- ния: RECORD NAME IS имя-записи 1 LOCATION MODE IS- L ( имя-данных-1) DIRECT ( ид-данных-1 J CALC [имя-проц-l] USING ид-данных-2 [,ид-данных-3]... DU LICATES ARE i [NOT ] ALLOWED VIA имя-набора-l SET I ----------- Со своей стороны КЯОД удалил квадратные скобки и добавил чет- вертый способ SYSTEM (по алгоритму системы). 4.3.1. Замечание о синтаксисе В предыдущем параграфе впервые в настоящей книге прштл.щтся общий формат некоторого предложения ЯОД, и поэтому здесь \\щ,пно дать краткое изложение синтаксического формализма, примепяе дою для представления подобных общих форматов. В основном такой же синтаксический формализм использовался и для описания Кобола, РГБД его лишь слегка расширила. Поскольку пользователям Кобола синтаксис предложения LOCATION MODE по- нятен без дополнительных пояснений, они могут пропустить весь сле- дующий текст данного раздела. При изображении синтаксиса применяются следующие правила: 1. Слова языка пишутся прописными буквами; имена, которые должен подставлять пользователь, обозначаются строчными буквами. 2. Обязательные для употребления слова подчеркиваются. Не- подчеркнутые слова (правильно написанные!) могут включаться лишь для повышения «читаемости» описания схемы. Они могут быть опуще- ны без всякого ущерба для смысла конструкции. 3. Если некоторое слово, имя, фраза или все предложение заклю- чены в квадратные скобки, то это означает, что данное слово, имя, фра- зу или предложение можно опустить (не включать в текст описания). Пример представления общего формата LOCATION MODE по РГБД достаточно хорошо иллюстрирует эти положения. В нем могут быть опущены слово NOT, подставляемый пользователем ид-данных-3 и да- же все предложение LOCATION MODE. Заметим, что в рассматривае- мом случае смысл конструкции изменяется в зависимости от включения или не включения в нее соответствующего элемента. 34
4. При наличии фигурных скобок требуется выбрать один из за- ключенных в них вариантов, перечисляемых сверху вниз. В синтак- сисе LOCATION MODE показаны два примера использования таких скобок, причем одни из них вложены в другие. Более наглядным яв- ляется пример с внешними скобками, который сокращенно можно пред- ставить в виде: (CALC LOCATION MODE IS DIRECT [VIA SET Таким образом, администратор данных может написать: LOCATION MODE IS CALC ИЛИ LOCATION MODE IS DIRECT ' ИЛИ LOCATION MODE IS VIA SET. 5. Многоточие ( . . .) указывает на допустимость повторения. На- пример, вариант с CALC: LOCATION MODE IS CALC USING ид-данных-2 [,ид-данных-3] ... означает, что данное предложение может завершаться одним из сле- дующих способов: USING ид-данных-2 USING ид-данных-2, ид-данных-3 USING ид-данных-2, ид-данных-3, ид-данных-4 и т. д., т. е. теоретически здесь возможен список нескольких сотен идентификаторов базы данных. Общий формат ид-данных-2 [,ид-данных-3].., весьма часто встречается в предложениях РГБД. Обратим внимание на то, что запятая помещена внутри квадратных скобок, так как она может появиться и повторяться только для каждого следующего иден- тификатора. 4.3.2. Идентификаторы и имена базы данных В отчете РГБД и в настоящей книге встречаются два синтаксичес- ких элемента, которые необходимо пояснить даже для опытных поль- зователей Кобола. Примеры этих элементов: имя-данных-1 и ид-данных-4. В обоих случаях имеется в виду обозначение простого или группо- вого элемента данных в некоторой части схемы. Разница состоит в том, что имя-данных не может квалифицироваться или использоваться с индексами, тогда как идентификатор-данных (ид-данных) не толь- ко может, но и должен — при необходимости обеспечения однознач- ности имени в базе данных. 9* 35
В различных отчетах КОДАСИЛ всегда пишется полностью «имя- данных-б^зы-данных» или «идентификатор-данных-базы-данных», что тольк о удлиняет текст и замедляет чтение. Мы будем использовать обозначения имя-данных и ид-данных. Соотношение между/ этими эле- ментами представляется следующим образом: ид-данных = имя-данных [(целое-! [.целое-2]...)] имя-записи Приме р предложения LOCATION MODE не является показатель" ным для выяснения различия в применении ид-данных и имени-дан’ ных, пс скольку в нем указанные элементы заключены в фигурные скоб’ ки, означающие, что можно выбрать любой из них.. Пусть это не сму- щает читателя — соответствующее объяснение дается далее при об- суждении вариантов рассматриваемого предложения. Пока же нуж- но просто усвоить: если написано имя-данных, то квалификация и индексаии я запрещены; если же написано ид-данных, то квалифика- ция и индексация должны применяться, но лишь для обеспечения од- нозначности имени в базе данных. Целое число, которое всегда пишется после имени-данных или ид- данных (например, ид-данных-2 или имя-данных-7), желательно для последующих ссылок именно на данное имя или идентификатор в раз- личных правилах, которые обязательно следуют за каждым синтакси- ческим форматом. Кроме того, без этих целых «различителен» пользо- ватель мог бы решить, что один и тот же идентификатор может (или должен) использоваться в двух-трех соответствующих местах предло- жения. 4.4. ВОЗМОЖНЫЕ СПОСОБЫ РАЗМЕЩЕНИЯ Закончив с синтаксическим формализмом, мы можем вернуться к основной линии изложения и обсудить все возможные способы разме- щения. Однако прежде выясним, когда и зачел, требуется указание способа размещения. Такое указание используется каждый раз при первоначальном размещении в базе данных записи какого-либо типа. Как мы увидим далее, только в одном из трех возможных способов размещения (а именно в CALC) определяется так называемый первич- ный ключ, который можно использовать и для выборки записей. Но это не означает, что первичный ключ должен применяться при поиске записей со способом размещения CALC. Не вдаваясь в подробности методов поиска записей в базе данных, сформулируем одно из основ- ных свойств систем, основанных на предложениях КОДАСИЛ: отдель- ная запись может быть найдена в базе данных несколькими различны- ми способами. В частности, определение для некоторого типа записи способа размещения CALC добавляет для нее еще один способ доступа. 4.5. СПОСОБ РАЗМЕЩЕНИЯ CALC Способ размещения CALC (от calculation — вычисление) предпо- лагает, что при помещении записи в базу данных соответствующий ключ базы данных (а следовательно, и место размещения записи) вычис- 36
ляется по значению (значениям) одного или нескольких элементов, перечисленных после слова USING (ИСПОЛЬЗУЯ) предложения LOCATION MODE. В отчете РГБД подразумевается, что CALC является средством рандомизации, хотя явно об этом не упоминается. Так или иначе все разработчики восприняли CALC как указание для применения рандо- мизирующего алгоритма (хеш-функпии). В частности, в системе IDS/Т размещению CALC всегда соответствовал (и соответствует) один ран- домизирующий алгоритм. Временно принимая эту ограниченную интерпретацию CALC, ос- тановимся подробнее на концепции рандомизации. Классической ра- ботой на эту тему является статья Лума, Юена и Додда fl] 1970 г., в которой приводятся результаты экспериментального исследования восьми различных методов преобразования ключей. Авторы статьи при- ходят к выводу, что наилучший результат дает метод деления. Послед- ний метод часто применяется на практике, поэтому рассмотрим его подробнее. Значение ключа, независимо от того, является ли оно числовым, буквенно-цифровым или их комбинацией, рассматривается как одна длинная битовая строка, точнее, как соответствующее ей целое число. Это целое делится на другое целое число и остаток (или его часть) бе- рется для ключа базы данных. Делителем может быть какое-либо простое число, близкое к общему числу возможных позиций. Еще в 1963 г. Бухгольц [2] предложил выбирать в качестве делителя наиболь- шее простое число, не превосходящее общее число возможных позиций. С точки зрения же Лума и его соавторов, годится любое число, близ- кое к общему числу позиций. Чтобы иметь представление о практическом применении рандоми- зации при использовании способа размещения CALC, целесообразно несколько забежать вперед и рассмотреть понятие области. Область есть поименованная часть базы данных. Каждый тип записи приписы- вается к одной или нескольким областям. Обычно область состоит из некоторого числа страниц одинакового размера. Теоретически раз- биение области на страницы не имеет значения для программиста, но знать ему об этом весьма полезно. Как правило, рандомизирующий CALC-алгоритм генерирует не полный ключ базы данных, а номер страницы области. Запись разме- щается с некоторой позиции этой страницы, если для нее еще имеется место. В противнем случае на данной странице ставится указатель на одну из «страниц переполнения», в которую помещается сама запись. 4.5.1. Дубликаты значений ключа Выбирая для некоторого типа записи способ размещения CALC, администратор данных должен решить вопрос и о дубликатах (одина- ковых значениях) первичного ключа. Точнее, он должен либо разре- шить, либо запретить дубликаты этого ключа. На практике могут встре- титься оба случая. Если первичный ключ представляет собой фами- лию человека, то естественно допустить дубликаты. Трудно придумать ..................................................7"'" 37
ситуацию, в которой возможно только одно лицо с фамилией Смит, Браун или Джонс. При разрешении дубликатов (указание DUPLI- CATES ALLOWED) первичный ключ не является однозначным иден- тификатором записи. С другой стороны, если в качестве CALC-ключа выбирается номер изделия или личный идентификационный номер, то он должен быть однозначным, и администратору данных рекомендуется запретить дубликаты значений этого ключа. Все изложенное выше о дубликатах остается в силе при любых спо- собах выбора позиции размещения в памяти по значению первичного ключа. К сожалению, как уже отмечалось, CALC ассоциируется с при- менением рандомизации. Можно, однако, воспользоваться для него методом доступа ISAM, но тем не менее в отношении дубликатов зна- чений ключа это ничего не изменит. 4.5.2. Коллизии (синонимы) Понятие коллизии относится лишь к интерпретации CALC как ран- домизации. Коллизия (некоторые называют ее столкновением сино- нимов) возникает в том случае, когда два различных значения ключа дают при рандомизации одно и то же внутреннее значение позиции. В системе должны быть предусмотрены средства, позволяющие спра- виться с подобной ситуацией. В частности, проблема коллизий реша- ется с помощью изложенного выше подхода, при котором алгоритм рандомизации выбирает страницу и на ней размещается несколько записей, а также, возможно, указатели на страницы переполнения. Эта проблема затронута здесь только для того, чтобы подчеркнуть ее отличие от проблемы «дубликатов значений». С последней приходится сталкиваться и администратору данных, и прикладному программисту, тогда как проблема коллизий касается только разработчика системы. 4.5.3. Нестандартные CALC-алгоритмы Выше были рассмотрены почти все основные аспекты способа раз- мещения CALC. Синтаксис такого варианта размещения; LOCATION MODE IS CALC [имя-процедуры-1] USING ид-данных-2 I,ид-данных-3] ... DUPLICATES- ARE [NOT] ALLOWED Поясним задание имени-процедуры-1. Если это указание опуще- но, то используется CALC-алгоритм, предусмотренный разработчи- ком. С другой стороны, РГБД позволяет здесь администратору данных применить свой собственный алгоритм вместо стандартного. На прак- тике возможность определения процедур базы данных почти нигде не реализована7, так что обсуждение данного вопроса можно пока отло- жить до соответствующего раздела книги. Однако во многих системах администратору данных предоставляется выбор одного из нескольких существующих алгоритмов или возможность определить свой собст- венный. 38
4.5.4. Вы бор ключа В синтаксическом формате предыдущего раздела вторая строка имеет вид: USING ид-данных-2 [,ид-данных-3] ... Читателям, знакомым с Коболом, комментарии здесь не требуют- ся. Тем же, кому не приходилось иметь дело с этим языком, поясним, что USING (ИСПОЛЬЗУЯ) применяется в Коболе для указания па- раметров. Данный способ равноценен заключению последних в круг- лые скобки, как это принято при более математическом подходе. Из рассмотрения синтаксиса следует, что CALC-ключ должен содержать не менее одного элемента. Каждый входящий в него элемент может быть простым или групповым, квалифицированным и индексирован- ным в зависимости от обстоятельств. И наконец, элементы CALC-ключа должны, очевидно, принадле- жать типу записи, способ размещения которой в данном случае опре- деляется. 4.6. СПОСОБ РАЗМЕЩЕНИЯ DIRECT (ПРЯМОЙ) Тщательное изучение способа размещения DIRECT показывает, что он был неправильно задуман и, кроме того, неудачно назван. Не случайно КЯОД исключил его из ЯОД схемы. Однако этот способ еще встречается во многих системах и потому нуждается в пояснении. Слово прямой ассоциируется с памятью прямого доступа, однако все записи любых типов независимо от способа размещения распола- гаются в запоминающих устройствах прямого доступа. Указание спо- соба размещения DIRECT для некоторого типа записи не предусмат- ривает, так же как и при CALC, какого-либо особого способа поиска записей данного типа. Его название связано, скорее всего, с тем, что такой процесс разме- щения записи — наиболее быстрый и непосредственный. Здесь не де- лается попытка выбрать подходящую с точки зрения последующего доступа к записи позицию в памяти. Фактически способ размещения DIRECT может применяться по усмотрению программиста в одном из двух случаев, которые будут рассмотрены ниже. Синтаксис этого способа размещения довольно простой: LOCATION MODE IS DIRECT и одинаково представлен в отчетах РГБД и КЯОД. Однако КЯОД из- за некоторых возникших здесь проблем внес изменения в его семан- тику. Суть данного способа состоит в том, что программисту предостав- ляется возможность управлять размещением записей определяемого типа. Поскольку программист вынужден делать это на уровне отдель- ных записей, он должен быть хорошо знаком с методом выделения клю- чей базы данных. В любом случае ему необходимо предоставить сред- ство для сообщения системе их значений. имя-данных-1 ид-да иных-1 39
4.6.1. Назначение элементов типа ключа базы данных В основном именно для указанной цели РГБД ввела новый (по от- ношению к Коболу и ПЛ/1) тип элементов данных* TYPE IS DATA-BASE-KEY Если программисту предоставляются средства манипулирования зна- чениями ключа базы данных, то ему нужно также обеспечить возмож- ность хранения этих значений в своей рабочей области и передачи их резидентному модулю СУБД. Один из подходов РГБД к решению этой проблемы заключается в том, что администратор данных может опре- делять в записях схемы элементы типа ключа базы данных. В подоб- ном случае значения ключей действительно могут сохраняться в са- мой базе данных. Однако такая ситуация вызвала существенные воз- ражения со стороны многих исследователей. Другой подход вынужда- ет нас снова обратиться к синтаксису: LOCATION MODE IS DIRECT (имя-даннь,х’11 [ ид-данных-l J и проанализировать различие в употреблении здесь имени-данных 1- и ид-данных-1. Вариант ид-данных-1 подразумевает, что в некотором типе записи схемы определен элемент типа ключа базы данных. Этот тип записи не обязательно совпадает с тем, для которого специфицируется способ размещения. Однако именно через него программист будет передавать системе каким-то образом сгенерированное им значение ключа, кото- рое должно быть все еще свободным в базе данных и которое теперь присваивается помещаемой в нее записи. Отсюда не следует, что само значение ключа базы данных помеща- ется в базу данных, хотя это и не исключается. Администратору дан- ных достаточно определить фиктивный тип записи, состоящий только из элемента типа ключа базы данных. Можно не помещать в базу дан- ных экземпляры такого типа записи, но при включении последнего в подсхему программы появляется возможность использования опреде- ленного в нем элемента. Второй вариант синтаксиса, имя-данных-1, позволяет добиться то- го же результата без определения фиктивной записи. В отчете КЯОД отмечается, что (с. 3.3.5, разд. 3.3.4) «по своему вхождению в предло- жение LOCATION MODE имя-данных-базы-данных-1 рассматрива- ется как ключ базы данных и не является частью какой-либо записи». В этом случае имя-данных-1 представляет определяемый в схеме элемент, который автоматически включается в секцию рабочей памя- ти программы, работающей с данным типом записи. Такое необычное решение было принято в связи с желанием РГБД и КЯОД воздержать- ся от внесения изменений в существующие включающие языки про- граммирования. 40
Итак, мы установили, что при использовании типа записи со спо- собом размещения DIRECT программист обязан сам обеспечить выбор места ее расположения и что в его распоряжении должен иметься эле- мент типа ключа базы данных для сообщения системе его значений. Рассмотрим теперь методы применения этого способа размещения. 4.6.2. Применение способа размещения DIRECT ’ Для рассмотрения вопроса о том, что происходит при помещении в базу данных записи со способом размещения DIRECT, необходимо забежать вперед и обратиться к ЯМД-оператору STORE (ПОМЕСТИТЬ, СОХРАНИТЬ) с его чрезвычайно сложной семантикой. Впрочем, здесь нам понадобится лишь один из аспектов этого оператора. Выясним, что происходит при предъявлении системе значения эле- мента типа ключа базы данных перед выполнением оператора STORE. Это значение может быть допустимым, т. е. еще не использованным; недопустимым, возможно, потому, что оно уже используется; неопределенным (нулевым). В первых двух случаях программист пытается управлять распо- ложением записи в базе данных и это ему либо удается, либо нет. В третьем случае он, видимо, и не предпринимает такой попытки, т. е. он сообщает, что ему безразлично, где система разместит запись. В принципе вопрос о том, управляет ли программист размещением или нет должен решаться администратором данных. Другими словами, должны быть два различных способа размещения. Случай, когда про- граммист манипулирует ключами базы данных, заслуживает некото- рой критики. Действительно, работая на этом физическом уровне, можно добиться повышенной эффективности, но можно и получить большие неприятности. Конечно, подобную возможность следует со- хранить, но решение об ее использовании передать администратору данных. Если же программист сообщает резиденту СУБД только нулевые значения ключа базы данных, то по сформулированной РГЯБД семан- тике оператора STORE система по своему усмотрению выбирает зна- чение ключа базы данных и соответственно размещает запись, т. е. применяется алгоритм разработчика. Эта ситуация практически экви- валентна предусмотренной РГБД возможности вообще не указывать способ размещения записи, что совпадает с четвертым вариантом син- таксиса КЯОД: LOCATION MODE IS SYSTEM. Слово SYSTEM выбрано здесь не совсем удачно. Действительно, администратор данных в этом случае, очевидно, не собирается опреде- лять первичный ключ (как при CALC) или размещение по физической близости (как при VIA SET, что будет рассмотрено далее), а также пре- доставлять программисту управление физическим размещением (как при DIRECT, если программист генерирует ненулевые значения клю- ча базы данных). По-видимому, администратор данных просто хочет, 41
чтобы записи помещались в базу данных как можно быстрее, но без вмешательства программиста Подобный способ размещения следова- ло бы назвать LOCATION MODE IS FAST (БЫСТРЫЙ). Кроме того, способ размещения DIRECT должен бы обязывать программиста предоставлять ненулевые значения ключей базы данных. 4.6.3. Выборка записей Общее правило, определяющее этот вариант в отчете РГБД (с. 104» разд. 3.3.6), наверняка сбило бы с толку многих читателей, пытающих- ся понять его положения. Согласно этому правилу «если указано LO- САТЮМ MODE DIRECT, то при выполнении команды выбора записи по ее способу размещения элемент данных, специфицированный в пред* ложен и и LOCATION MODE, должен содержать некоторый ключ ба- зы данных. С другой стороны, при выполнении командь! STORE этот элемент данных может содержать ключ базы данных или неопределен- ное (нулевое) значение». Нас интересует лишь первая фраза приведенного правила. Факти- чески имеется только одна «команда, выбирающая запись на основа- нии ее способа размещения», и для этой так называемой команды явно сказано, что должен использоваться способ размещения CALC. Таким образом, первая фраза приведенного выше правила просто бес- смыслена и, более того, вызывает путаницу. К счастью, она была за- мечена КЯОД и исключена. (Читателям, знакомым с IDS/1, видимо, понятно, что ошибка РГБД возникла из-за того, что в IDS/I способ размещения в памяти и способ выборки были разделены. РГБД, пытаясь объединить эти две концепции в один «способ размещения», на самом деле полностью от- казалась от способа выборки и переименовала «способ помещения в па- мять» в «способ размещения».) Так как же все-таки находить и выбирать записи со способом раз- мещения DIRECT? Ответ на этот вопрос простой — так же, как и записи с другими способами размещения, но при одном существенном ограничении: нельзя использовать специальный метод поиска записей с размещением CALC. Запись всегда может быть найдена, если извес- тен ее ключ базы данных, вне зависимости от способа размещения. Еще раз подчеркнем, что в любом случае имеется несколько различных способов нахождения конкретной записи. Все они будут детально рас- смотрены в гл. 15, посвященной оператору FIND (НАЙТИ). 4.7. СПОСОБ РАЗМЕЩЕНИЯ VIA SET (ЧЕРЕЗ НАБОР) Для уяснения сущности способа размещения VIA SET читатель должен иметь четкое представление о типе набора. Если на этот счет есть какие-либо сомнения, рекомендуем перечитать параграф 3.4. Данный способ размещения можно указывать только в том слу- чае, когда тип записи, для которого определяется размещение, явля- 42
ется членом некоторого типа набора. Синтаксис рассматриваемого ва- рианта: LOCATION MODE IS VIA имя-набора-l SET. Фактически запись должна быть членом типа набора, указанного именем-набора-1. В этом типе набора можно определить и другие записи-члены. Описываемый тип записи может быть членом других ти- пов набора, но воздействие способа размещения VIA SET определя- ется только членством в даннохМ наборе. При таком способе размещения запись в базе данных окажется, скорее всего, физически вблизи других членов указанного набора. Оп- ределяя семантику оператора STORE, РГБД уточняет (с. 262, стро- ка 5): «...запись будет размещена... по возможности вблизи действи- тельной или вероятной точки включения в выбранный экземпляр на- бора». (Пропущенные части цитаты не имеют отношения к обсуждае- мой теме.) К сожалению, мы вынуждены коснуться сложной проблемы «вы- бора набора». Каждая помещаемая в базу данных запись может быть включена в один из нескольких наборов (см. разд. 3.4.1) указанного типа. Как правило, определенному типу набора соответствует несколь- ко экземпляров набора, один из которых должен быть каким-то об- разом выбран для размещения вблизи него записи (а возможно, и для включения в него). Процесс выбора набора рассматривается в гл. 7. Уточняя семантику способов размещения, КЯОД принял более осторожную формулировку данного способа, а именно (с. 3.36, пра- вило 9): «При задании варианта VIA имя-набора-Г SET СУБД (т. е. ее резидентный модуль) назначает ключ базы данных записи-объекту, как если бы она должна была стать членом экземпляра типа набора, указанного в фразе VIA». Заметим, что КЯОД отказался от предложенного РГБД размеще- ния «по возможности вблизи» и что его формулировка почти полно- стью совпадает с формулировкой РГЯБД. На самом деле подход КЯОД—РГЯБД не совсем оправдан. Рас- смотрим, например, следующую V-образную структуру: Если тип записи С имеет способ разме- щения CALC или DIRECT, то ключ базы данных будет назначаться без учета член- ства записи в двух указанных наборах. Однако если этот тип записи имеет способ размещения VIA ВС SET, то принадлеж- ность к набору ВС должна иметь какое-то значение для размещения в отличие от при- надлежности к АС. При помещении в базу данных запись С, вероятно, будет включена как в набор АС, так и в набор ВС, независимо от ее способа, размещения. Таким образом, если указание одного (а не другого) типа набора в определении способа размещения хоть что-нибудь означает, то оно должно подразумевать попытку обеспечить физическую близость участников (владельца и членов) этого набора. 43
На практике в большинстве систем принята именно такая интер- претация VIA SET. Собственно, попытка обеспечить физическую бли- зость участников и отличает данный способ размещения от SYSTEM (или DIRECT с нулевыми значениями ключа базы данных). 4.7.1. Выборка записей В отчете РГБД, как и в случае DIRECT, вновь упоминается о «вы- борке на основе способа размещения» (тоже исправлено КЯОД), что только вводит читателей в заблуждение. Для записей со способом раз- мещения VIA SET нет специального варианта выборки. Правда, тип записи с данным способом размещения является по определению чле- ном указанного типа набора, что фактически обеспечивает некоторые дополнительные возможности поиска по сравнению с ситуацией, когда он не входит в этот набор. 4.8. ОБЛАСТИ Понятие области уже встречалось нам при обсуждении способа размещения CALC. Рассмотрим его теперь более подробно. В настоя- щей книге используется предложенный РГЯБД термин realm (область) вместо применяемого РГБД и КЯОД термина area, хотя именно по- следний встречается в спецификациях большинства систем. Замена термина связана с тем, что слово area уже используется в Коболе для обозначения совокупности позиций (как правило, смеж- ных) в оперативной памяти, а также в понятии области копирования (saved area) . Комитет по языку программирования КОДАСИЛ призы- вает избегать использования уже применяемого для других операций слова В отчете РГБД область определяется как (с. 13) «поименованный раздел адресуемого пространства базы данных, который может содер- жать экземпляры записей и наборов или фрагментов наборов различ- ного типа». Это определение заменено КЯОД на следующее: «Область есть поименованная совокупность записей, для которой нет надобности сохранять отношения владелец—член. Область может содержать эк- земпляры одного или нескольких типов записи, причем экземпляры некоторого типа записи могут входить более чем в одну область. Кон- кретная запись приписывается одной области и не может быть переме- щена в другую. Область может быть...»8 Здесь КЯОД явно избегает формулировки «адресуемое простран- ство памяти», о котором говорит РГБД. Однако во всех реализованных системах область является именно таким разделом этого пространст- ва. Концепция области оказалась с самого начала своеобразным яб- локом раздора. В конце концов было принято, что администратор дан- ных должен приписывать типы записи к областям, как это отмечается в спецификациях КЯОД. Более того, он обязан с помощью языка уп- равления размещением на внешних носителях (см. параграф 2.6) при- 44
писать каждую область к определенному типу внешнего запоминаю- щего устройства и ему еще предоставляются средства детального уп- равления размещением в ней записей. Программисту следует знать только о распределении типов записи по областям. Остальные сведе- ния ему, как правило, не нужны (за исключением случая использова- ния особого варианта ЯМД-оператора FIND, о котором речь пойдет позже). Если администратор данных почему-либо не желает применять концепцию областей, он может разместить всю базу данных, т. е. все типы записи в одной всеобъемлющей области. Тем не менее програм- мист должен «открывать» эту область в начале своей программы и «за- крывать» в конце. Разделение базы данных на области имеет свои преимущества. На- пример, оно позволяет распределять базу данных на запоминающих устройствах прямого доступа различного типа и создает возможность повышения общей эффективности при параллельной обработке дан- ных. Недостатком разработанной РГБД методики работы с областями является необходимость включения в программу оператора READY (ОТКРЫТЬ). Сторонники концепции области возражают (и вполне < справедливо), что это открытие можно выполнять неявно при «вызове»j подсхемы. 4.8.1. Приписка типа записи к области Провесе приписки типа записи к одной или нескольким областям достаточно прост. Он выполняется в той части ЯОД схемы, называе- мой статьей записи, где объявляются все свойства каждого типа запи- си (такие, как ее способ размещения). Соответствующий синтаксис РГБД: jWITHIN имя-области-1 [{,имя-области-2}.... REALM-ID IS имя-данных-2) Мы заменили здесь слово AREA на REALM для однозначности терминологии. В большинстве случаев тип записи приписывается только к одной области, и синтаксис существенно упрощается: 'WITHIN иия-области-1. Если же администратор данных знает, что будут поставлены десят-' ки тысяч записей некоторого типа, и в то же время не хочет определять слишком большие области, он может приписать этот тип записи к двум или более областям. Возможно, это связано G установленным разра- ботчиком предельным размером областей, но чаще проблема состоит в том, что поддержка областей большого размера сопряжена с опреде- ленными трудностями. Для распределения записей по двум или более областям необхо- димо использовать некоторый критерий или признак. Это опять ло- 4»
жится на плечи программиста, составляющего программу помещения новых записей в базу данных. Он должен присвоить элементу данных, указанному именем-данных-2, имя одной из областей, перечисленных в предложении WITHIN. Таким образом, решение о распределении типа записи по двум или более областям принимает администратор данных, а решение о том, в какую из этих областей поместить конкретные запи- си данного типа,— программист, составляющий программу загрузки записей. Предложение WITHIN было дополнено КЯОД двумя новыми ва- риантами, которые пока еще не нашли широкого применения. Его син- таксис (расширенный) имеет вид: имя-области-1 [{,имя-области-2}... REALM-ID IS' имя-данных-1 WITHIN [USING PROCEDURE имя-процедуры-Ijj REALM OF OWNER Первое дополнение связано с рассмотренньш выше вопросом о при-' нятии решений. Если администратор данных решает сам управлять конкретным распределением записей по областям, то он может написать процедуру базы данных, выполняющую соответствующие действия. Указанная процедура будет автоматически присваивать значение эле- менту имя-данных-1 и программист уже не сможет повлиять на этот процесс. Однако такая возможность зависит от наличия процедур базы данных, которые отнюдь не везде реализованы. Вторая идея КЯОД состоит в том, чтобы разрешить администрато- ру данных приписывать типы записи со способом размещения VIA SET (см. параграф 4.4) к той же области, в которой расположен владе- лец типа набора, указанного в определении способа размещения. Та- кое разрешение вполне оправдано, если интерпретировать способ раз- мещения VIA SET в терминах физической близости участников набора, как было предложено в настоящей книге. В некоторых системах этот подход принят как обязательное правило. Действительно, вряд ли име- ет смысл выбирать способ размещения VIA SET, а затем размещать за- писи владельца и членов в различных областях. В предложениях РГБД подобное правило отсутствует. КЯОД, по крайней мере, допускает его применение как один из возможных вариантов. 4.8.2. Временные области Завершая обсуждение распределения типов записи по областям, мы должны упомянуть о временных областях. Это понятие редко встре- чается в реализованных системах, что частично объясняется опреде- ленными трудностями реализации, а возможно, и сомнением разработ- чиков в его необходимости для пользователя. Временной (temporary) называется область, которую программист использует как «рабочую память» в процессе выполнения программы. Как и другие области, ее нужно открывать для использования, но
при выполнении оператора READY предоставляется копия данной об- ласти, не содержащая никаких записей. Соответственно при закрытии этой области все размещенные в ней записи исчезают. Основное различие постоянных (permanent) и временных областей состоит в следующем. Если две параллельно выполняемые программы открывают одну и ту же постоянную область, то они получают доступ к одним и тем же физическим данным. Если же эти программы откры- вают временную область, то каждой предоставляется своя собственная копия этой области, т. е. для них выделяются отдельные дорожки дис- ка. Последнее обстоятельство и является одной из причин трудности реализации данной концепции. Сегодняшние операционные системы не всегда предусматривают такую возможность, а разработчику СУБД нелегко внести исправления в имеющуюся операционную систему. Как же пользоваться временными областями, если такая возмож- ность все-таки существует? Включающий язык, будь то Кобол, Форт- ран или ПЛ/1 предоставляет программисту средства размещения за- писей на запоминающих устройствах прямого или последовательного доступа на время выполнения его программы. Единственное преиму- щество временной области состоит в том, что записи в ней связаны структурой с использованием наборов. Напомним, однако, что за оп- ределение типов записи, типов набора и областей несет ответственность администратор данных. Если программисту требуются временные об- ласти, администратор данных должен это предусмотреть, определить необходимые области и приписать к ним соответствующие типы записи. Во избежание недоразумений при использовании временных облас- тей РГБД ввела правило, согласно которому (по измененному КЯОД тексту, с. 3.25) «Записи временных областей не могут быть владельца- ми или членами наборов, включающих записи, не расположенные в данных областях». (Это правило следовало бы записать не в множест- венном, а в единственном числе.) Оно устанавливает, что если времен- ная область предназначается для размещения структурированных в на- боры записей, то и владелец, и члены набора должны размещаться в данной области. Отсюда также вытекает, что в рассматриваемом слу- чае необходимо применять так называемые рабочие типы записи или же типы записи, приписанные, по крайней мере, к одной постоянной и к одной временной областям (с помощью варианта REALM-ID, пред- ложения WITHIN). В последней ситуации распределением записей между временными и постоянными областями должна заниматься сама программа. Однако будем надеяться, что подобные ситуации возника- ют довольно редко. 4.9. ЗАКЛЮЧЕНИЕ В настоящей главе были рассмотрены вопросы представления типа записи во внешней памяти. Для этого нам понадобилось ввести поня- тия ключа базы данных и области, являющиеся фундаментальными концепциями предложений РГБД. С целью обобщенного представления приведем соответствующие , части КЯОД-синтаксиса статей области и записи, включающие два рас- 47
смотренных ранее предложения: {REALM NAME IS имя-области-1 [; REALM IS TEMPORARY]}.,, {RECORD NAME IS имя-записи-1 LQCATION ; WITHIN [имя-данных-11 DIRECT --------[ид-данных-l J CALC [имя-проц-l] USING ид-данных-2 [, иД-данных-3]... DUPLICATES ARE ВТ) ALLOWED имя-набора-1 SET SYSTEM имя-области-1 [{, имя-области-2}... REALM-ID IS имя-данных-2 [USING PROCEDURE имя-проц-2]} REALM OF OWNER Здесь намеренно опущены некоторые еще не обсуждавшиеся свой- С' ва и, в частности, весь процесс определения внутренней структуры записи. Ниже в примерах будут использоваться только наиболее рас- пространенные из них. 4.9.1. ПРИМЕР b- REALM NAME IS ОБЛАСТЬ-ПОСТАВЩИКА. RECORD NAME IS ПОСТАВКА-; LOCATION MODE IS CALC USING КЛЮЧ-РАЗМЕЩ DUPLICATES ARE NOT ALLOWED; WITHIN область-поставщика. RECORD NAME }S ПОСТАВЩИК; ™^DE __________________ПОСТАВЩИКИ SET; RECORD NAME LOCATION MODE IS CALC USING ЙД- ЗАКАЗА, ПОСД6Д-НОМЕР-ЗАКАЗА DUPLICATES ARE NOT ALLOWED; WIT HIN ОБ Л АСТЬ-ПОСТ ДВЩИ KA. RECORD NAME IS ГРАФА-ЗАКАЗА-ПОКУПКИ; LOCATION MODE IS VIA COCTAB-3AKA3A SET; WITHIN ОБЛАСТЬ-ПОСТАВЩИКА. Данный пример иллюстрирует описание области и типов записи в этой об- ласти. Два типа записи цмеют способ размещения CALC, а два других—VIA SET. В последних упоминаются два типа набора, описание которых будет рас- сматриваться позднее. За предложением WITHIN для каждого типа записи дол- жен, вообще говоря, следовать список элементов с указанием их характеристик. Подробно описание элементов рассматривается в гл. 9. ЛИТВРАТУРА 1. L u m V. Y.. Yuen P. S. T., D о d d M. Key-to-Address Transformation Techniques: A Fundamental Performance Study on Large Existing Formatt ed Files.— Comm of ACM, April 1971, p. 228—239. 2. В u chholz W. File Organization and Adressing. — IBM Syst. J., June 1963, p. 86-111,
ГЛАВА 5 ПРЕДСТАВЛЕНИЕ ТИПОВ НАБОРА ВО ВНЕШНЕЙ ПАМЯТИ 5.1. ВВЕДЕНИЕ В гл. 3 мы определили тип набора как средство построения струк- турных связей между записями и сравнили его с традиционными внут- ренними структурами записи, получившими распространение в 60-х годах в качестве метода представления несложных иерархических структур на носителях с последовательным доступом. Там же было рассмотрено назначение типов записи-владельца и за- писей-членов и выделены три класса наборов: с одним членом, с не- сколькими членами и сингулярные. Напомним, что каждому типу на- бора должно быть присвоено отдельное имя и что любому определен- ному в схеме типу набора соответствует, в базе данных несколько набо- ров (или экземпляров набора), хотя некоторые из них могут оказаться «пустыми». В последнем случае в наборе имеется экземпляр записи- владельца, но Йет ни одного экземпляра записей-членов. В заключение с помощью типа набора строились различные струк- туры базы данных. Изучая диаграммы этой главы, легко заметить, что тип набора воплощает связь между типами записей. Однако, как уже отмечалось, можно идентифицировать много различных связей между двумя типами записи, и администратор данных на оснований каких- либо практических соображений должен решить, которые из них будут включены в структуру базы данных. Точнее, он каждый раз должен решать, оправдано ли определение некоторого типа набора как допол- нительного пути доступа, облегчающего и ускоряющего процесс поис- ка и выборки записей. При обсуждении способа размещения упоминалось о том, что «всег- да имеется несколько способов поиска записи», а определение для неко- торого типа записи размещения CALC добавляет еще один способ по- иска. Спецификация участия типа записи в некотором типе набора также дает дополнительный способ поиска. Тип записи может иметь единственный способ размещения, но допускается его участие в не- скольких типах набора, причем каждое такое участие добавляет еще один способ (путь) доступа к записи. Прежде чем перейти к обсуждению представления типа набора в памяти, заметим, что совершенно не обязательно явно определять в базе данных хотя бы один тип набора. Администратор данных может специфицировать базу данных, состоящую из одного или даже из сот- ни типов записи без единого типа набора. В этом крайнем случае ни один из типов записи не может иметь способ размещения VIA SET. Было бы по меньшей мере странным использовать базирующуюся на предложениях КОДАСИЛ СУБД, не применяя типы набора, но факт остается фактом — типы набора можно не определять. При изучении 49
подсхем мы увидим, что даже если типы набора определены в схеме, они не обязательно должны включаться в подсхему. Наконец, остают- ся еще неявные связи, которые будут обсуждаться в гл. 24 в связи с из- ложением реляционной модели. 5.2. МЕТОДИКА ПРЕДСТАВЛЕНИЯ Рассматривая представление типов записи, мы исследовали вопрос о помещении конкретных записей в ту или иную область и о размеще- нии их внутри выбранной области. Хотя речь все время шла о размеще- нии, имелось в виду относительное расположение внутри области (или областей), а не выбор конкретного пакета дисков, цилиндра и дорожки. Переходя к представлению типов набора, заметим, что оно не про- тиворечит представлению участвующих в нем типов записи владельца и членов, а, напротив, между ними имеется определенная взаимосвязь. Записи различных типов размещаются в соответствии с указаниями предложения способа размещения и предложения WITHIN. Тема представления типа набора во внешней памяти настолько выделяется в каждом кратком обзоре предложений КОДАСИЛ (вклю- чая и обзор, подготовленный автором (1J), что у невнимательного чи- тателя может сложиться впечатление будто все идеи РГБД сводятся именно к ней. Однако это не так. В базирующихся на предложениях КОДАСИЛ СУБД есть еще много интересного и полезного, что нахо- дит подтверждение в настоящей книге. 5.3. ВИДЬ! ПРЕДСТАВЛЕНИЯ НАБОРОВ С целью обозначения варианта представления, который должен указываться администратором данных для каждого типа набора в базе данных, РГБД ввела термин вид набора (set mode). Было предложено два альтернативных вида набора: цепочка (chain) и массив указателей (pointer array). Выбор первого варианта, как будет показано далее, требует принятия нескольких дополнительных решений. Понятия вида набора и двух его вариантов занимали центральное место в подходе РГБД к представлению связанных с ними объектов. Поэтому отказ от идеи вида набора как одного из средств ЯОД является одним из самых существенных изменений, внесенных КЯОД. Значение такого отказа станет более очевидным после детального рассмотре- ния упомянутых понятий. Концепции цепочек и (в несколько меньшей степени) массивов указателей встречаются в большинстве реальных систем, так что ни один обзор не может считаться полным без их деталь- ного обсуждения. 5.4. ЦЕПОЧНОЕ ПРЕДСТАВЛЕНИЕ НАБОРА Для иллюстрации цепочного представления рассмотрим тип набора с одним членом, приведенный на рис. 5.1 (воспроизводится с рис. 3.5). 50
Напомним, что в настоящей книге прямо- угольники обозначают типы записи, а окруж- ности — экземпляры записей. На рис. 5.2 показано графическое пред- ставление экземпляра данного типа набора. Соединительные линии (специально без стре- лок) здесь свидетельствуют о том, что три записи ОБРАЗОВАНИЕ и одна запись СЛУ- ЖАЩИЙ принадлежат одному и тому же на- бору. В данной книге применяется выраже- ние «записи ОБРАЗОВАНИЕ подключены к набору» (по ЯМД-оператору CONNECT (ПОД- СОЕДИНИТЬ, ПОДКЛЮЧИТЬ), предложенному РГЯБД вместо соответствующего оператора РГБД INSERT (ВКЛЮЧИТЬ)). Каким образом обеспечивается связь между записями — зависит от детали- зации вида набора. 5.5. ЦЕПОЧКА С УКАЗАТЕЛЕМ СЛЕДУЮЩЕЙ ЗАПИСИ Простейшим представителем цепочки является цепочка с указате- лем следующей записи, пример которой дается на рис. 5.3. Здесь имеется в виду, что запись-владелец содержит указатель на «первую» запись набора, а именно на запись «БН 1959». Практически Рис. 5.2. Экземпляр одночлен- ного типа набора Рис. 5.3. Цепочка с указателем следующей записи это означает, что ключ базы данных записи «БН 1959» помещается в запись «Смит». (Ключи базы данных подробно рассмотрены в парагра- фе 4.2). Далее, ключ базы данных записи «МН 1961» помещается в за- пись «БН 1959» и т. д. Последняя запись на рис. 5.3 «ДФ 1966» содержит указатель на запись-владельца «Смит», тем самым «замыкая» цепочку (в отличие от незамкнутых структур, применяемых в некоторых других системах). Смысл такой цепочной структуры состоит в том, что она обеспечи- вает последовательный доступ к записям-членам. Если для записи-вла- дельца определен способ размещения CALC, то ее можно найти непо- средственно и от этой точки поочередно перебрать все записи-члены. 51
В терминах примера можно таким образом просмотреть три записи об- разования Смита. Подчеркнем, что тип записи ОБРАЗОВАНИЕ также допускает спо- соб размещения CALC. При таком способе размещения записи образо- вания можно выбирать как непосредственно, так и через набор. Подробнее методы доступа будут рассмотрены позднее, но прежде чем перейти к следующему типу цепочек, необходимо сделать несколь- ко замечаний. 5.5.1. Проблема коррекции указателей Проанализируем реальную ситуацию, когда в наборе имеется 2000 записей-членов. (Достаточно было бы и трех, но тогда уменьшится на- глядность примера.) Довольно часто приходится полностью удалять (или убирать) записи из базы данных. В таких случаях резидент СУБД (заметим — непрограммист) обязан соответствующим образом скорректировать указатели. Он должен иметь доступ к предшествую* щей записи, чтобы заменить в ней указатель и установить его на запись, следующую за удаляемой. Именно доступ к предшествующей записи и составляет проблему. Единственный способ добраться до нее — прой- ти по всему кольцу цепочки. Если же каждая из 2000 записей располо- жена на своей дорожке диска, то потребуется 2000 обращений к дис- ку, т. е. чрезвычайно большой расход машинного времени. Опытный программист, умеющий тщательно проектировать свою собственную систему, может здесь подсказать, что если мы добираемся до удаляемой записи по цепочке, то достаточно сохранять ключ базы данных предшествующей записи. К сожалению, «прохождение по цепоч- ке» не является единственным способом доступа к удаляемой записи, и это приходится учитывать при реализации операции удаления. 5.5.2. Применение цепочек с указателем следующей записи Преимущество цепочной структуры с указателем следующей за- писи заключается в том, что она по памяти экономичнее других пред- ставлений набора. Такой структурой целесообразно воспользоваться при большом числе небольших наборов (например, при 1000 наборов не более чем по 10 записей в каждом). Но если записи часто удаляются, то даже и в этой ситуации рекомендуется применить какое-нибудь дру- гое представление. Однако администратор данных может определить для типов записей-членов способ размещения VIA SET (через упомяну- тый набор данных). Тогда записи-члены будут иметь тенденцию рас- полагаться на одной и той же странице области, что оправдает приме- нение цепочки с указателем следующей записи. Оценивая возможность принятия такого решения, администратор данных должен учитывать размеры страницы, записи, указателя (т. е. ключа базы данных) и набора, а также частоту удаления записей. 52
5.6. ЦЕПОЧКИ С УКАЗАТЕЛЕМ СЛЕДУЮЩЕЙ И ПРЕДЫДУЩЕЙ ЗАПИСЕЙ Описанная выше проблема доступа к предшествующей записи пол- ностью снимается при использовании других представлений типа на- бора, в частности цепочки с указателем следующей и предыдущей запи- сей. Такая структура приведена на рис. 5.4. Рис, 5.4. Цепочка с указателем следующей и предыдущей записей Рис. 5.5. Экземпляр набора с несколькими типами записей-членов Каждая запись набора здесь содержит два указателя (т. е. значе- ния ключа базвт данных). Поэтому при удалении записи из большого набора становятся легко доступными как следующая, так и предыду- щая запись. 5.6.1. Случай типа набора с несколькими типами записей-членов До сих пор при обсуждении цепочек с указателем следующей запи- си и цепочек с указателем следующей и предыдущей записей мы огра- ничивались рассмотрением типов набора с одним членом. Важно заме- тить, что оба эти вида представления набора не зависят от того, один или несколько типов записей-членов он включает Записи-члены раз- личных типов могут следовать вперемешку в экземпляре многочленного типа набора. Таким образом, описанные цепочные представления явля- ются свойствами типа набора, а не его записей-членов. На рис. 5.5. показан экземпляр типа набора, изображенного на рис. 3.6. Заметим, что последовательность записей-членов в наборе не зави- сит от вида его представления Она определяется так называемым порядком набора (set order), который будет рассмотрен позднее. Пере- мешивание записей ОБРАЗОВАНИЕ и ДОЛЖНОСТЬ на рис. 5.5 является вполне допустимым. 5.6.2. Недостаток цепочек с указателем следующей и предыдущей записей Цепочки с указателем следующей и предыдущей записей являются довольно удобным средством представления набора и находят гораздо более широкое применение, чем цепочки с указателем следующей за- 53
писи. Действительно, при обработке данных приходится удалять запи- си достаточно часто. Однако и для тех, и для других цепочек существует серьезная про- блема, связанная с необходимостью перехода от члена некоторого набо- ра к владельцу. Напомним, что программист располагает несколькими способами доступа к записям базы данных. Рассмотрим, например, тип записи ОБРАЗОВАНИЕ (см. рис. 5.1) со способом размещения CALC. В ~>том случае можно найти некоторую запись ОБРАЗОВАНИЕ, не обращаясь предварительно к записи СЛУЖАЩИЙ. Пусть теперь нам нужно перейти к записи-владельцу. Такая возможность всегда имеется, но если задан вид размещения набора цепочкой, то нужно пройти по ней, а это опять вызывает значительный расход машинного времени. 5.7. ЦЕПОЧ КИ С УКАЗАТЕЛЕМ ВЛАДЕЛЬЦА Если администратор данных предполагает, что для некоторого типа набора будет часто выполняться переход от записей-членов к владельцу, он может задать представление, при котором член тш Рис. 5.6. Представление одно- членного типа набора цепочкой с указателями следующей запи- си и владельца Рис. 5.7. Представление одно- членного типа набора цепочкой с указателями следующей и предыдущей записей и владель- ца па набора содержит указатель владельца. Заметим, что наличие ука- зателя владельца является свойством типа записи-члена, а не типа набора. Однако для типов набора с одним членом (особенно если СУБД допускает только такие типы набора) эта разница не имеет значения. Задание указателя владельца не зависит от наличия указателя пре- дыдущей записи, хотя ситуации, при которых желательно иметь ука- затель владельца, часто требуют определения и этого указателя. Теперь мы имеем несколько новых представлений типа набора. На рис. 5.6 и 5.7 показаны наборы с одним типом записи-члена. В первой и последней записях набора с указателями следующей и предыдущей записей два из имеющихся указателей всегда совпадают. Тем не менее они хранятся в записи как если бы они были разными, что существенно облегчает включение в набор записей, примыкающих к владельцу. Последнее не означает физической близости. Когда речь 54
идет о позиции в наооре или цепочке, имеется в виду относительная позиция. К этой теме мы еще вернемся при обсуждении порядка набора. Следует отметить, что в многочленном типе набора вполне возможна ситуация, при которой для одного типа члена определен указатель вла- дельца, а для другого — нет (рис. 5.8). Если многочленный тип набора включает более двух типов запи- сей-членов, то для любого из них (и даже для всех) может быть опреде- лен указатель владельца. Пример на рис. 5.8 легко расширить, вклю- чив в него указатель на предыду- щую запись или указатель владель- ца для записи ОБРАЗОВАНИЕ, либо и тот и другой. Можно, разумеется, предусмотреть, чтобы указатель вла- дельца имел запись ОБРАЗОВАНИЕ, а не запись ДОЛЖНОСТЬ: Таким образом, как указатель пре- дыдущей записи, так и указатель вла- дельца для каждого типа записи-чле- на должны применяться в зависимо- сти от ситуации. Иногда администра- тору данных кажется проще специфи- цировать все возможные указатели (на всякий случай). Однако такой подход нельзя считать обоснованным. Рис. 5.8. Представление многочлен- ного типа набора цепочкой с ука- зателями следующей записи и вла- дельца для одного из членов Для небольших баз данных эго еще приемлемо. Но если база данных велика, причем за счет большого числа небольших наборов, и если записи группируются соответству- ющим заданием способа размещения VIA SET, то наличие указате- лей владельца и предыдущей записи может привести к напрасному расходу памяти, а при операциях ведения базы данных (постановка и удаление записей), возможно, и машинного времени. 5.8. МАССИВЫ УКАЗАТЕЛЕЙ Концепция цепочек с указателем следующей записи с возможно- стью определения указателей предыдущей записи и владельца заимст- вована РГБД из хорошо проверенной на практике системы IDS, разра- ботанной Бахманом в 1962 г. в фирме General Electric. Заметим, что в этой системе (теперь IDS/1) термин тип набора (или набор) не исполь- зуется, а фактически единственным допустимым типом набора в ней яв- ляется набор с цепочной структурой. Из концепции цепочек РГБД вывела концепцию наборов и решила добавить еще один способ представления наборов в памяти — массив указателей. Чтобы обосновать введение массивов указателей, рассмотрим цепоч- ное представление одночленного или многочленного типа набора, в котором определены указатель предыдущей записи и указатель вла- дельца для всех записей-членов. Такое представление типа набора, при- 55
веденного на рис. 3.6, показано на рис, 5.9. Здесь каждая запись содер- жит три указателя. Для лучшего уяснения соответствующей структуры с массивом ука- зателей переместим каждый указатель' следующей записи в такой массив, «уберем» каждый указатель предыдущей записи, а указатель Рис. 5.9. Представление многочленного типа набо- ра цепочкой с указателями следующей и предыду- щей записей и указателем владельца для всех членов владельца оставим как он есть (рис. 5.10). На рисунке стрелками обо- значены указатели от записи-владельиа к каж- дой записи-члену. Это не должно создавать впе- чатления, что все указа- тели следующей записи из цепочной структуры теперь располагаются в записи-владельпе. Прак- тически они помещаются владельца и никогда не в запись- не распо- лагаются в памяти в непосредственной близости от него Вопрос о том, где именно и каким образом разместить массив указателей, ос- тавляется полностью на усмотрение разработчика. Важным свойством массива указа- телей является то, что быстрое выпол- нение операций над цепочной струк- турой с указателями предыдущей за- писи и владельца для всех членов обеспечивается здесь только при двух указателях на одну запись-члена, тогда как в цепочной структуре (см. рис. 5.8) используются три указате- ля. Таким образом, массив указате- лей позволяет сэкономить один указа- тель на каждой записи-члене. При использовании массива ука- зателей программист может обраба- тывать набор в любом направлении и Рис. 5.10 Представление много- членного типа набора с помощью массива указателей переходить от записи-члена к записи- владельцу без риска увеличения вре- мени выполнения операций. 5.8.1. Реализация массивов указателей Массивы указателей пока еще не нашли широкого применения в ре- альных системах. Большинство разработчиков решило, что опыт Gene- ral Electric (а затем и Honeywell) в работе с цепочками демонстрирует их достаточную эффективность, и поэтому реализация массивов ука- зателей не включалась в разработку или, по крайней мере, отклады- 56
валась. Действительно» цепочные структуры несколько легче реализу- ются и, видимо, «только цепочные» системы коммерчески более жизне- способны, чем системы «только на массивах указателей» Такой «толь- ко цепочный» подход предоставляет администратору данных дополни- тельные возможности по управлению соотношением между расходом памяти и временем обработки, и осуществлять это управление, дейст- вительно, нетрудно. Однако уже сейчас можно предсказать, что мас- сивы указателей со временем будут получать все большее признание и распространение. 5.9. ОТКАЗ КЯОД ОТ УКАЗАНИЯ ВИДА ПРЕДСТАВЛЕНИЯ НАБОРА Как отмечалось выше, спецификации РГБД давали администрато- ру данных возможность определять цепочки или массив указателей для каждого типа набора в базе данных, Если выбирались цепочки, то можно было еще задать указатель предыдущей записи для всего типа набора и указатель владельца для каждого его члена. Важно подчеркнуть, что выбор любого вида представления набора и, в частности, тех или других указателей при цепочном представлении совершенно не влияет на процесс составления программы. Следователь- но, программист может ничего не знать о спецификации вида представ- ления набора в схеме, хотя такая информация может помочь ему напи- сать более эффективную программу По-видимому, именно тот факт, что программист не обязан учиты- вать представление набора, побудил КЯОД отказаться от его указа- ния в ЯОД схемы. Фактически это понятие было удалено лишь на две трети, так как КЯОД (в характерной для комитетов манере принимать компромиссное решение) сохранил концепцию набора, проходимого в обратном направлении, и концепцию указателя владельца. Однако не осталось никакого упоминания о цепочках и массивах указателей. Отказ от указания вида представления набора может быть связан также с явной ориентацией на особенности реализации в дискуссиях РГБД по поводу цепочек и массивов указателей. Поскольку програм- мисту не нужно знать о подобном указании, следует отнести концеп- цию представления набора, скорее, к ЯУВН, чем к ЯОД схемы. Но комитеты КОДАСИЛ никогда не заявляли, что ЯОД схемы содержит только то, что должно быть известно программисту. Столь подробное изложение концепций цепочки и массива указате- лей может показаться несколько излишним. Однако эти понятия чрез- вычайно важны для уяснения подхода КОДАСИЛ к управлению база- ми данных. 5.10. СИНТАКСИС ВИДА ПРЕДСТАВЛЕНИЯ НАБОРА Описание структуры базы данных на ЯОД схемы состоит из неко- торого числа так называемых статей (entry). Различают четыре типа таких статей: статью схемы, статью области, статью записи и статью на- бора. 57
В предыдущей главе мы рассмотрели отдельные части статьи об- ласти и статьи записи. Статья набора, как и статья записи, включает две подстатьи: подстатью набора и подстатью члена. Ниже мы пояс- ним, почему подстатья набора является частью его статьи. Синтаксис РГБД для уже известных нам понятий из статьи набора имеет ьид (с. 126.7, с сокращениями): SET NAME IS имя-набора-1 ( CHAIN [LINKED TO PRIOR] ] ; MODE IS I p01NTER ARRAY J _ f имя-записи-l 'i ; QWNE^_IS SYSTEM j {MEMBER IS имя-записи-l { } { } [LINKED TO OWNER] Здесь опущены части статьи набора, которые еще не обсуждались в данной книге. Можно сравнить этот синтаксис с синтаксисом КЯОД (с. 3.4.0 и 3.4.1, с сокращениями): SET NAME IS имя-набора-1 {имя-эаписи-I ) SYSTEM J (; SET IS PRIOR PROCESSABLE] {MEMBER IS имя-записи-l { } { } [LINKED TO OWNER] }... Поскольку в подстатье члена имя записи-члена указывается в пер- вом предложении, КЯОД внес небольшое изменение, переместив пред- ложение «ВЛАДЕЛЕЦ» из конца статьи набора в ее начало. 5.10.1 Примеры описания наборов Используя синтаксис РГБД, который чаще встречается на практике, при- ведем примеры описаний некоторых представлений наборов, рассмотренных ра- нее в данной главе. Пример 1 (см. рис. 5.1 и 5.3) SET NAME IS СО; MODE IS CHAIN; OWNER IS СЛУЖАЩИЙ. MEMBER IS ОБРАЗОВАНИЕ, Пример 2 (см. рис. 5.1 н 5.4) SET NAME IS CO; MODE IS CHAIN LINKED TO PRIOR; OWNER IS СЛУЖАЩИЙ. MEMBER IS ОБРАЗОВАНИЕ. 58
Пример 3 (см. рис. 3.6 и 5.5) SET NAME IS СОД; MODE IS CHAIN; OWNER IS СЛУЖАЩИЙ. MEMBER IS ОБРАЗОВАНИЕ. MEMBER IS ДОЛЖНОСТЬ. Пример 4 (см. рис. 5.1 и 5.6) SET NAME IS CO; MODE IS CHAIN; OWNER IS СЛУЖАЩИЙ. MEMBER IS ОБРАЗОВАНИЕ LIN KED TO OWNER. Пример 5 (см. рис. 3.6 и 5.8) SET NAME IS СОД; MODE IS CHAIN: OWNER IS СЛУЖАЩИЙ. MEMBER IS ОБРАЗОВАНИЕ. MEMBER IS ДОЛЖНОСТЬ LINKED TO OWNER. Пример 6 (см. рис. 3.6 и 5.9) SET NAME IS СОД; MODE IS CHAIN LINKED TO PRIOR; OWNER IS СЛУЖАЩИЙ. MEMBER IS ОБРАЗОВАНИЕ LINKED TO OWNER. MEMBER IS ДОЛЖНОСТЬ LINKED TO OWNER. Пример? (см. рис. 3.6 и 5.10) SET NAME IS СОД; MODE IS POINTER ARRAY; OWNER IS СЛУЖАЩИЙ. MEMBER IS ОБРАЗОВАНИЕ. MEMBER IS ДОЛЖНОСТЬ. Полезно отметить, что при использовании синтаксиса КЯОД различие между примерами 6 и 7 устраняется и их описание принимает следующий вид: Примере : SET NAME IS СОД; OWNER IS СЛУЖАЩИЙ. SET IS PRIOR PROCESSABLE. MEMBER IS ОБРАЗОВАНИЕ LINKED TO OWNER MEMBER IS ДОЛЖНОСТЬ LINKED TO OWNER. В последний пример мы включили фразу LINKED ТО OWNER для каждого типа записи-члена. Из синтаксиса КЯОД подстатьи члена видно, что такое ука- зание является необязательным (с. 3.71, правило 4): «Необязательная фраза LINKED ТО OWNER приводит к тому, что для типа набора, определение кото- рого содержит данную подстатью члена набора, СУБД предпочтительно выби- рает метод представления, обеспечивающий прямой доступ в наборе от такой за- писи-члена к записи-владельцу. Фраза ,..». Однако ЯОД схемы по предложениям КЯОД не должен учитывать разницу между представлением цепочками или массивом указателей, но тогда стано- вится неясным, что происходит, если фраза LINKED ТО OWNER не задана. Если же эта фраза присутствует, то все равно остается неясность из-за выраже- ния «предпочтительно выбирает». В любом случае очевидно, что выбор представ- ления осуществляет сама СУБД, а опытный администратор данных наверняка поинтересуется, какой именно выбор она сделает. Идея использования массива указателей без указателей владельца почти полностью неприемлема. Если программист действительно ничего не знает о представлении такого типа набора, то его попытка перейти от записи-члена к владельцу может быть реализована только последовательным просмотром всех записей-владельцев с проверкой наличия указателя на запись-член, с которой начинался поиск (незавидная перспектива!). ЛИТЕРАТУРА 1. О 1 1 е Т. W. Tutorial on CODASYL Data Base Management Concepts. Proceedings of British Computer Society Symposium held October 1974 on Imple- mentations of the CODASYL DBMS Proposals. 2. В achm ап C. W., W il 1 i a ms С. B. A General Purpose Program- ming System for Random Access Memories,— Proc, FJCC, 26, 1964, p. 411—422. 59
ГЛАВА 6 УПОРЯДОЧЕННОСТЬ НАБОРА И КЛЮЧИ ПОИСКА 6.1. ВВЕДЕНИЕ В предыдущей главе рассматривалось представление типа набора во внешней памяти. Были исследованы различные аспекты этой проб- лемы, и теперь читатель знаком с цепочками и массивами указателей. Ему, в частности, должно быть известно, что их использование почти совершенно не зависит от представления в памяти типов записи, а ес- ли не учитывать способ размещения VIA SET, то можно говорить об их полной независимости. 6.2. УПОРЯДОЧЕННОСТЬ НАБОРА . Здесь мы переходим к вопросу о том, как члены набора упорядо- чены друг относительно друга. Выше уже встречались понятия первой и последней записей в наборе. Но что означает слово «первая»? Может быть, первая поставленная или хранимая дольше других закись? Не имеет ли это понятие отношение к физической позиции в области или на странице? Если не принимать во внимание фактор случайности, то на все эти вопросы возможен только один ответ — нет. Изложению концепции упорядоченности набора, в частности понятий первой и по- следней записей, и посвящается настоящая глава. Данная концепция является одним из аспектов представления набора в памяти. 6.2.1. Зачем упорядочивают наборы' / При использовании файлов на магнитной ленте естественно упоря- дочивать записи в соответствии с предполагаемой последовательно- стью их обработки. Необходимость такого упорядочения определяется физическими характеристиками доступа для данного типа устройств. Чтобы обратиться к определенной записи в файле на магнитной ленте необходимо пройти через все его предшествующие записи, а если нуж- но модифицировать запись, то приходится копировать весь файл Концепция упорядочения записей с ориентацией на последующее использование переносится из области обработки данных на магиит- * ных ленках в область устройств прямого доступа и СУБД. В системе IDS/1 предусмотрена возможность работы с сортированными цепочка- ми, и это ее бесспорно полезное свойство нашло отражение в предложе- ниях РГБД. Опытному администратору данных известно из практики, что отнюць не всегда выгодно иметь сортированные наборы, как это принято при использовании магнитной ленты. Поэтому допускаются и другие варианты упорядочения наборов, которые мы будем называть хронологическими, хотя комитеты KODACHJl не применяют этот тер- мин и воо бще не имеют специального термина для обозначения данного понятия. Однако если один из классов упорядочения наборов получил название, то естественно дать соответствующие названия и остальным. 60 ‘ ‘ - — ....
В настоящей книге мы введем термины — сортируемый и хронологи- чески Выбирая то или иное упорядочение, можно управлять важными временными характеристиками процесса выполнения программ. Обыч- но вопросы расхода памяти здесь значения не имеют, но, как мы уви- дим далее, их тоже иногда приходится учитывать. 6.2.2. Кто выбирает вид упорядочения? Если администратор данных решает, что некоторый тип набора дол- жен быть сортирован, то независимо от того, кто пишет программы об- новления базы данных (т. е. ее записей и наборов) и когда эти програм- мы выполняются, записи-члены в данном наборе будут располагаться в определенном порядке, как правило, отсортированные по некоторому номеру, имени или дате. У программиста в подобном случае нет воз- можности поместить запись в набор по своему усмотрению — порядок набора централизованно (по отношению к программистам, пишущим программы обновления базы данных) контролируется в соответствии с решением администратора данных. Все варианты сортировки наборов представляют собой решение ад- министратора данных о централизованном управлении упорядочен- ностью набора. Для хронологических наборов администратор данных может выбрать вариант, который оставляет решение о порядке набора программистам, или же вариант, при котором записи-члены упорядочи- ваются по принципу магазина (стека, т. е. «первой» считается последняя поставленная) либо по принципу очереди («первой» считается первая поставленная). КЯОД ввел еще один вариант — IMMATERIAL (НЕСУЩЕСТВЕННЫЙ), означающий, что порядок записей ни для кого не имеет значения. Однако, как будет показано далее, этот вари- ант вряд ли найдет применение на практике. 6.3. СОРТИРУЕМЫЕ НАБОРЫ (По-видимому, не так уж важно, будем ли мы говорить о «сорти- руемых наборах» или о «сортируемых типах набора», хотя во всех ос- тальных аспектах понятий набора и его типа подобное различие обяза- тельно должно учитываться.) С помощью ЯОД схемы администратор данных может определить некоторый тип набора как «сортируемый». Это означает, что все наборы данного типа поддерживаются в сортированном порядке в соответст- вии с критерием, единым для типа набора. Мы рассмотрим вначале од- ночленные типы, набора, так как в многочленных вопросы сортировки решаются значительно сложнее. 6.3.1. Сортируемый одночленный тип набора Чтобы определить сортировку в одночленном типе набора, необхо- димо выбрать в качестве ключа сортировки один или несколько эле- ментов в типе записи-члена. Смысл ключа сортировки здесь точно та- 61
кой же, как и в традиционной обработке дан- ных. В качестве примера приведем уже рас- смотренный в гл. 4 и 5 одночленный тип на- бора (рис. 6.1). Если специфицировать этот тип набора как сортируемый, то в качестве типичного ключа сортировки можно выбрать элемент ДАТА-ЗАВЕРШЕНИЯ записи ОБРАЗОВА- НИЕ: Зачем администратору данных может по- надобиться определять сортировку в одно- членном: типе набора? В нашем примере, очевидно, используются лишь небольшие наборы, поэтому последствия определения или не- определ^ния сортировки здесь будут в любом случае незначительны. Для больших наборов возможны две ситуации, при которых сорти- ровка дает существенные преимущества. Первая ситуация возникает при необходимости часто выдавать отчет, содержащий данные из записей-членов, упорядоченных опреде- ленным образом. Очевидно, что время сортировки данных отчета суще- ственно сокращается, если доступ к записям осуществляется в требуе- мой последовательности, (Заметьте, здесь не говорится: «если записи хранятся в требуемой последовательности» — это совсем другая проб- лема). Другая ситуация связана с частым поиском определенных запи- сей в одлом или нескольких наборах данного типа. Если критерий по- иска совпадаете ключом сортировки, то программа раньше заканчива- ет поиск, проверяя значение элемента или элементов ключа сортиров- ки. Программист в этом случае пользуется тем, что ему известен ключ сортировки, — довольно частое явление в традиционной обработке данных. Впро чем, у читателя не должно создаваться впечатление, что сор- тировка выгодна в любых ситуациях. Следуя приведенным выше рас- суждени ям, можно, казалось бы, всегда специфицировать и поддер- живать некоторый сортируемый порядок для наборов любого типа, чтобы программист мог им при случае воспользоваться. Вспомним, од- нако, что новая запись в момент постановки ее в базу данных, как пра- вило, должна быть включена в набор или в несколько наборов раз- личных типов. Как осуществляется такой процесс включения? Ре- зидентный модуль СУБД должен прежде всего найти точку включения в набор. Независимо от того, представлен ли тип набора цепочками или массивами указателей, при больших наборах указанная операция мо- жет потребовать доступа к сотням записей. Это явление устраняется при использовании программы «первоначальной загрузки» записей в пустую базу данных, но для последующих операций ее обновления оно остается. Прежде чем определять сортировку для некоторого типа набора, следует рассмотреть соотношение между временем поиска записи и вре- менем ее включения в данный набор. Часто наиболее приемлемым ока- зывается хронологический тип набора. Однако в программировании 62
обычно имеется возможность сократить время обработки за счет до- полнительного расхода памяти, и рассматриваемая ситуация не явля- ется в этом отношении исключением. Здесь можно применить индекси- рованные сортируемые наборы. 6.3.2. Индексированные типы набора Индексированными могут быть объявлены только сортируемые типы набора. Назначение индекса состоит в том, чтобы ускорить процесс нахождения точки включения записи в набор. Согласно спецификациям из этого не следует, что индекс можно использовать для поиска запи- сей. Однако, очевидно, что индексы одинаково эффективны в процес- сах постановки и поиска записей. Реализация подобных индексов, как отмечалось РГБД, потребует дополнительного расхода внешней памяти. Кроме того, администрато- ру данных может понадобиться разместить индекс в памяти более бы- строго доступа, чем для записей-членов индексируемого набора. По- этому было разрешено присваивать индексу имя. Это единственный слу- чай именования индексов во всем ЯОД схемы, и несколько странно, что именно для индексов сортируемых наборов сделано подобное ис- ключение. Почему бы тогда не допустить такую возможность для мас- сивов указателей и поисковых ключей? Если индексам не присвоены имена, то их размещение для каждого набора сортируемого типа набора определяется самой СУБД. Если же имя присвоено, то предполагается, что администратор данных с по- мощью ЯУВН разместит индекс в специальной области. 6.3.3. Многочленные сортируемые типы набора В одночленных сортируемых типах набора в типе записи-члена не- обходимо было выделить один или несколько элементов в качестве ключа сортировки. Сортировка многочленных типов набора связана с некоторыми трудностями. Существуют четыре различных варианта такой сортировки. Сортировка BY RECORD NAME (ПО ИМЕНИ ЗАПИСИ) В многочленном типе набора в качестве основного ключа сортиров- ки может использоваться имя записи. Подобная возможность не была предусмотрена РГБД, однако КЯОД, пересматривая несколько недо- работанные представления РГБД об упорядочении наборов, счел это целесообразным в варианте SORTED BY RECORD NAME. Администратор данных может в таком случае определить вторич- ные ключи сортировки для любых записей-членов. С целью иллюстра- ции изложенного рассмотрим уже знакомый нам многочленный тип набора, представленный на рис. 6.2. Если данный тип набора специфицирован как сортируемый по име- ни записи, то в каждом наборе записи ДОЛЖНОСТЬ будут пред- шествовать записям ОБРАЗОВАНИЕ, потому что буква «Д» лексико- графически сортируется раньше буквы «О». Рассмотрим, как это отра- ' - - — " 63
жается на последовательном досту- пе к набору. Пусть в некотором на- боре имеются записи обоих типов членов и программист уже нашел каким-то образом запись-владельца СЛУЖАЩИЙ. Если он теперь об- ратится к «следующей» или «пер- вой» в наборе, то он получит за- пись ДОЛЖНОСТЬ. Если же он обратится к «последней» или «пре- дыдущей», то он найдет запись ОБ- РАЗОВАНИЕ. Администратор данных может решить, что такое разделение запи- < 'й ДОЛЖНОСТЬ и ОБРАЗОВАНИЕ недостаточно. Тогда он имеет < заво оп ределить дополнительный ключ сортировки для типа записи ДОЛЖН ОСТЬ (или для типа записи ОБРАЗОВАНИЕ, или для обоих СЛУЖАЩИЙ СОД БРАЗОВАНИЕ должность Рис. 6.2. ^Многочленный тип набора Рис. 6.3. .Многочленный тип набора, сортируемый «по име- ни записи» жпов). Если он выберет в качестве возрастающего ключа сортиоовки ишсей ДОЛЖНОСТЬ элемент ДАТА-НАЗНАЧЕНИЯ, то записи ОБРАЗОВАНИЕ будут следовать в некотором случайном порядке, а запись ДОЛЖНОСТЬ — в порядке возрастания даты назначения слу- жащего на должность. Эта ситуация представлена на рис. 6.3 (здесь не используются стрелки-указатели, чтобы подчеркнуть, что они не ьмеют отношения к упорядочению набора). При рассмотрении примера у читателя, естественно, возникает во- прос: можно ли обратиться от записи-владельца к первой записи ОБ- РАЗОВАНИЕ, не просматривая предварительно все записи ДОЛЖ- НОСТЬ? Другими словами, если администратор данных предполагает, что такая необходимость действительно появится, каким образом он может ускорить этот процесс? В подобных случаях лучше всего опре- делить два отдельных типа набора. В многочленном типе набора нет специальных средств облегчения указанного доступа. 64
Сортировка BY DEFINED KEYS (ПО ОПРЕДЕЛЕННЫМ КЛЮЧАМ) В многочленном типе набора администратор данных может выбрать один или несколько элементов, одинаковых в каждом типе записи-чле- на. Словом «одинаковые» в данном случае подчеркивается, что значе- ния элементов ключа сортировки некоторого типа записи-члена сравни- мы, в смысле определения их старшинства, со значениями элементов ключей сортировки других типов записи-члена. Возвращаясь к примеру на рис. 6.2, в качестве таких элементов можно выбрать ДАТА-ЗАВ ЕРШЕ НИЯ в типе записи ОБРАЗОВАНИЕ и ДАТА-НАЗНАЧЕНИЯ в типе записи ДОЛЖНОСТЬ. Если эти даты специфицировать как ключи сортировки, то представленный на рис. 6.3. набор, сортируемый по имени записи, будет теперь упорядочен так, как показано на рис. 6.4. Спецификации КЯОД не содержат подробных сведений о ключах сортировки в различных типах записи, в частности об их длине. По всей видимости, эти детали будут уточняться в конкретных системах, реали- зующих данную возможность. Очевидно, однако, что имена ключей сор- тировки могут быть различными. При сортировке «по определенным ключам» администратор данных может определить отношение к дубликатам значений ключа сортиров- ки. Так, он вправе: запретить дубликаты; при этом система будет отказываться разме- щать и включать в набор запись, у которой значения ключа сортиров- ки совпадают с соответствующими значениями уже имеющихся в набо- ре записей; разрешить записи с дубликатами ключа сортировки и определить, в какую позицию включается запись с ключом-дубликатом относитель- но уже имеющихся записей с тем же ключом, — перед этими записями или после них; разрешить записи с дубликатами ключа сортировки, но не указы 3 Зак. 145 65
гать, как они включаются относительно уже имеющихся подобных записей- В последнем случае администратор данных имеет возможность за- дать некоторое «управление дубликатами» в подстатье члена при опре- делении ключей сортировки. Сортировка BY DATA-BASE-KEY (ПО КЛЮЧУ БАЗЫ ДАННЫХ) Это — один из двух вариантов сортируемых типов набора, преду- смотренных еще РГБД. (Оба они имеют существенно меньшее значение, чем рассмотренные выше варианты КЯОД). Если для некоторого типа набора определена сортировка по клю- чу базы данных (указывается SORTED BY DATA-BASE-KEY, а у РГБД — BY DATABASE-KEY), то записи-члены упорядочиваются в наборе в соответствии со значением своего ключа базы данных (см. параграф* 4.2). Рассматриваемый вариант предназначен для админист- ратора данных или программиста, работающего на физическом уровне. Чтобы эффективно выполнять упорядочение, и mom и другой должны знать, как сортируются значения ключа базы данных. В соединении со способом размещения VIA SET для записей-членов данный вариант позволяете минимизировать число обращений к диску в тех случаях, когда программа последовательно обрабатывает все записи набора. Многочленность типа набора может оказать влияние на этот про- цесс в зависимости от способа выделения ключа базы данных при раз- мещении записи. Возможно, записи различных типов будут разделены в каждом наборе (как при сортировке по имени записи) или перемеша- ны (как при сортировке по определенным ключам). Соршровка WITHIN RECORD-NAME (В ПРЕДЕЛАХ ИМЕНИ-ЗАПИСИ) Этот вариант сортируемого типа набора также предусмотрен РГБД. Он специально рассматривается последним, так как является несколь- ко необычным и требует предварительного ознакомления с предыду- щими способами упорядочения. (Заметим, что данный вариант отсут- ствует в IDS/1 и в октябрьском отчете РГБД 1969 г.). Идея его заключается в том, чтобы каждый тип записи-члена мог иметь свои собственные ключи сортировки. При этом они не будут вторичными по отношению к имени записи, как при сортировке «по имени-записи», и не должны соответствовать друг другу для воз- можности сравнения, как при сортировке «по определенным ключам». В результате применения указанного варианта записи различных ти- пов могут оказаться перемешанными в наборе. Если для ^некоторого типа записи-члена не задан ключ сортировки, то используется уни- версальный вторичный ключ, а именно значение ключа базы данных. Таким образом, если администратор данных выбирает этот способ упорядочения, но ни для одного типа записи-члена не определяет ориентированных на приложение ключей сортировки, то в итоге мы получим то же, что и при сортировке «по ключу базы данных». Формулировки общего правила для рассматриваемого варианта в предложениях РГБД и КЯОД почти совпадают. Чтобы пояснить все 66
вышеизложенное, воспроизведем это правило из отчета КЯОД: «Не- обязательная фраза WITHIN RECORD-NAME обеспечивает сорти- ровку залисей безотносительно к упорядоченности других типов запи- си в наборе. Это означает не то, что подразумевается сортировка по ти- пу записи в качестве старшего ключа, а лишь только то, что если рас- сматривать некоторый тип записи независимо от остальных членов, то он упорядочен в соответствии со своим собственным ключом управле-* ния сортировкой. Ключи управления сортировкой задаются предло- жением KEY для каждого из типов записей-членов. Если для какого- либо типа записи-члена предложение KEY не задано, то в качестве ключевых элементов упорядочения по возрастанию берутся ключи ба- зы данных экземпляров определяемого типа записи». Читатели, знакомые с терминологией РГБД, могут заметить, что известное им предложение ASCEND ING/DESCENDING теперь более точно называется предложением KEY. В разд. 6.3.2 обсуждались индексированные одночленные типы набо- ра. Однако возможность определения и именования индексов распро- страняется на любые сортируемые типы набора с любым числом типов записей-членов. Индекс является свойством типа набора, а не какого- либо отдельного типа записи-члена. 6.4. ХРОНОЛОГИЧЕСКИЕ ТИПЫ НАБОРА Как уже указывалось (см. разд. 6.2.2), хронологический набор мож- но специфицировать таким образом, что место включения новых записей определяется администратором данных, или это решение оставляется программисту. Мы начнем изложение с более простого первого случая. 6.4.1. Магазины и очереди По аналогии с изучением сортируемых типов набора рассмотрим сначала одночленный тип набора, а затем выясним, какие осложнения возможны (если они возникают) при переходе к многочленным. Существуют два варианта контролируемых администратором дан- ных хронологических типов набора, и в каждом из них любая новая запись включается «рядом» с записью-владельцем. По синтаксису КЯОД один вариант объявляется фразой INSERTION IS FIRST (ВКЛЮЧЕНИЕ ПЕРВОЙ), а другой — фразой INSERTION IS LAST (ВКЛЮЧЕНИЕ ПОСЛЕДНЕЙ), где «первая» и «последняя» понима- ются как в переборе записей по указателю следующей в цепочке. Это не означает, что хронологический тип набора обязательно связан с це- почным представлением, просто в данном случае оно более удобно для обсуждения. Концепцию хро- нологических типов набора мы проиллюстрируем на примере типа набора, показанного на рис. 6.5. Пусть имеется система непосред- ственного ввода данных, и в тече- ние дня обслуживающий персонал может вводить в базу данных зака- 67 ПРЕДМЕТ | ПЗ ЗАКАЗ-ПОКУПКА Рис. 6.5. Тип набора с одним членом
зы на покупку (представленные экземплярами типа записи ЗАКАЗ- ПОКУПКА). Каждая запись ЗАКАЗ-ПОКУПКА автоматически под- соединяется к записи заказанного ПРЕДМЕТа. Предположим далее, что тип набора ПЗ упорядочивается хронологически. Тогда в течение первой половины дня могут возникнуть последовательно пять ситуа- ций (см. рис. 6.6). Цепочное представление с указателем следующей за- писи выбрано только для примера. В типе записи-члена представлены два элемента: ИМЯ-КЛИЕНТА и ЗАКАЗАННОЕ-КОЛИЧЕСТВО. t---O(neT за ка зо д) /(первый заказ) t-2(2 заказа) , i Рис. 6.6. Экземпляры хронологического типа набора в различ- \\ ные моменты времени при «включении первой» В момент времени t = 4 уже очевидно, что набор упорядочивается не так, как если бы он был сортируем (по обоим показанным элементам или по любому из них). Варна нт «включение первой» фактически определяет магазин (стек), так как если обработка заказов начнется от записи ПРЕДМЕТ по ука- зателю следующей записи, то первым будет обработан заказ, который был поставлен последним (т. е. последний принятый). Такая практика, конечно, несправедлива по отношению к клиентам. Однако преимуще- ство магазинной организации состоит в том, что позиция включения каждой новой записи находится очень быстро и, следовательно, мини- мизируется время ввода данных о новом заказе на покупку. Если администратору данных нужно обеспечить очередность в об- служивании клиентов за счет небольшого увеличения времени вклю- чения записей ЗАКАЗ-ПОКУПКА, то он может установить порядок набора «включение последней». При этом в момент времени t =® 4 68
(см. рис. 6.6) сложится ситуация, показанная на рис. 6.7. Стрелка меж- ду последней записью набора (в данном случае последней поставлен- ной) и его владельцем указывает место включения следующей (по вре- мени) записи. Заметим, что комбинация «цепочкой с указателем следующей запи- си» и «включение последней» является хотя и вполне допустимой, но не обязательно оптимальной. Здесь все определяется степенью совместности физического раз- мещения записей. При большом числе небольших наборов такая ком- бинация вполне эффективна,особенно если для записей-членов задан способ размещения VIA SET. Если же наборы большие и для записей-членов определен какой-либо другой способ раз- мещения, то включение новой записи ЗАКАЗ-ПОКУПКА может существенно замедлиться, так как для нахождения точки включения потребуется пройти по длинной цепочке указателей до послед- ней записи. Вариант «включение последней» фак- тически определяет очередь (первый вошедший обслуживается первым) обра- ботки заказов, поступающих от кли- ентов. Рис. 6.7. Экземпляр хронологи- ческого типа набора при «вклю- чении последней» Мы уже можем проследить взаимосвязь между различными спосо- бами размещения, представления и упорядочения наборов. Сущест- вует множество примеров этой взаимосвязи, и опытному администра- тору данных известно, какие комбинации являются «надежными», а каких следует по возможности избегать. Выше отмечалось, что при вариантах «включение первой» и «вклю- чение последней» порядок набора устанавливается администратором данных, как и при сортируемых типах набора. Впрочем, у программис- та еще остается одна возможность управления упорядоченностью: при пакетной обработке загружать новые записи в соответствующей последовательности. Однако в системах непосредственного ввода, по- добных рассмотренной выше системе обработки заказов, программист должен знать вариант упорядочения набора, но не может повлиять на порядок записей в отдельных наборах. 6.4.2. Включение «следующей» и «предыдущей» В том случае, если администратору данных желательно определить хронологический тип набора, в котором записи-члены упорядочивают- ся некоторым образом, не соответствующим ни одному из способов сортировки, он должен предоставить программисту возможность про- цедурного упорядочения набора. Для этой цели имеется еще два варианта хронологического типа набора: INSERTION NEXT (ВКЛЮЧЕНИЕ СЛЕДУЮЩЕЙ) и INSERTION PRIOR (ВКЛЮЧЕНИЕ ПРЕДЫДУЩЕЙ). Однако 69
прежде, чем перейти к их обсуждению, необходимо пояснить одно из основных понятий процесса выполнения программы—индикатор теку- щего состояния. Существует несколько таких индикаторов, которыми должен уметь пользоваться программист. Все они будут подробно рас- смотрены позднее. Здесь же нам потребуется только индикатор теку- щей записи в типе набора. В любой момент выполнения программы индикатор текущей запи- си в типе набора содержит значение ключа базы данных, указываю- щее какую-либо запись (владельца или члена) в некотором наборе, тип которого соответствует этому индикатору. В программе поддержива- ется по одному такому индикатору для каждого типа набора ее под- схемы. * В рассматриваемых здесь вариантах упоря- дочения при помещении новой записи в базу данных или включении какой-либо записи в на- бор (которое может вы- полняться и не одновре- менно с размещением) Рис. 6.8. Экземпляр хронологического типа набора в некоторый момент времени при включении «сле- дующей» и «предыдущей» ее позиция в последнем определяется значением индикатора. При варианте «включение следующей» запись помещается за текущей за- писью набора, т. е. в направлении указателя следующей записи, а при варианте «включение предыдущей» — в направлении указателя преды- дущей записи, если таковой имеется. Порядок набора мы будем опять рассматривать в терминах цепочного представления, не забывая о су- ществовании массивов указателей. Заметим, что в случае применения массивов указателей соответст- вующий массив должен быть каким-то образом «раздвинут» для поме- щения в него ключа базы данных новой записи. Оба рассматриваемых варианта хронологического упорядочения набора иллюстрируются рис. 6.8 (на примере типа набора, показанно- го на рис. 6.5). Здесь цепочное представление с указателем следующей записи используется только для определения направления «следующе- го» в цепочке. (В настоящей книге это направление изображается про- тив часовой стрелки.) Индикатор текущей в наборе ПЗ указывает за- пись ЗАКАЗ-ПОКУПКА, соответствующую заказу Брауна на шесть предметов «стакан». Если определен порядок «включение следующей», то заказ Уайта на 18стаканов будет помещен между записями Брауна и Смита, а если порядок набора «включение предыдущей», то между записями Джона и Брауна. Несмотря на то что комбинация цепочного представления с указа- телем следующей записи и варианта упорядочения «включение преды- дущей» является допустимой, ее практическое применение не эф- 70
фективно. Однако, с точки зрения разработчика системы, такую ком- бинацию, как правило, легче разрешить, чем запретить. Таким образом, выбирая варианты упорядочения «включение следу- ющей» и «включение предыдущей», администратор данных оставляет по- рядок набора на усмотрение программиста, хотя указание «следующей» или «предыдущей» и связано с некоторыми ограничениями. Впрочем, установка индикатора текущей в типе набора находится в ведении про- граммы, так что практически результирующий порядок набора пол- ностью зависит от решений программиста. 6.4.3. Многочленные хронологические типы набора Для хронологических типов набора переход от одного типа записи члена к нескольким типам членов не вызывает таких осложнений, как для сортируемых. Разница сказывается в основном лишь при обра- ботке наборов. В любом варианте хронологического упорядочения за- писи в наборе, скорее всего, будут следовать вперемешку по отноше- нию к их типам, так что программисту придется распознавать и отби- рать необходимые ему записи. Правда, в его распоряжении имеется вариант оператора доступа, позволяющий указывать имя типа требуе- мой записи. В этом случае при поиске будут игнорироваться записи всех остальных типов. Тем не менее мы рекомендуем не пользоваться многочленными хронологическими типами набора. 6.5. НЕОПРЕДЕЛЕННЫЙ ПОРЯДОК НАБОРА В процессе уточнения представлений РГБД об упорядочении набо- ров КЯОД ввел еще один дополнительный вариант, который не является ни сортируемым, ни хронологическим. Он называется IMMATERIAL (НЕСУЩЕСТВЕННЫЙ, НЕОПРЕДЕЛЕННЫЙ) и означает, что для администратора данных порядок записей в наборе безразличен, но программисту не предоставляется возможность управлять им. Соот- ветствующим правилом КЯОД (с. 3.77) определяется, «... что записи- члены экземпляров данного типа набора упорядочиваются наиболее удобным для СУБД способом». А так как разработчик вряд ли предложит какой-либо новый способ упорядочения, отличный от уже рассмотренных, данный вариант, ско- рее всего, будет соответствовать «включению первой» для цепочек и «включению последней» для массивов указателей, хотя здесь можно учитывать еще одно, пока не рассмотренное понятие — критерий выбора (селекции) набора. 6.6. ПОСТОЯННОЕ И ВРЕМЕННОЕ УПОРЯДОЧЕНИЕ НАБОРОВ Представленное здесь свойство хотя и редко реализуется, но в оп- ределенной степени является полезным, а потому должно быть изу- чено. Оно связано с применением оператора ЯМД, позволяющего про- граммисту изменить порядок следования записей в наборе во время выполнения программы. Подчеркнем, что при этом не меняется ос- новное упорядочение набора, иначе указанное свойство могло бы слу- жить одним из средств реструктуризации. Такая возможность введена РГБД только для хронологических типов набора, чтобы позволить пограммисту постоянно или временно 71
упорядочивать их отдельные экземпляры. При временном упорядо- чении действительный порядок записей-членов в базе данных не изме- няется, а программист во время выполнения своей программы имеет дело с так называемым локальным набором (в отчете РГБД этот тер- мин не употребляется). После завершения выполнения программы временный локальный порядок исчезает. В случае постоянного упо- рядочения программист может изменить фактический порядок следо- вания записей в базе данных, если это допускается администратором данных. Переходя к более совершенной терминологии КЯОД, для каждого хронологического типа набора необходимо определить порядок как постоянный или временный. Если порядок постоянный, то програм- мист не может его изменить, временный же предоставляет ему такую возможность. Данное определение относится также и к неопределен- ному порядку набора. Рассмотренное свойство не находит широкого применения, так как в конкретных системах редко реализуется ЯМД-оператор ORDER (УПОРЯДОЧИТЬ). Поэтому все хронологические типы набора счи- таются упорядоченными постоянно. 6.7. СИНТАКСИС УПОРЯДОЧЕНИЯ НАБОРА Выше мы полностью изложили подход КЯОД к упорядочению набо- ров. Следует напомнить, что предложения РГБД в данной области считаются недоработанными. Поэтому здесь будет приведен только син- таксис КЯОД. В контексте статьи набора он имеет следующий вид (с.3.63): SET NAME IS имя-набора-h OWNER IS (имя-записи-1Т . I SYSTEM J [;SET IS ; ORDER (FIRST PRIOR PROCESSABLE] PERMANENT TEMPORARY INSERTION IS UST NEXT PRIOR IMM/TERIAfe SORTED INDEX NAME IS имя-индекса-1 (BY рАтд-BASE-KEY BY RECORD NAME WITHIN record-name BY DEFINED KEYS [DUPLICATES ARE FIRST" LAST ALLOWED] NOT 72
Если набор определяется как сортируемый, администратор дан- ных может также специфицировать ключи сортировки в подстатье чле- на. Соответствующий синтаксис КЯОД (с. 3.64): , MEMBER IS имя-записи-l { } { } (LINKED ТО OWNER} ; ( ASCENDING ) ' в1 is ид-данных-3 ' Г ASCENDING ’ ’ I DESCENDING ид-данных-4 DUPLICATES ARE "FIRST LAST NOT NULL IS [NOT] ALLOWED] ALLOWED Это то самое предложение, которое было названо РГБД АЗСЕЫ- DING/DESCENDING (ВОЗРАСТАЮЩИЙ/УБЫВАЮЩИЙ), а впос- ледствии заменено КЯОД на KEY (КЛЮЧ). Предложение KEY должно применяться при варианте BY DEFI- NED KEYS и может, использоваться при WITHIN RECORD-NAME и BY RECORD-NAME. С остальными вариантами упорядочения набо- ра оно не употребляется. 6.8. ПРИМЕРЫ УПОРЯДОЧЕНИЯ НАБОРОВ В настоящей главе не было возможности привести примеры всех случаев упорядочения наборов. Поэтому при рассмотрении описаний мы будем по мере необходимости ссылаться на примеры, разобранные выше (для упрощения пунк- туация здесь опущена). , Пример 1 (см. рис. 6.1) . SET NAME IS СО . OWNER IS СЛУЖАЩИЙ ORDER IS PERMANENT INSERTION IS SORTED BY DEFINED KEYS MEMBER IS ОБРАЗОВАНИЕ KEY IS ASCENDING ДАТА-ЗАВЕРШЕНИЯ - DUPLICATES LAST NULL NOT ALLOWED Заметим, что данный пример хорошо иллюстрирует потенциальную проб- лему двух разных предложений определения дубликатов. Поскольку здесь толь- ко одна запись-член, управление дубликатами может быть специфицировано как в подстатье набора, так и в подстатье члена, в частности в обеих подстатьях одновременно. В последнем случае эти определения не должны быть противоре- чивыми. П р и м е р 2 (см. рис. 6.2 и 6.3) SET NAME IS СОД OWNER IS СЛУЖАЩИЙ ORDER IS PERMANENT INSERTION IS SORTED BY RECORD-NAME MEMBER IS ОБРАЗОВАНИЕ MEMBER IS ДОЛЖНОСТЬ KEY IS ASCENDING ДАТА-НАЗНАЧЕНИЯ DUPLICATES NOT ALLOWED NULL NOT ALLOWED 1 73
В соответствии с текстом разд. 6.3.3. в данном примере не определяется ключ сортировки для записей ОБРАЗОВАНИЕ. Указание о запрещении дублика- тов не позволяет служащему в один и тот же день занять две новые должности. Примерз (см. рис. 6.1 и 6.4). SET NAME IS СОД OWNER IS СЛУЖАЩИЙ ORDER IS PERMANENT INSERTION IS SORTED BY DEFINED KEYS DUPLICATES ARE LAST MEMBER IS ОБРАЗОВАНИЕ KEY IS ASCENDING ДАТА-ЗАВЕРШЕНИЯ MEMBER IS ДОЛЖНОСТЬ KEY IS ASCENDING ДАТА-НАЗНАЧЕНИЯ Сравнение примеров 3 и 1 показывает, что проще включить управление дуб- ликатами в подстатью набора, чем указывать его в каждой подстатье члена. Од- нако фраза DUPLICATES в последней дает возможность запретить нулевые зна- чения, в то время как аналогичная фраза в подстатье набора этого не предусмат- ривает. Как правило, нулевые значения являются допустимыми, поэтому при отсутствии запрещающего указания предполагается, что они разрешены. Пример 4 (см. рис. 6.2 и разд. 6.3.3) SET NAME IS СОД OWNER IS СЛУЖАЩИЙ ORDER IS PERMANENT INSERTION IS SORTED BY DATA-BASE-KEY MEMBER IS ОБРАЗОВАНИЕ MEMBER IS ДОЛЖНОСТЬ Пример 5 (см. рис. 6.2 и разд. 6.3.3) SET NAME IS СОД OWNER IS СЛУЖАЩИЙ ORDER IS PERMANENT INSERTION IS SORTED WITHIN RECORD-NAME MEMBER IS ОБРАЗОВАНИЕ KEY IS ASCENDING ДАТА-ЗАВЕРШЕНИЯ DUPLICATES ARE LAST NULLS NOT ALLOWED MEMBER IS ДОЛЖНОСТЬ KEY IS ASCENDING ДАТА-НАЗНАЧЕНИЯ DUPLICATES ARE LAST NULLS NOT ALLOWED Этот пример можно сравнить с примером 3. Заметим также, что если опустить в примере 5 оба предложения KEY, то он станет эквивалентным примеру 4. Пример 6 (см. рис. 6.5. и 6.6) SET NAME IS ПЗ OWNER IS ПРЕДМЕТ ORDER IS PERMANENT INSERTION IS FIRST MEMBER IS ЗАКАЗ-ПОКУПКА Пример? (см. рис. 6.5 и 6.7) SET NAME IS ПЗ OWNER IS ПРЕДМЕТ ORDER IS PERMANENT INSERTION IS LAST MEMBER IS ЗАКАЗ-ПОКУПКА Пример8 (см. рис. 6.5 и 6.8). SET NAME IS ПЗ OWNER IS ПРЕДМЕТ ORDER IS PERMANENT INSERTION IS NEXT MEMBER IS ЗАКАЗ-ПОКУПКА Пример 9 (см. рис. 6.5 и 6.8) SET NAME IS ПЗ OWNER IS ПРЕДМЕТ SET IS PRIOR PROCESSABLE ORDER IS PERMANENT INSERTION IS PRIOR MEMBER IS ЗАКАЗ-ПОКУПКА 74
В данном примере добавлено предложение PRIOR PROCESSABLE с целью обеспечить соответствие фразе INSERTION IS PRIOR. Пример 10 (см. рис. 6.2 и параграф 6.5) SET NAME IS СОД OWNER IS СЛУЖАЩИЙ ORDER IS PERMANENT INSERTION IS IMMATERIAL MEMBER IS ОБРАЗОВАНИЕ MEMBER IS ДОЛЖНОСТЬ Здесь мы специально возвращаемся к многочленному типу набора, который использовался для примеров сортируемых типов набора. -- - 6.9. ВЫБОР ВАРИАНТА УПОРЯДОЧЕНИЯ НАБОРА Будущий администратор данных может быть несколько озадачен таким изобилием вариантов упорядочения наборов. Который же из них выбрать и в каких случаях его использовать? Среди девяти воз- можных вариантов можно назвать два или три наиболее употребитель- ных, а остальные встречаются довольно редко. Прежде чем перейти к классификации вариантов, сделаем замечание об относительно новой возможности INSERTION IS IMMATERIAL, которая, как известно, еще нигде не реализована, хотя и не должна представлять трудности для разработчика. Если при реализации этой возможности фраза о «наиболее удобном для СУБД способе» из пра- вила КЯОД интерпретируется как наиболее быстрое включение в на- бор (без учета предполагаемого использования набора), то данный ва- риант является вполне приемлемым. Если же выбран подход «не имеет значения», то осторожный администратор данных этим вариантом не воспользуется. Наиболее употребительными считаются следующие варианты (в порядке частоты их применения): FIRST BY RECORD-NAME LAST Заметим, что для одночленного типа набопа BY DEFINED KEYS эквивалентно BY RECORD-NAME. Реже используются варианты (в порядке приоритета использова- ния): IMMATERIAL BY DATA-BASE-KEY (см. разд. 6.3.3) NEXT BY DEFINED-KEYS (для многочленного типа набора) WITHIN RECORD-NAME PRIOR Подчеркнем, что приведенное выше упорядочение вариантов яв- ляется чисто интуитивным и не основано ни на каких эксперименталь- ных исследованиях. Относительная частота их использования в отдель- ных системах и приложениях может быть различной. 75
•ЛО. ПОИСКОВЫЕ КЛЮЧИ Мы решили обсудить поисковые ключи в одной главе с упорядоче- нием наборов, в частности, для того, чтобы обратить внимание читателя на взаимосвязь концепций поискового ключа и индекса. В разд. 6.3.2. указывалось, что администратор данных может определить сортируе- мый тип набора как индексированный с целью ускорения процесса включения записи в экземпляр этого набора. Подразумевается, что для каждого экземпляра набора создается и поддерживается (в по- следовательности, соответствующей порядку членов набора) один ин- декс, причем его ключ по определению совпадает с ключами сортиров- ки. Итак, назначение индекса — ускорить процесс помещения записи в базу данных. Напомним, что в отличие от индекса массив указателей предназна- чен лишь для представления принадлежности записей экземпляру набора. Порядок записей-членов при этом определяется порядком ука- зателей в массиве. Последний не является специфическим средством сортируемых наборов, так как с его помощью вполне эффективно пред- ставляются и хронологические (или «неопределенные») типы набора. С другой стороны, возможность индексирования гораздо легче реали- зуется в системе, где уже имеются массивы указателей. Для этого нуж- но, каким-то образом добавить к элементам массива значения ключа сор- тировки. Тем не менее хотя спецификации РГБД не запрещают комби- нации индексированных сортируемых наборов с цепочным представ- лением, но вряд ли такая комбинация будет иметь практическое зна- чение. В то время как индекс должен ускорить процесс помещения записи (ту часть этого процесса, которая касается ее включения в набор), назначение поискового ключа — ускорить процесс поиска записи в наборе. Поисковый ключ не связан с ключом сортировки или вообще с сортировкой набора, как это имеет место для индекса. По аналогии с сортировкой предполагается, что имеется столько же индексов поиско- вых ключей, сколько и соответствующих наборов. Однако реализация данной возможности оправдана лишь для больших наборов. Поиско- вый ключ в небольшом наборе почти ничего не дает пользователю. Чтобы полностью уяснить роль поискового ключа, мы должны об- ратиться к ЯМД-оператору FIND (НАЙТИ), который используется в программе для поиска записей в базе данных. Существует несколько вариантов этого оператора. Один из них осуществляет поиск в наборе записи, содержащей в каком-либо (или нескольких) элементе ука- занные программистом значения. Если такой элемент (или элементы) соответствует поисковому ключу, то последний используется для ус- корения поиска. (Случай, когда эти элементы не соответствуют поис- ковому ключу, будет рассматриваться в соответствующей главе.)' Здесь опять мы сталкиваемся с ситуацией, в которой ускорение про- цесса поиска связано с дополнительным расходом памяти. Заметим так- же, что при помещении или удалении записей из набора необходимо вносить изменения в индекс поискового ключа. Если в сортируемом наборе элементы данного ключа совпадают с элементами ключа сорти- 76
ровки, то теоретически он может одновременно использоваться и для ускорения постановки записей. Таким образом, становится очевид- ным, что индекс сортируемого набора можно рассматривать как част- ный случай поискового ключа, хотя первый предназначен для вклю- чения записей, а второй — для их поиска! К сожалению, это утверждение справедливо лишь с существенными оговорками. Поисковый ключ является свойством типа записи-члена в некотором типе набора. Как мы увидим далее, синтаксические пра- вила не позволяют определять поисковый ключ как свойство типа на- бора даже в том случае, когда его элементы могут быть найдены в каж- дом типе записи-члена и удовлетворяют всем требованиям сравнимо- сти. С одночленным типом набора проблем не возникает, но в много- членном типе набора можно специфицировать один или несколько по- исковых ключей для одного типа записи-члена и не специфицировать их для других членов. Фактически поисковый ключ точно соответ- ствует индексу только одночленного сортируемого типа набора, за ис- ключением варианта сортировки «по ключу базы данных». 6.10.1. Синтаксис Синтаксис определения поискового ключа является частью синтак- сиса подстатьи члена, приведенного в параграфе 6.7. Хотя КЯОД не- сколько изменил синтаксис РГБД, это изменение выходит за рамки настоящего изложения. В контексте статьи члена этот синтаксис имеет следующий вид (с. 3.64 отчета КЯОД): MEMBER IS имя-записи-l { } { } [LINKED ТО OWNER] Г, SEARCH KEY IS ид-данных-5 [, ид-данных-6] ... I CALC } USING { ----------------------------- \ —----- [INDEX [NAME IS имя-индекса-l] j DUPLICATES ARE [NOT] ALLOWED] ... Мы видим, что запись-член может не иметь поисковых ключей либо иметь их один или несколько. Любой поисковый ключ состоит из одного или нескольких элементов (каждый из которых, разумеется, должен быть определен как часть данной записи-члена). Администратор данных имеет возможность выбрать представление поискового ключа. Если он выбирает вариант USING CALC, то в со- ответствии с правилами КЯОД (с. 3. 84) «для доступа к искомой записи используется стандартный (для конкретной СУБД) алгоритм преоб- разования ключа». Если же он отдает предпочтение варианту USING INDEX, то «для доступа к искомой записи используется стандартный механизм индексации СУБД. Фраза NAME (ИМЯ) призвана упро- стить ссылки на конкретные индексы в языке управления размеще- нием на внешних носителях». (Слово «упростить» здесь выбрано не- удачно, так как без фразы NAME указанные ссылки были бы невоз- можны.) 77
Следует отметить, что ни «стандартный алгоритм преобразования ключа», ни какой-либо иной не позволяют рандомизировать значение поискового ключа непосредственно в позицию записи, которая уже бы- ла размещена в базе данных в соответствии с некоторым критерием (т. е. по способу размещения, возможно, и CALC, но наверняка по другим элементам типа записи). Для поискового ключа можно указать CALC, но тогда придется просматривать ряд таблиц (или индексов). Одно из промежуточных решений (между CALC и INDEX) состоит в преобразовании значения поискового ключа в значение ключа базы данных «псевдозаписи», содержащей уже ключ (ключи) базы данных записи или записей с искомым значением поискового ключа. Естест- венно, имеется и другой, более «индексный» подход, а именно про- смотр соответствующим образом организованных таблиц, 6Л0.2. Примеры поисковых ключей В завершение главы приведем два примера определения поисковых ключей. Приме р 1 (см. рис. 6.5), SET NAME IS ПЗ OWNER IS ПРЕДМЕТ ORDER IS PERMANENT INSERTION IS FIRST MEMBER IS ЗАКАЗ-ПОКУПКА SEARCH KEY IS ТОРГОВЫЙ-ОТДЕЛ USING INDEX DUPLICATES ARE ALLOWED Элемент поискового ключа ТОРГОВЫЙ-ОТДЕЛ должен быть, очевидно, определен в типе записи ЗАКАЗ-ПОКУПКА. Заметим, что для обеспечения группировки заказов по торговым отделам можно воспользоваться другим ти- пом набора (рис. 6.9). Рис. 6.9. Пример структуры, позволяющей избе- жать использования поискового ключа В качестве упражнения читателю предлагается самому исследовать потен- циальные преимущества и недостатки каждого из этих двух подходов. Пример 2 (см. рис. 6.9) SET name: IS ПЗ PRIOR processable OWNER IS ПРЕДМЕТ ORDER IS PERMANENT INSERTION IS SORTED INDEXED BY DEFINED KEYS MEMBER IS ЗАКАЗ-ПОКУПКА KEY IS ASCENDING ЗАКАЗАННОЕ-КОЛИЧЕСТВО DUPLICATES FIRST NULL NOT ALLOWED . SEARCH К EY IS ЗАКАЗАННОЕ-КОЛИЧЕСТО USING INDEX DUPLICATES ALLOWED SET NAME IS T3 OWNER IS ТОРГОВЫЙ-ОТДЕЛ ORDER IS PERMANENT INSERTION IS FIRST MEMBER IS ЗАКАЗ-ПОКУПКА 78
Данный пример иллюстрирует несколько рассмотренных ранее вариантов. Во-первых, тип записи ЗАКАЗ-ПОКУПКА является членом сортируемого типа набора ПЗ и в то же время членом хронологического типа набора ТЗ. Поисковый ключ записи ЗАКАЗ-ПОКУПКА определен в наборе ПЗ, но не определен в наборе ТЗ. Здесь обращает на себя внимание некоторая непоследовательность подхода РГБД в отношении индексов и поисковых ключей, которая не была устранена в предложениях КЯОД. В типе набора ПЗ элемент ЗАКАЗАННОЕ-КОЛИЧЕ- СТВО представляет одновременно ключи сортировки и поисковый и, кроме того, данный тип набора является индексированным. Очевидно, мы должны допустить дубликаты значений элемента ЗА КАЗАННОЕ-КОЛИЧЕСТВО для любой запи- си ПРЕДМЕТ. В определении упорядочения набора (и, следовательно, в обеспе- чивающем этот порядок индексе) можно указать, как нужно включать в набор новые записи относительно уже имеющихся с тем же значением ключа. Для по- искового ключа мы только констатируем, допускаются или не допускаются дуб- ликаты его значения. Как в этом случае поступит система? 6.10.3. Предложения по расширению концепции поискового ключа Следовало бы полностью исключить концепцию индексированных сортируемых наборов и заменить ее следующим правилом для поиско- вых ключей: если элементы данных, указанные в определении поиско- вого ключа, в точности соответствуют аргументам ключа сортировки в типе набора, сортируемом «по имени записи», то при включении новой записи в данный набор должен использоваться указанный поисковый ключ. Признано полезным еще одно расширение концепции поискового ключа, а именно спецификация некоторых поисковых ключей как гло- бального свойства определяемого типа записи9. Это средство предла- гается как дополнительное по отношению к уже имеющимся внутрина- борным средствам. В настоящее время, если возникает необходимость в глобальном вторичном индексе для некоторого типа записи, послед- ний приходится определять как член некоторого сингулярного типа набора. В этом типе набора владельцем является сама система, а по- скольку она единственная, имеет место только один экземпляр такого набора. В результате база данных оказывается перегруженной «внеш- ними» типами набора и поисковыми ключами. ГЛАВ А 7 СПОСОБ ВКЛЮЧЕНИЯ И ДОПУСТИМОСТЬ ИСКЛЮЧЕНИЯ 7.1. ВВЕДЕНИЕ Способ включения и допустимость исключения записей в набор мно- гие понимают как некоторое «членство в наборе» или «тип членства». Причина затруднений здесь не в самих концепциях, а в том, как они были первоначально представлены РГБД Комитет по языку описания данных не внес изменения в первоначальное представление, но, к сча- 79
стью, этой проблемой занялась РГЯБД. Очень часто восприятие кон- цепций существенно зависит от их представления и именования. По мнению РГЯБД, речь идет не об одной концепции, а о двух со- вершенно различных понятиях, практически не имеющих между собой ничего общего, кроме того, что они объявляются в одном и том же пред- ложении ЯОД. Поэтому мы будем рассматривать эти понятия раздельно, но при из- ложении синтаксиса вернемся к обобщенному представлению о членст- ве в наборе. Первым обсудим способ включения как наиболее сущест- венный. 7.2. СПОСОБ ВКЛЮЧЕНИЯ В НАБОР Способ включения в набор должен быть указан для каждого члена любого типа набора. Имеются два варианта способа включения: ав- томатический и ручной, В многочленном типе набора вполне допуска- ется объявление одного типа члена автоматическим, а другого — руч- ным. Однако по отношению к способу включения многочленные типы набора не представляют каких-либо сложностей по сравнению с одно- членными, и поэтому мы ограничимся рассмотрением последних. Для уяснения концепции способа включения необходимо иметь представление о двух операторах ЯМД — STORE и CONNECT. Чтобы поместить в базу данных новую запись, программит должен со- ставить эту запись в определенной области памяти и затем выпол- нить для нее оператор STORE (ПОСТАВИТЬ). Последний синтакси- чески очень прост, но обладает весьма сложной семантикой. Далее мы увидим, что на процесс его выполнения оказывают влияние многие декларации ЯОД. В частности, для каждого типа набора, членом кото- рого объявлен данный тип записи, рассматривается способ включения в данный набор. Действия, определяемые тем или другим вариантом способа вклю- чения, описать нетрудно. При ручном способе включения новая запись не включается ни в один набор данного типа, а при автоматическом — помещается в один из них. В какой именно — это уже отдельный во- прос* решаемый в соответствии с указанием о «выборе набора» (он об- суждается в следующей главе). Использование способа включения поясним на примере некоторой части системы обработки заказов (рис. 7.1). ПРЕДМЕТ ЗАГОЛОВОК- ЗАКАЗА-ПОКУПКИ ! ЗАДЕРЖАННЫЙ- ЗАКАЗ-ПОКУПКА I ЗАКАЗ СТРОКА-ЗАКАЗА «------ Рис. 7.1. Тип записи, являющийся автоматическим членом в одном типе набора и ручным в другом 80
На рис. 7.1 впервые в настоящей книге дается изображение ручного способа включения записи-члена в набор (пунктирной линией). Способ включения является настолько важной концепцией, что заслуживает самостоятельного графического представления, обеспечивающего не- посредственное визуальное восприятие на структурных диаграммах. В нашем примере каждая запись СТРОКА-ЗАКАЗА должна быть подключена к некоторой записи ЗАГОЛОВОК-ЗАКАЗА-ПОКУПКИ. Запись СТРОКА-ЗАКАЗА не имеет самостоятельного значения. В ней, скорее всего, содержатся наименование предмета, заказанное количест- во этих предметов и другие данные. Если этот предмет не имеется в на- личии в момент поступления заказа, то последний обычно помещается в «файл задержанных заказов». (Для пользователя IDS/1 это будет цепочка задержанных заказов, в данном же случае — их набор.) При поступлении новой партии товаров запускается программа, об- рабатывающая задержанные заказы, для которых уже есть соответст- вующие предметы. Однако в случае типа набора ЗАДЕРЖАННЫЙ- ЗАКАЗ существен именно тот факт, что в момент помещения записи СТРОКА-ЗАКАЗА в базу данных неизвестно, должна она быть вклю- чена в набор ЗАДЕРЖАННЫЙ-ЗАКАЗ или нет. Это можно выяснить лишь соответствующей проверкой, выполняемой чаще всего в про- грамме, содержащей оператор STORE. Если запись СТРОКА-ЗАКАЗА должна быть включена в набор ЗАДЕРЖАННЫЙ-ЗАКАЗ, то ее включение осуществляется с помощью оператора, названного РГЯБД CONNECT (ПОДКЛЮЧИТЬ). В спецификациях РГБД этог оператор определен как INSERT (ВКЛЮЧИТЬ)10, и, хотя данный термин не- сколько неудачен, он используется в большинстве ранних систем. Предложение ЯОД, специфицирующее порядок в наборе, имеет вид: ORDER IS PERMANENT INSERTION IS... Остается лишь надеяться, что INSERTION1 (ВКЛЮЧЕНИЕ) будет однажды заменено на CONNECTION (ПОДСОЕДИНЕНИЕ, ПОДКЛЮ- ЧЕНИЕ). Рассмотренный пример показывает, что способ включения является очень важной концепцией. В конечном счете выбранный администра- тором данных способ включения определяет семантику применяемого программистом оператора STORE. Специфицируя его для некоторого члена набора, администратор данных должен решить, имеет ли смысл самостоятельное существование экземпляров этого члена без явного соединения с каким-либо экземпляром владельца., Если да, то следует задать ручной способ включения, а если нет — автоматический. 7.2,1. Неприсоедкненные записи В том случае, когда для некоторого члена набора определен автома- тический способ включения, все равно имеется возможность исключить (отсоединить) соответствующую запись из набора, в который она была включена при выполнении оператора STORE. Это можно сделать с по- ‘ мощью оператора DISCONNECT (ОТСОЕДИНИТЬ). (РГБД ввела 81
термин REMOVE—ИСКЛЮЧИТЬ) —более трудный для объяснения, но часто встречающийся в конкретных системах наряду с INSERT.) Как правило, при исключении записи-члена из набора после вы- полнения двух-трех операторов программы она включается в неко- торый другой набор. Последнее, однако, не является обязательным, и запись может оказаться ни к чему не присоединенной в базе данных. Это относится также и к записям-членам с ручным способом вклю- чения. В подобных случаях естественно возникает вопрос: как вновь найти такую «неприсоединенную» запись? «Потеря» записей в базе данных при отсутствии какого-либо способа их последующего обнаружения — явление не из приятных. Если для данного типа записи определен спо- соб размещения CALC, то с помощью известного значения элемента CALC-ключа эту проблему можно решить. А что делать, если тип записи имеет другой способ размещения? При способе размещения VIA SET разработчик обычно вводит до- полнительное правило, согласно, которому способ включения должен быть автоматическим. Это означает, что должен быть определен набор, «вблизи» которого размещается запись. Если последняя будет затем ис- ключена из одного набора и включена в другой, то вряд ли при этом изменится ее физическое расположение. В некоторых системах введено еще одно правило о том, что тип записи, являющийся ручным членом какого-либо типа набора, дол- жен быть автоматическим членом в другом типе набора. 7.2.2. Двойное включение Рассмотрим важное правило, определяющее включение записей в наборы (оно уже упоминалось в разд. 3.4.1). Это правило входит в семантические правила предложения MEMBER и в журнале развития формулируется следующим образом: «Каждая запись-член участвует не более чем в одном экземпляре любого типа набора, в котором она определена в качестве типа записи-члена, т. е. она может быть связана не более чем с одной записью-владельцем каждого такого типа набора. В конкретном наборе данная запись может появиться только один раз». Это правило оказывает влияние на выполнение операторов STORE и CONNECT. И в том и в другом случае имеет место процесс выбора конкретного набора для включения записи, но протекает он для ука- занных операторов не одинаково. При выполнении STORE речь идет о новой записи, которая не может оказаться уже включенной в какой- либо другой экземпляр рассматриваемого типа набора. Что касается оператора CONNECT, то здесь ситуация совершенно иная. Програм- мист может по ошибке попытаться включить запись в набор, когда она уже присутствует в этом наборе или в каком-либо ином наборе того же типа. А так как двойное включение запрещено, подобная по- пытка приведет к отказу в выполнении данного оператора. Последст- вия невозможности выполнения операторов ЯМД будут обсуждаться позднее. 82
7.3. ДОПУСТИМОСТЬ ИСКЛЮЧЕНИЯ Если способ включения связан с постановкой записи в базу дан- ных, то допустимость исключения относится в основном к: удалению из нее записи. Эта концепция несколько увеличивает структурирую- щие средства администратора данных. Следуя спецификациям КЯОД, она дает администратору данных возможность предотвратить ситуа- цию, при которой записи оказываются ни к чему не присоединенными в базе данных. Существуют два вида определения исключения, которые идентифи- цируются РГБД и КЯОД как MANDATORY (ОБЯЗАТЕЛЬНЫЙ) и OPTIONAL (НЕОБЯЗАТЕЛЬНЫЙ). РГЯБД переименовала их со- ответственно в «постоянный» и «временный». Обязательный набор под- разумевает, что однажды включенная в него запись остается там по- стоянно и не может быть из него исключена, если при этом она не уда- ляется вообще из базы данных. Кроме того, выбор того или иного варианта исключения влияет на процесс выполнения оператора ERASE (или DELETE — УДА- ЛИТЬ запись). Однако семантика этого оператора настолько сложна и настолько сильно зависит от допустимости исключения, что пока мы укажем лишь ее основную проблему, а именно что происходит с запи- сями-членами при удалении записи-владельца. Допустимость исключения, возможно, следовало бы назвать «до- пустимостью отсоединения» ввиду переименования оператора REMOVE в DISCONNECT. Если администратор данных собирается обеспечить гибкость управления записями, то он может указывать необязатель- ный вариант, но в отдельных случаях весьма полезноюпределить и обя- зательный тип набора. 7.4. ЗАМЕЧАНИЯ О РЕАЛИЗАЦИИ Допустимость исключения является первым встретившимся в насто- ящей книге свойством, реализации которого различаются почти во всех конкретных системах, если не синтаксически, то, по крайней мере, семантически. Влияние выбора способа включения на выполнение оператора STORE реализуется, как правило, достаточно стандартно, но некоторые разработчики распространяют семантику способа вклю- чения на допустимость исключения, ликвидируя тем самым четкое разграничение между этими двумя понятиями, В других случаях до- пустимость исключения трактуется в более узком, чем в представлен- ном выше, смысле. 7.5. СИНТАКСИС ОПРЕДЕЛЕНИЯ СПОСОБА ВКЛЮЧЕНИЯ И ДОПУСТИМОСТИ исключения Способ включения и допустимость исключения определяются в под- статье члена статьи набора (см. параграф 6.7 и разд. 6.10.1). В спе- цификациях КЯОД подстатья члена имеет следующий вид: 83
(AUTOMATIC) (MANDATORY MEMBER IS имя-записи-1 < АЛЛХ1ТТАТ ------- MANUAL OPTIONAL [LINKED TO OWNER] ( ASCENDING I lRA2^1 KEY IS DESCENDING ид-базы-данных-3 ASCENDING " ’ DESCENDING ид-базы-данных-4 7.6. ПРИ Al EP Для иллюстрации определения способа включения и допустимости исключе- ния воспользуемся примером, приведенным на рис, 7,1, SET NAME IS ЗАКАЗ-ПОКУПКА OWNER IS ЗАГОЛОВОК-ЗАКАЗА-ПОКУПКИ ORDER IS PERMANENT INSERTION IS FIRST MEMBER IS СТРОКА-ЗАКАЗА MANDATORY AUTOMATIC OWNER SET NAME IS ЗАДЕРЖАННЫЙ-ЗАКАЗ PRIOR OWNER IS ПРЕДМЕТ ORDER IS PERMANENT INSERTION IS LAST MEMBER IS СТРОКА-ЗАКАЗА OPTIONAL MANUAL LINKED TO OWNER Причины определения для набора ЗАДЕРЖАННЫЙ-ЗАКАЗ ручного вклю- чения были изложены в параграфе 7.2. Тип набора ЗАКАЗ-ПОКУПКА объяв- лен «обязательным», так как вряд ли имеет смысл отделять некоторую строку от заказа, частью которого она является. В типе набора ЗАДЕРЖАННЫЙ-ЗАКАЗ тип записи-члена объявлен «необязательным» — после удовлетворительной обра- ботки задержанного заказа соответствующая СТРОКА-ЗАКАЗА отсоединяется от «предмета», но остается в базе данных. ГЛАВА 8 ВАРИАНТЫ ВЫБОРА НАБОРА 8.1. ВВЕДЕНИЕ Мы уже рассмотрели два свойства типа набора — вид его представ- ления и упорядоченность, а также три свойства типа записи-члена в типе набора — поисковые ключи, способ включения и допусти- мость исключения. Было бы неправильным считать какое-либо из этих свойств чисто структурным, хотя сама концепция типа набора (как свойство двух типов записи) является структурной в том смысле, что она определяется для облегчения доступа к записям-членам. То же са- мое можно сказать и о поисковых ключах. Вид набора имеет отноше- ние к представлению в памяти, а способ включения и допустимость исключения — к семантике операторов ЯМД. Какое же место в этой классификации займет еще одно свойство, к изучению которого мы переходим? 84
8.2. КРИТЕРИЙ ВЫБОРА НАБОРА Критерий выбора набора является свойством типа записи-члена в типе набора. В терминах приведенной выше классификации этот критерий, безусловно, имеет отношение к семантике операторов ЯМД. Выше уже несколько раз упоминалось о возникающей в процессе выполнения программы проблеме выбора конкретного набора данно- го типа, в который должна быть включена запись, из которого она должна быть исключена или в котором ее нужно найти. Другими сло- вами, данная проблема появляется, как правило, при выполнении следующих четырех операторов ЯМД: STORE, FIND, CONNECT, MODIFY. Существуют два подхода к ее решению. Один из них основан на ис- пользовании «индикатора текущей в типе набора». Последний уже встречался в разд. 6.4.2 при обсуждении упорядочения набора, где, в частности, указывалось, что, установив соответствующий мидика- тор, программист может в некоторых случаях упорядочивать набор по своему усмотрению. Другой подход к решению проблемы выбора на- бора гораздо сложнее. Он используется только для операторов STORE и FIND. Для операторов же CONNECT и DISCONNECT возможен лишь первый подход, но поскольку он применим также и к указанным выше операторам, его мы рассмотрим в первую очередь. 8.3. ВЫБОР НАБОРА ПО ИНДИКАТОРУ ТЕКУЩЕГО СОСТОЯНИЯ Напомним, что во время выполнения программы для каждого при меняемого в ней типа набора автоматически поддерживается индикатор текущей записи (являющийся фактически и индикатором текущего экземпляра набора в данном типе набора). Как мы увидим далее, ЯОД подсхемы допускает ограниченное представление базы данных. Если в схеме последней определено 29 типов записи и 37 типов набора, то одна из подсхем может ограничиться только 7 типами записи и 11 ти- пами набора. В программе, работающей по этой подсхеме, будет под- держиваться 11 индикаторов текущей в типе набора. В начале выполнения программы все указанные индикаторы содер- жат нулевые значения, но при исполнении каждого оператора FIND или STORE значения одного или нескольких из них обновляются. В этом случае в индикатор ставится значение ключа базы данных неко- торой записи, хранящейся в базе данных. Как правило, такая запись принадлежит к типу, являющемуся владельцем или членом в тех ти- пах набора, для которых обновляются индикаторы текущих. Пусть теперь нам нужно поместить в базу данных запись, являю- щуюся автоматическим членом одного (для простоты) типа набора. В подобной ситуации запись должна быть включена в некоторый эк- земпляр упомянутого типа набора. В который именно? Это зависит от состояния индикатора текущей записи соответствующего ти па набора. Индикатор текущей записи может указывать на его владельца или на одного из членов. Определяет ли индикатор также и позицию > в кото- 85
рую вставляется запись, зависит от способа упорядочения набора. Что же касается выбора набора с помощью этого индикатора, то он может определяться рассмотренным выше критерием, а может и не опреде- ляться им. Так, для оператора STORE выбор набора связан с кри- терием выбора набора, а для CONNECT — нет. Так уже получается, когда вопрос решается комиссией или рабочей группой. Синтаксис РГБД для выбора набора по индикатору текущей имеет вид: SET OCCURENCE SELECTION IS THRU CURRENT OF SET В спецификациях КЯОД он заменен следующим: SET SELECTION IS THRU имя-набора-l OWNER IDENTIFIED BY CURRENT OF SET (Следует отметить некоторую неточность в оригинальном тексте от- чета КЯОД. Указанное выше имя-набора-1 написано в кем как имя- набора-2, что создает впечатление, будто выбор набора всегда осуще- ствляется через какой-либо другой тип набора, а не через тот, который указан в начале статьи набора.)11 8.4. ВЫБОР НАБОРА ПО СПОСОБУ РАЗМЕЩЕНИЯ CALC Если в некотором типе набора тип записи-владельца имеет способ размещены я CALC, то этот последний может использоваться для выбора набора вместо индикатора текущей. Как уже отмечалось в параграфе 4.5, задавая данный способ размещения, администратор данных дол- жен указать, является ли CALC-ключ уникальным или нет, т. е. сле- дуя терминологии РГБД, допускаются дубликаты его значений или не допускаются. В том случае, когда дубликаты значений CALC-ключа запрещены, он позволяет однозначно идентифицировать запись-владельца и может использоваться для выбора набора. По-видимому, РГБД питала некоторые иллюзии относительно ис- пользования способа размещения DIRECT, так как аналогичная воз- можность формулировалась ею как «выбор набора по способу размеще- ния владельца», причем указывалось, что способ размещения DIRECT здесь может использоваться наряду со способом размещения CALC. Однако оказалось, что это совсем не так, в связи с чем КЯОД полно- стью измен ил синтаксис и семантику данного варианта. Идея выбора набора по CALC-ключу (в новой формулировке КЯОД) состоит в том, что во время выполнения программы резидентному мо- дулю СУБД передаются значения CALC-ключа, по которым он выби- рает экземпляр записи-владельца, а тем самым и экземпляр набора. В соответствии со спецификациями РГБД эти значения могут переда- ваться через область оперативной памяти, выделенную для типа запи- си-владельца. Такая «область записи» отводится в оперативной памя- ти для каждого типа записи подсхемы (см. ниже). С другой стороны, администратор данных может указать и другие элементы с идентич- ными характеристиками в качестве средства передачи параметров. 86
CALC-KEY EQUAL ТО Синтаксис РГБД для рассматриваемого варианта (с. 145) имеет вид: SET OCCURENCE SELECTION IS THRU LOCATION MODE OF OWNER (USING ид-данных-5 [, ид-данных-6] ... {ALIAS FOR ид-данных-7 IS имя-данных-!} ...] Следует помнить, что использование данного синтаксиса предпола- галось и в том случае, когда у записи-владельца определен способ размещения DIRECT. Синтаксис КЯОД более точен: SET SELECTION IS THRU имя-набора-l OWNER IDENTIFIED BY ид-данных-1 "I Г , ид-данных-3 1 1 имя-данных-1) [ , имя-данных-3 J J Владелец набора имя-набора-1 должен иметь способ размещения CALC. Если вариант EQUAL ТО (РАВЕН) не используется, то прежде чем применять данный критерий выбора, необходимо присвоить соот- ветствующие значения элементам CALC-ключа в рабочей области за- писи. При использовании этого варианта указанные элементы могут быть, вообще говоря, объявлены в любой части схемы, т. е. в любом типе записи, и им нужно предварительно присвоить соответствую- щие значения. 8.5. ВЫБОР НАБОРА ПО ЭЛЕМЕНТУ ТИПА КЛЮЧА БАЗЫ ДАННЫХ Этот вариант аналогичен выбору набора по индикатору текущей за- писи с той лишь разницей, что здесь используется не определяемый си- стемой индикатор, а специфицируемый в схеме элемент данных. Пре- имущества такого способа не вполне ясны. В любом случае система за- ведет и будет поддерживать индикатор текущей записи. И даже если по решению администратора данных потребуется применить элемент данных, то программисту придется переместить в этот элемент значе- ние ключа базы данных из индикатора. В разд. 4.6.1 было показано, что в типе записи можно определять элементы типа ключа базы данных. Рассматриваемый вариант выбор ! набора представляет собой один из способов использования таких эле- ментов. Синтаксис КЯОД для этого варианта имеет вид: SET SELECTION IS THRU имя-набора-l OWNER IDENTIFIED BY DATA-BASE-KEY [eQUAL TO ( ид“даннЬ1Х“1 11 ^имя-данных-I J J Синтаксис РГБД в данном случае соответствует выбору по способу размещения владельца. На самом деле выбор набора по элементу типа ключа базы данных концептуально не зависит от способа размещения типа записи-владельца. Если известен ключ базы данных записи-вла- дельца, то последняя может быть найдена, что определяет и выбор на- бора, независимо от того, какой из способов размещения — CALC, 8Z
DIRECT, SYSTEM или VIA SET — специфицирован для владельца, РГБД пыталась связать выбор записей по ключу базы данных с DIRECT, в то время как этот вариант выбора совершенно не зависит ст способа размещения. Рассмотренные выше три варианта выбора набора довольно часто встречаются (в соответствии с порядком их представления) в конкрет- ных системах. Существует еще один вариант, который применяется значительно реже, но для полноты изложения здесь будет приведен. 8.6. ИЕРАРХИЧЕСКИЙ ВЫБОР НАБОРА Сущность иерархического выбора должна быть понятна читателям, знакомым с системой IMS, так как в данном случае была, по-видимому, Рис. 8.1. Иерархия типов набора предпринята попытка перенести в предложения РГБД одну из особен- ностей этой системы. Для представления решаемой здесь проблемы мы должны вспомнить, что тип набора является, вообще гово- ря,лишь средством построения пол- ной структуры базы данных. Пусть нам требуется построить структуру базы данных, показанную на рис. 8.1. Именно в таких конструк- циях предполагается использовать иерархический выбор набора. Отметим некоторое различие в подходах РГБД и КЯОД к поста- новке проблемы. В соответствии со спецификациями РГБД (с. 147, пра- вило 4) иерархический выбор набора «применяется в тех случаях, ког- да непосредственная запись-владелец экземпляра набора может быть однозначно выбрана только как член некоторого другого набора ... Эта ситуация может возникать на произвольном числе уровней, со- ставляющих непрерывный путь от конкретного владельца набора имя- набора-2 до конкретного владельца типа набора, частью определения которого является данное предложение выбора». Другими словами, администратор данных может предопределить путь от записи А к записи D (см. рис. 8.1). Это делается для того, чтобы при помещении экземпляра D в базу данных (а в некоторых случаях и при его поиске) программист перед выполнением оператора STORE или FIND мог задать значения последовательности элементов данных, устанавливая тем самым «экземпляр пути» для «типа пути», специфи- цированного администратором данных. Такой вариант выбора позво- ляет сократить число операторов в программе. При его отсутствии программисту пришлось бы процедурно пройти по указанному пути g помощью операторов FIND. Возможны ли ситуации, при которых администратор данных вы- нужден определять именно иерархический выбор набора? Ответ на 88
этот вопрос должен быть отрицательным, однако РГБД все-таки выде- ляет ситуацию, при которой оба типа записи В и С имеют способ раз- мещения VIA SET. Самая «верхняя» запись структуры не может размещаться таким способом, так как она не является членом ни одного типа набора. Для нее характерен, скорее всего, способ размещения CALC. Иерархический выбор набора позволяет избегать применения ва- риантов выбора по индикаторам текущей или по сообщаемому ключу базы данных. Если мы определяем критерий выбора набора для D в типе набора CD, то мы не можем использовать способ размещения вла- дельца, поскольку для С специфицирован VIA SET. Таким образом, запись С может быть выбрана только как член набора ВС. В свою очередь В тоже имеет способ размещения VIA SET, и поэтому ее можно выбрать лишь как член набора АВ. Запись А выбирается однозначно, так как она относится к типу записи со способом размещения CALC (в предположении уникальности данного CALC-ключа). Следуя РГБД, мы должны были бы определить этот алгоритм так: MEMBER IS D... SET OCCURENCE SELECTION IS THRU AB USING LOCATION MODE OF OWNER BC USING BB CD USING CC где BB и CC — элементы записей В и С соответственно. В действительности приведенная выше выдержка из предложений РГБД о том, когда рекомендуется применять иерархический выбор набора, не отражает сути проблемы. Здесь, скорее, помогает аналогия с «аргументом поиска сегмента» в системе IMS, которая подсказывает программисту непроцедурный способ поиска и постановки записей с помощью конкретизации пути доступа. При этом расход машинного времени остается прежним, так как система в любом случае должна пройти вниз по иерархической «лестнице», осуществляя на каждой ее ступеньке доступ к соответствующим записям. 8.7. СИНТАКСИС Для полноты представления приведем синтаксис РГБД определе- ния выбора набора. Он имеет два формата: один — для неиерархичес- ких вариантов, другой — для иерархического. Формат 1 SET OCCURENCE SELECTION IS THRUt CURRENT OF SET . LOCATION MODE 'USING ид-данных-5 F. ил-данпмх-6] ... . OF OWNER, {ALIAS FOR ид-даьпыл-/ io шил данных-1} ... Ь9
Формат. 2 SET OCCURENCE SELECTION IS THRU имя набора-2 USING (CURRENT OF SET LOCATION MODE .OF OWNER [ALIAS FOR ид-данных-8 IS имя-данных-2] ... , имя-набора-3 USING ид-данных-9 [, ид-данных-10] ... {ALIAS FOR ид-данных-ll IS имя-данных-3} ... Синтаксис КЯОД не менее сложен и существенно отличается от приведенного выше. В частности, он включает некоторый специаль- ный вариант для многочленных типов набора. Как указывалось в на- чале главы, выбор набора является свойством члена, а не типа набора. Однако трудно представить себе ситуацию, при которой было бы жела- тельно иметь два или более критериев выбора набора в одном и том же типе набора. Специальный вариант КЯОД дает администратору дан- ных возможность указывать, что выбор набора для одного из членов многочленного типа набора совпадает по определению с выбором набо- ра какого-либо другого члена. Теоретически это средство позволяет избежать повторного описания длинных иерархических путей доступа. Синтаксис КЯОД также имеет два формата, но лишь один из них опи- сывает рассмотренные выше свойства. SET SELECTION [FOR имя-набора-1] IS THRU имя-набора-2 OWNER IDENTIFIED BY SYSTEM CURRENT OF SET DATA-BASE-KEY EQUAL TO ид-данных-l 1 имя-данных-l J CALC-KEy[eQUAL TO [ ид-данных-2 1 [• иД-Даннь.х-3 1 --------— L ( имя-данных-2 J имя-данных-3 J MEMBER имя-записи-l SELECTION THEN THRU имя-набора-3 WHERE OWNER IDENTIFIED BY ид-данных-4 Ш EQUAL TO f ид-данных-5 .------— [ имя-данных-4 Читателя не должна вводить в заблуждение разница между именем- набора-1 и именем-набора-2. Числовые индексы здесь призваны обес- печить однозначную ссылку на соответствующие имена в синтаксичес- ких и общих правилах. Однако для всех вариантов выбора, кроме ие- рархического, имя-набора-1 и имя-набора-2 должны обозначать один и тот же тип набора. 90
8.8. ИСПОЛЬЗОВАНИЕ БОЛЕЕ ПРОСТЫХ ВАРИАНТОВ ВЫБОРА НАБОРА Иерархический вариант усложняет выбор набора в предложениях как РГБД, так и КЯОД. На практике этот вариант реали-зован лишь в одной или двух СУБД и читателю не придется иметь с ним дело, если он не работает именно с такими системами. Мы бы рекомендовали администраторам данных по возможности пользоваться не иерархическим вариантом, а наиболее простым выбо- ром набора по индикаторам текущих, если только в системе не предус- мотрено средство, которое рассматривается в следующем параграфе. В любом случае программист, применяющий типы набора, должен уметь работать с индикаторами текущих состояний, так что наша ре- комендация не вызовет у него затруднений. 8.9. ОСОБЕННОСТЬ КРИТЕРИЯ ВЫБОРА НАБОРА В предложениях КЯОД предусмотрено дополнительное средство, которое не только упрощает подход к проблеме выбора набора, но и имеет отношение к общей проблеме логического представления типа набора. В предложениях РГБД, а следовательно, и в большинстве реализо- ванных систем отношение «один к многим» между двумя типами записи определяется явно с помощью следующих указаний: SET NAME IS имя-набора-l OWNER IS имя-записи-1 MEMBER IS имя-записи «1 Другими словами, отношение существует потому, что его сущест- вование определено, а не потому, что оно предполагается по каким-то внутренним свойствам. Собственно, единственный способ установить неявную связь (в общем смысле) между двумя типами записи — вклю чить общие элементы данных в оба типа записи. Лучше всего пояснить это на примере. Рассмотрим два типа записи: 01 ОТДЕЛ LOCATION MODE IS CALC USING НОМ-ОТД DUPLICATES NOT ALLOWED 02 НОМ-ОТД PICTURE 999 02 НАЗВ-ОТД PICTURE X (15) 02 КОД-ПОМЕЩ PICTURE 99 02 БЮДЖЕТ PICTURE 999 01 СЛУЖАЩИЙ LOCATION MODE IS CALC USING НОМ-СЛУЖ DUPLICATES NOT ALLOWED 02 НОМ-СЛУЖ PICTURE X (4) 02 ФАМ-СЛУЖ PICTURE X (12) 02 ЛАБ-СЛУЖ PICTURE X (4) 02 НОМ-ОТД-СЛУЖ PICTURE 999 02 ГОД-РОЖД PICTURE 9 (6) Наиболее существенна в приведенных декларациях, типа записи схемы предпоследняя строка в типе записи СЛУЖАЩИЙ, специфици- рующая простой элемент данных НОМ-ОТД-СЛУЖ. Совпадает ли 91
последний с элементом НОМ-ОТД в типе записи ОТДЕЛ? Точнее, бе- рутся ли их значения из одного множества значений? Эти вопросы фак- тически относятся к семантике определяемых данных. Если значения указанных элементов действительно берутся из од- ного множества значений, то включение НОМ-ОТД-СЛУЖ в тип записи СЛУЖАЩИЙ равносильно утверждению, что в каждом отделе имеется нуль, один или более служащих, а каждый служащий принад- лежит одному или не принадлежит ни одному из отделов. До сих пор мы не вводили в рассмотрение отношения типа набора. Интересно проследить, что произойдет, если не определять явно от- ношение, неявно выраженное в элементах данных. Прежде всего, уве- личится время выполнения процессов, связанных с доступом ко всем служащим некоторого отдела. Ведь роль отношений типа набора и со- стоит главным образом в обеспечении путей доступа (см. параграф 3.5). Следует также рассмотреть вопрос о том, как достигается совпа- дение значений элементов НОМ-ОТД-СЛУЖ и НОМ-ОТД. Такое сов- падение требуется в момент помещения записи СЛУЖАЩИЙ в базу данных, если для нее определен автоматический тип включения (см. параграф 7.2). Тем не менее в рассмотренных выше синтаксических правилах ЯОД схемы не предусматривались средства для сравнения значений некоторого элемента в типе записи-члена и «соответствующе- го» элемента в типе записи-владельца. Подобные рассуждения могут показаться неуместными в главе, посвященной выбору набора, но именно критерий выбора набора име- ет к ним самое прямое отношение. Если бы удалось выбрать экземпляр набора с помощью значения НОМ-ОТД-СЛУЖ и при этом выяснилось, что для данного экземпляра записи СЛУЖАЩИЙ оно не совпадает ни с одним из имеющихся в базе данных значений НОМ-ОТД, то вы- брать соответствующий набор оказалось бы невозможным. При авто- матическом типе включения это означает, что оператор STORE СЛУ- ЖАЩИЙ не выполняется (возникает исключительное состояние базы данных). Такой метод выбора набора обеспечивает проверку правиль- ности значений элемента в типе записи-члена, который используется в критерии выбора набора. Его можно назвать проверкой правильно- сти связи между типами записи. Изложенный ранее подход РГБД (в части, касающейся выбора на- бора по способу размещения CALC, см. параграф 8.4) не позволяет реа- лизовать рассмотренную выше возможность. В рамках спецификаций РГБД мы можем написать: SET NAME IS О-С OWNER IS ОТДЕЛ ‘member’ IS СЛУЖАЩИЙ ‘ SET‘ OCCURENCE SELECTION* IS THRU LOCATION MODE OF OWNER USING НОМ-ОТД Здесь нельзя заменить НОМ-ОТД элементом НОМ-ОТД-СЛУЖ, так как правила явно определяют, что «все идентификаторы-базы-дан- 92
ных должны относиться к элементам данных, объявленным в записи- владельце указанного набора (наборов)». Однако в пересмотренном синтаксисе КЯОД выбор набора специ- фицируется следующим образом: SET SELECTION FOR О-С IS THRU O-C OWNER IDENTIFIED BY CALC-KEY EQUAL TO НОМ-ОТД-СЛУЖ Несколько непоследовательный синтаксис, но зато обеспечивает Требуемый эффект. Пожалуй, следовало бы назвать элемент записи- члена, управляющий выбором набора, «элементом набора», а синтаксис всего предложения упростить: (SYSTEM SET SELECTION IS VIA «CURRENT OF SET (SET ITEM имя-данных-2 [, имя-данных-3] ... В соответствии с правилами, регулирующими взаимосвязь между выбором набора и способом включения, для типа набора, имеющего запись-члена с ручным включением (см. параграф 7.2), можно опреде- лить любой вариант выбора набора. При ручном способе включения запись-член не вставляется в набор в момент ее помещения в базу дан- ных, но может быть введена в него позднее оператором CONNECT (см. параграф 16.5). Этот оператор не использует определение выбора набора, и, следовательно, с его помощью можно подсоединить запись СЛУЖАЩИЙ к записи ОТДЕЛ с несовпадающим номером отдела. Если администратор данных считает нужным воспользоваться контро- лирующим свойством типа набора (кроме обеспечения доступа к за- писям-членам), то ему рекомендуется специфицировать автоматичес- кий способ включения. ГЛАВА 9 ВНУТРЕННЯЯ СТРУКТУРА ТИПА ЗАПИСИ 9.1. ВВЕДЕНИЕ Представление концепции типа записи в параграфе 3.2 предназна- чалось в основном для читателей-программистов, не имеющих опыта в экономических приложениях. Однако там она была именно представ- лена, а не исследована, и нам теперь предстоит детально рассмотреть внутреннюю структуру записи схемы. Различие внутренней структуры записи и «внешней» структуры связей между записями определялось в в параграфе 3.3. До сих пор предметом изучения в настоящей книге являлась, главным образом, внешняя структура связей как одна из фундаментальных концепций современных систем управления базами данных. На уровне внутренней структуры записи РГБД также выдви- нула несколько новых идей, к рассмотрению которых мы и переходим. 93
9.2. ИСТОРИЧЕСКИЕ ПРЕДПОСЫЛКИ Уже в октябрьском отчете 1969 г. РГБД настолько отошла от перво- начальной задачи «расширения Кобола», что слово «Кобол» и не упоми- налось нигде в тексте после предисловия председателя рабочей груп- пы. В предисловии же отмечалось: «Мы надеемся, что язык описания данных явится основой разработки соответствующего стандарта и что отдельные включающие языки будут с ним взаимодействовать». И да- лее: «С другой стороны, семантика и синтаксис языка манипулирова- ния данными предлагаются как расширение Кобола и как образец средств манипулирования данными, которые должны присутствовать во включающем языке. Для других включающих языков могут быть разработаны соответствующие средства, т. е. синтаксис и семантика ЯМД». Однако высказанное здесь пожелание оказалось трудно реализуе- мым. Во-первых, в 1969 г. фирма IBM активно продвигала ПЛ/1, прео- долевая некоторое сопротивление рынка, а, во-вторых, внутренняя структура записи в ЯОД схемы в октябрьском варианте 1969 г. пол- ностью совпадала с соответствующей структурой Кобола. Естественно, IBM выразила протест, заявив, что ЯОД схемы слишком тесно связан с Коболом и поэтому не может претендовать на взаимодействие с нес- колькими включающими языками. В связи с этим РГБД заменила ориен- тированную на Кобол внутреннюю структуру записи ЯОД схемы со- ответствующей структурой, ориентированной на ПЛ/1, представленной в апрельском отчете 1971 г. Между 1971 и 1973 гг. интерес к ПЛ/1 за- метно ослаб, но КЯОД не вернулся к структурам Кобола. Тем не менее все разработчики СУБД, базирующихся на предложениях КОДАСИЛ, в той или иной степени вновь обратились к первоначальным структу- рам. И дело здесь вовсе не в том , что их не устраивает язык ПЛ/1, а, скорее, в том, что они не хотят пользоваться его внутренней структу- рой записей (что совсем не одно и то же). Возврат к Коболу может осуществляться двумя способами. Пер- вый из них состоит в использовании Кобола и его структур, второй — в использовании структур Кобола, выраженных в языке ПЛ/1, т. е. , фактически подмножества предложений РГБД и КЯОД. 9.3. НАЗНАЧЕНИЕ ВНУТРЕННЕЙ СТРУКТУРЫ ЗАПИСИ Внутренняя структура записи является основным средством связи между базой данных и включающим языком. Как было показано в пре- дыдущих главах, связи между записями обеспечиваются соответствую- щими возможностями ЯМД. Манипулирование данными внутренней структуры записи полностью относится к включающему языку. Записи ПЛ/1 бесспорно имеют более развитую структуру, чем запи- си Кобола, т. е. допускают большее число различных типов элементов и предоставляют большие возможности по определению вложенных повторяющихся групп. Интересно отметить, что с момента, когда фирма IBM в 1964 г. представила язык ПЛ/1, отношение к внутренней структуре записи 94
завершило «круговой цикл» развития. Относительно недавно в ис- следовательских публикациях IBM стали подчеркиваться достоинст- ва представления с интригующим названием «отношения в третьей нормальной! форме». Анализ этого якобы абстрактного представления показывает, что здесь подразумевается (в традиционной терминоло- гии обработки данных) отсутствие сложной внутренней структуры записи. Гораздо легче представить себе общую структуру базы дан- ных, если каждая запись состоит только из простых элементов и не имеет повторяющихся групп. Мы согласны с этим мнением. Если экземпляры повторяющейся группы имеют неодинаковые раз- меры в различных экземплярах записи, то это приводит к переменной длине записи. Такая возможность, безусловно, предусматривается Коболом ANSI. Как указывалось в параграфе 3.3, внутренняя струк- тура записи представляет собой исторически сложившуюся концеп- цию, в то время как тип набора является относительно новым поняти- ем. Никакой комитет не в состоянии отменить внутреннюю структуру записи, но может рекомендовать ею не пользоваться. Некоторые раз- работчики не допускают записей переменной длины, а следовательно, и фразы OCCURS DEPENDING (ПОВТОРЯЕТСЯ В ЗАВИСИМОС- СТЙ) в Коболе (или ее эквивалента). Скорее всего* это свойство со временем выйдет из употребления. Перейдем теперь от критических замечаний к изложению внутренней структуры типа записи в ЯОД схемы. 9.4. ТИПЫ ЭЛЕМЕНТОВ Каждый простой элемент данных может быть определен с помощью предложения TYPE (ТИП) или PICTURE (ШАБЛОН), но не тем и другим одновременно. Предложение TYPE типично для ПЛ/1 и от- ражает предусмотренную в нем возможность работать с комплексными числами, последовательностями битов, символьными строками и раз- личными типами действительных числовых элементов. Синтаксис это- го предложения в спецификациях КЯОД (с. 3.55) имеет вид: TYPE IS (BINARY (DECIMAL| f FIXED 1 | FLOATJ ( REAL [COMPLEX [целое-1 [, целое-2]] (BIT ' {CHARACTER | (целое'31 DA TA-BAsE-KEY имя- разработчика Первая часть данного синтаксического правила относится к чис- ловым элементам. В качестве примера приведем четыре возможные 95
комби на ix и и для REAL: REAL BINARY FIXED REAL BINARY FLOAT REAL DECIMAL FIXED REAL DECIMAL FLOAT В конкретной системе могут быть реализованы не все комбинации’ так как это зависит от числа возможных аппаратных представлений числовых: элементов данных. Целое-1 определяет точность представ- ления элемента, а целое-2 задает масштабный множитель. Последнее применяется только для элементов с фиксированной точкой. Элементы типа BIT представляют собой битовые строки (недопус- тимые в Коболе), целое-3 указывает длину строки. Литерные (символь- ные) строки или элементы типа CHARACTER известны читателям, использующим Кобол, как элементы DISPLAY (ДЛЯ ВЫВОДА). В разд. 4.6.1 уже упоминалось о возможности определения элемен- тов типа DATA-BASE-KEY, и теперь мы видим, как она реализует- ся в контексте спецификации внутренней структуры записи. Необхо- димо помнить, что хотя для каждой помещаемой в базу данных записи выделяется некоторое значение ключа базы данных, администратор данных н,е обязан описывать в типе записи элемент для размещения этого значения. Подобный элемент предназначен для администратора данных, ориентирующегося на физический уровень представления и собирающегося обеспечить программистам средство работы на этом уровне. В зависимости от свойств программ реструктуризации исполь- зование элементов типа ключа базы данных может привести к различ- ным неприятным последствиям. В нескольких случаях РГБД позволяла разработчикам включать свои собственные средства, выходящие за рамки ее предложений. КЯОД отменил все эти «вакантные возможности», за исключением рас- сматриваемой. Если разработчик собирается использовать включаю- щий язык, который может работать с типами данных, непредусмотрен- ными в ПЛ/1, а следовательно, и в ЯОД схемы, то он может включить их как элементы типа «имя разработчика». Примерами могут служить типы данных «дата», «время», «широта» и «долгота». 3.5. ПОВТОРЯЮЩИЕСЯ ГРУППЫ (ИЛИ АГРЕГАТЫ) Повторяющаяся группа — это поименованная совокупность эле- ментов, которая в конкретной записи может присутствовать в несколь- ких экземплярах. В Коболе имеются два вида повторяющихся групп: с фиксированным для всех экземпляров записи числом повторений и с переменным. В типе записи этого языка может быть определено лю- бое число повторяющихся групп первого вида. Что же касается повто- ряющихся групп второго вида, то их всего три, и они должны разме- щаться в конце записи. Язык ПЛ/1, а вслед за ним и ЯОД схемы накладывает меньшие огра- ничения на степень вложенности повторяющихся групп и их располо- жение в записи. Для обозначения вложенных повторяющихся групп 96
в ПЛ/1 используется термин «агрегат», который перенесен также в ЯОД схемы- Синтаксис ЯОД схемы для определения повторяющихся групп бо- лее простой и непосредственный, чем в Коболе. Он имеет следующий вид: OCCURS О6-"06'1 ] TIMES [ид-данных-1 ) Если применяется целое-1, то оно определяет фиксированное чис- ло повторений и должно быть больше нуля В этом случае число эк- земпляров группы одинаково в каждом экземпляре записи. При ис- пользовании ид-данных-1 он должен соответствовать простому эле- менту данных, принадлежащему той же записи и имеющему тип REAL FIXED, т. е. принимающему только целые значения. Агрегаты данных определяются с помощью предложения OCCURS. Агрегат, повторяющаяся компонента которого представляет собой простой элемент данных, называется вектором. Если этот элемент- компонента имеет числовой тип, то такой вектор эквивалентен одно- мерному массиву Фортрана. 9.6. ШАБЛОНЫ Определяя характеристики элемента данных, вместо предложения «тип» можно использовать предложение «шаблон». Концепция шаблона хорошо знакома пользователям Кобола и ПЛ/1. Пользователям же Фортрана поясним, что шаблон есть средство описания формата зна- чений элемента. При работе с числовыми данными это средство приме- няется редко, так как оно предназначено для таких «невычисляемыхэ данных, как номера телефонов, даты, имена, адреса и т. п. Примеры использования шаблона: ДАТА-РОЖДЕНИЯ PICTURE IS 99X99X99 НОМЕР-ТЕЛЕФОНА PICTURE IS 999X999X9 (4) Цифра 9 здесь означает, что в данной позиции допускается любая десятичная цифра от 0 до 9; X указывает позицию, которая может со- держать любую литеру из имеющегося набора литер; (4) определяет число повторений предыдущего символа. Второй пример можно на- писать в виде: НОМЕР-ТЕЛЕФОНА PICTURE IS 999X999X9999 Указатель повторения весьма полезен в тех случаях, когда некото- рый символ шаблона повторяется много раз, например: ФАМИЛИЯ PICTURE IS А (12) Значения элемента ФАМИЛИЯ могут состоять только из букв и про- белов. Предложение PICTURE, как и другие средства определения внут- ренней структуры записи в ЯОД схемы РГБД, базируется на соот- 4 Зак. 145 97
ветствующих средствах языка ПЛ/1. С другой стороны, разработчики конкретных систем часто ограничиваются Коболом, в котором есть ана- логичное предложение, полностью совпадающее с PICTURE. Поэтому мы здесь не будем вдаваться в подробности и порекомендуем читателю обратится к любому достаточно полному руководству по Коболу. зЛЕГИЕИТЫ-КОПИИ - гмент-копия —это элемент, определяемый как принадлежащий г литам записи в некотором типе набора. В типе записи-владель- L.i он специфицируется обычным способом, а в типе записи-члена — как «элемент с копируемым источником» (source item), т. е. значение этого элемента в каждой подсоединенной к набору записи-члене в точ- ности соответствует его значению в записи-владельце. Синтаксис КЯОД, определяющий данную возможность (с. 3.53), имеет вид: (ACTUAL ) > AND SOURCE IS ид-данных-l OF OWNER OF имя-набора-1 VIRTUAL ------- Если элемент-копия определен как ACTUAL (РЕАЛЬНЫЙ, ФАК- ТИЧЕСКИЙ), то значение этого элемента помещается в запись-член в момент включения ее в набор (возможно, при помещении ее в базу данных). Точнее, при выполнении оператора STORE или CONNECT производится обращение к записи-владельцу и копия значения ука- занного элемента переносится из записи-владельца в запись-член. Желательно (но совсем не обязательно), чтобы доступ к записи-владель- цу занимал не слишком много времени. В «Журнале развития Кобо- ла» не требовалось специфицировать синтаксис данной возможности, но необходимо было на нее сослаться. Подобные элементы в журнале развития называются (с. IV—1—5) «производными», так как их зна- чения возникают в процессе работы резидентного модуля СУБД. При этом не делается различия между описанными здесь элементами-ко- пиями и элементами-результатами, которые будут рассматриваться в гл. 10. Если элемент-копия определен как VIRTUAL (ВИРТУАЛЬНЫЙ), то копирование значения из записи-владельца в запись-член проис- ходит не в момент помещения записи в базу данных, а при выборке ее оттуда. В предыдущих главах уже упоминался один из основных ЯМД-операторов FIND. Перенос значения элемента-копии осуществ- ляется в процессе выполнения оператора GET, а не оператора FIND. Позднее эта ситуация будет рассмотрена более подробно. Элементы-копии обеспечивают согласование между различными записями и, кроме того, позволяют управлять соотношением расхо- дуемой памяти и времени. Если какой-либо элемент (простой или груп- повой) в некотором типе записи совпадет с элементом в другом типе записи и если между этими двумя типами записи устанавливается от- ношение типа набора, то разумно определить соответствующий элемент 98
записи-члена как элемент-копию, особенно в тех случаях, когда его значение зависит от алгоритма включения записи-члена в набор. Для выяснения возможных последствий такого определения рас- смотрим ситуацию, возникающую в процессе обработки записей. Ес- ли при обработке записей-членов вся запись-владелец должна присут- ствовать в оперативной памяти, то использование элементов-копий становится бессмысленным, независимо от того, имеется в виду раз- мещение только в оперативной памяти (виртуальный элемент-копия) или также и во внешней памяти прямого доступа (реальный элемент- копия). Если же в процессе обработки требуется лишь указанный элемент, а не все элементы записи-владельца, то можно сэкономить оператив- ную память, определив его как элемент-копию в записи-члене. В тех случаях, когда необходимо применять большие наборы и, кроме того, желательно экономить внешнюю память, данный элемент лучше спе- цифицировать как виртуальную копию, хотя следует помнить, что это связано с обращением к записи-владельцу. Определение рассмат- риваемого элемента как реальной копии позволяет сократить время обработки за счет дополнительного расхода внешней памяти. Естественно предположить, что реальные элементы-копии будут применяться гораздо реже, чем виртуальные. Программисту, кстати, совсем не обязательно знать, обрабатывает ли он «нормальный» эле- мент или элемент-копию. И даже если он знает об этом, то единствен- ное, что он может сделать, — по возможности избегать выборки вир- туальных элементов-копий. 9.8. ПРОВЕРКА ДОСТОВЕРНОСТИ ЭЛЕМЕНТОВ Машинно-обрабатываемые файлы данных уже давно подвергаются критике за отсутствие контроля правильности помещаемой в них ин- формации. С появлением интегрированных баз данных решение этой проблемы стало возможным. Комитеты по спецификациям и разработ- чики систем должны разрешить администратору данных формулиро- вать критерий правильности значений элементов данных, который бу- дет проверяться каждый раз перед помещением указанных значений в базу данных. В спецификациях РГБД для этих целей имеется предложение CHECK (ПРОВЕРКА), сокращенный синтаксис которого игмеет вид (с. 92): PICTURE CHECK IS --------- ----- BANGE OF литерал-8 THRU литерал-9 Комитет ЯОД заменил его следующим (g. 3.30): t CHECK IS PICTURE VALUE |NOT] 4* литерал-l [THRU литерал-2] [, литерал-3 [THRU литерал-4]].•• 99
Смысл варианта CHECK IS PICTURE (ПРОВЕРКА ПО ШАБЛО- НУ) совсем не так очевиден, как это может показаться на первый взгляд. Для его выяснения необходимо прежде всего рассмотреть од- но важное свойство подсхем, которое практически пока нигде не реа- лизовано, а именно возможность определения в подсхеме элементов, отличных по типу от соответствующих элементов схемы. Во время вы- полнения программы для такого элемента производится преобразова- ние типа в одном из двух «направлений» в зависимости от того, сохра- няется или выбирается значение этого элемента. Если же для некото- рого элемента определяется CHECK IS PICTURE, то указанное выше преобразование не осуществляется. Это свойство является несколько необычным. Фактически лицу, определяющему схему, предоставляется контроль над возможными спецификациями подсхемы. Если в схеме указано CHECK IS PICTU- RE, то бесполезно переопределять тип элемента в подсхеме, хотя ха- рактеристики элемента здесь могут представлять собой подмножество его же характеристик в схеме. «Характеристиками» называют свойст- ва элемента, определяемые предложениями TYPE и PICTURE. Вариант RANGE (ДИАПАЗОН) или, по спецификациям КЯОД, CHECK IS VALUE (ПРОВЕРКА ЗНАЧЕНИЯ) более явно связан с контролем значений элемента. При этом вариант КЯОД, очевидно, совершеннее варианта РГБД, так как он позволяет администратору данных указывать либо множество значений, либо множество их диа-., пазонов, либо и то и другое. Например, CHECK IS VALUE 3 THRU 10, 15, 20 THRU 30 или CHECK IS VALUE NOT 5, 10, 15, 20. 9.9. ПОДСТАТЬЯ ЭЛЕМЕНТА ДАННЫХ Обратимся вновь к гл. 4, содержащей общее описание типов запи- си, и в частности к параграфу 4.9, в котором приводится синтаксис определения типа записи. Тип записи нельзя считать полностью спе- цифицированным, пока не определен хотя бы один принадлежащий ему элемент. Полное описание типа записи должно по РГБД соответ- ствовать так называемой «структуре статьи записи». Последняя сос- тоит из подстатьи записи (см. параграф 4.9) и подстатьи данных, кото- рая может повторяться несколько раз. Вообще говоря, синтаксис РГБД (с. 90) допускает определение типов записи без элементов данных, но здесь либо имеется ошибка, либо речь идет о каком-то специальном использовании13. Итак» рассмотренный в настоящей главе синтаксис подстатьи дан- ных имеет вид: 100
(номер-уровня) имя-данных-1 ; PICTURE IS ''спецификация-шаблопнм-лптАппон-строки'' спецификация-числимым’шелоном TYPE IS (BINARY 1 (DECIMAL) (FIXED ) (FLOAT) REAL 'j COMPLEX J [целое-1 [, целое-2]] I (BIT | (CHARACTER | 1целое'31 data-base-key имя-разработчика t OCCURS |целое'4 1 TIMES ----------- (ид-данных-l J (ACTUAL ) AND SOURCE IS ид-данных-41 ; IS --------- I -------------- VIRTUAL) OF OWNER OF имя-набора-4 ;CHECK IS PICTURE VALUE [NOT] литерал-1 [THRU литерал-2] [, литерал-3 [THRU литерал-4J]... Как и в ПЛ/1, номер уровня является необязательным, но если он применяется, то должен быть целым числом в промежутке от 1 до 99 включительно. Подстатья данных включает одно из следующих возможных пред- ложений: 1. PICTURE 2. TYPE 3. SOURCE 4. OCCURS 5. OCCURS и PICTURE 6. OCCURS и TYPE Простой элемент данных определяется предложениями 1, 2 пли 3, вектор — предложениями 5 или 6, повторяющаяся группа — пред- ложением 4 (но напомним, что компоненты повторяющейся группы мо- гут быть, в свою очередь, повторяющимися группами). «Агрегат дан- ных» по терминологии ПЛ/1 есть либо вектор, либо повторяющаяся группа, т. е. элемент, в подстатье данных которого содержится пред- ложение OCCURS. 101
ело примеры Приведенные здесь примеры иллюстрируют практическое применение внут- ренней структуры записи, а не специфику описаний ПЛ/1, отсутствующую в конкретных коммерческих системах. П р и м е р 1 примере 1 разд. 5.10.1 представлено определение типа набора, показан- ного на рис. 5.1. Если администратор данных предпочитает вместо «внеш- ней» набор ной структуры использовать внутреннюю структуру записи, то это \.ожно сделать с помощью следующей статьи записи: R ECORD NAME IS СЛУЖАЩИЙ; i OCATION MODE IS CALC USING НОМЕР-СЛУЖ; WITHIN ОБЛАСТЬ-1. 02 НОМЕР-СЛУЖ; PICTURE IS 9 (8). 02 ФА2МИЛИЯ-СЛУЖ; PICTURE IS A (14). 02 ДАТА-РОЖДЕНИЯ; PICTURE IS 9 (6). 02 ЧИСЛО-СПЕЦ; TYPE IS DECIMAL FIXED. 02 ОБРАЗОВАНИЕ; OCCURS ЧИСЛО-СПЕЦ TIMES. 03 СПЕЦИАЛЬНОСТЬ; PICTURE IS X(5); CHECK IS VALUE Б. К. Н.» Б. H., М.К.Н.,. M.H.. Д.Ф., Б. И., M. И., Б. Б. 03 ДАТА-ЗАВЕРШ; PICTURE IS 9(6); CHECK IS VALUE 200101 THRU 760101. 03 УЧЕБНОЕ-ЗАВЕД; PICTURE IS X (14). Пример 2 Теперь представим предыдущий пример в виде типа набора (как в разд. 5.10.1), но при этом повторим элемент НОМЕР-СЛУЖ записи СЛУЖА- ЩИЙ в записи ОБРАЗОВАНИЕ: RECORD NAME IS СЛУЖАЩИЙ; LOCATION MODE IS CALC USING НОМЕР-СЛУЖ; WITHIN ОБЛАСТЬ-1. 02 НОМЕР-СЛУЖ; PICTURE IS 9 (8). 02 ФАМИЛИЯ-СЛУЖ; PICTURE IS A (14). 02 ДАТА-РОЖДЕНИЯ; PICTURE IS 9 (6). RECORD NAME IS ОБРАЗОВАНИЕ; LOCATION MODE IS VIA SET CO; WITHIN ОБЛАСТЬ-1. 02 НОМЕР-СЛУЖ; IS ACTUAL AND SOURCE IS НОМЕР-СЛУЖ OF OV'NER OF CO. 02 СПЕЦИАЛЬНОСТЬ; PICTURE IS X (5). 02 ДАТА-ЗАВЕРШ; PICTURE IS 9 (6). 02 УЧЕБНОЕ-ЗАВЕД; PICTURE IS X (14). SET NAME IS CO; MODE IS POINTER ARRAY; OWNER IS СЛУЖАЩИЙ; ORDER IS PERMANENT INSERTION IS LAST. MEMB ER IS ОБРАЗОВАНИЕ. ГЛАВА 10 ДОПОЛНИТЕЛЬНЫЕ возможности АДМ ИНН СТРАТО Р А ДА Н Н Ы X 10.1. ВВЕДЕНИЕ В предыдущих главах мы рассмотрели наиболее распространенные концепции ЯОД схемы. Большинство из них нашло применение в тех или иных конкретных системах. Однако это не означает, что исчерпа- ны все возможности, определенные (а в некоторых случаях только за- 102
думанные) в предложениях РГБД и КЯОД. В данной главе будут тп- ложены некоторые новые идеи, многие из которых еще нигде не ped - лизованы (а возможно, никогда и не будут реализованы). 10.2. КЛАССИФИКАЦИЯ ВОЗМОЖНОСТЕЙ ЯОД СХЕМЫ В начале гл. 8 была введена классификация возможностей ЯОД схемы, разделяющая их на четыре категории; 1) структурные; 2) облегчающие доступ; 3) представления в памяти; . 4) управляющие семантикой операторов ЯМД. Все рассмотренные выше свойства ЯОД схемы можно следующим об- разом распределить по этим категориям: 1) тип записи, элемент данных; 2) тип набора, поисковый ключ, способ размещения (CALC); 3) способ размещения (кроме CALC), область, предложение WI- THIN, вид представления набора, упорядоченность набора, элемент- копия; 4) допустимость исключения, способ включения, выбор набора, предложение CHECK- Приведенная здесь классификация может быть критически воспри- нята некоторыми членами РГБД и КЯОД, по мнению которых тип на- бора является структурным свойством и представляет некоторую взаимосвязь в реальном мире. С этим утверждением нельзя не согла- ситься, однако напомним (см. параграф 5.1), что администратор дан- ных принимает решение о представлении той или иной существующей в реальном мире связи в виде типа набора ЯОД схемы на основании критерия эффективности выполнения прикладных программ. Имеется еще одна более узкая классификация определений ЯОД схемы, значение которой станет ясным при рассмотрении оператороз ЯМД. Эта вторая классификация никак не связана с первой и распре- деляет предложения ЯОД схемы в зависимости от «степени участия программиста». Соответственно определения делятся на те, которые программист должен знать; не обязан знать, но которыми он может воспользоваться, если зна- ет их; не обязан знать и которые он не может использовать, даже если их знает. Очевидно что большинство из перечисленных выше тринадцати свойств ЯОД схемы попадают в первую категорию, три свойства — поисковый ключ, вид представления набора и его упорядоченность -г во вторую, но ни одно из рассмотренных до сих пор свойств не относит- ся к третьей категории. Роль этой последней выяснится после обсуж- дения средств ЯУВН в гл. 19. В нее можно будет также включить не- которые редко реализуемые возможности, указанные ниж.е. юз
10.3. ПРОЦЕДУРЫ БАЗЫ ДАННЫХ Многие из редко реализуемых средств зависят от процедур базы данных. Процедура базы данных пишется администратором данных на каком-либо языке программирования и автоматически вызывается в процессе выполнения прикладной программы при возникновении не- которой ситуации, указанной в схеме. В каком-то смысле всякая процедура базы данных является проце- дурным определением (или дополнением) семантики выполнения ЯМД- операторов со стороны администратора данных. Большинство пользо- вателей Кобола знакомо с концепцией деклараций USE (ИСПОЛЬЗО- ВАТЬ). В ПЛ/1 аналогичная возможность предоставляется операто- ром ON (ПРИ). Однако и в Коболе, и в ПЛ/1 эта возможность «одно- уровневая» по отношению к применяющему ее лицу. Программист сам определяет процедуры и ситуации, при которых они должны вызывать- ся в процессе выполнения его программы. Это замечательное средство редко используется из-за сложной и дорогостоящей реализации. Оно, очевидно, требует внесения измене- ний в компилятор включающего языка, а возможно, и в операционную систему. Теперь перейдем к рассмотрению некоторых способов применения процедур базы данных. 104. ПРЕДЛОЖЕНИЕ ON (ПРИ) В отчете РГБД предложение ON присутствует на уровнях: облас- ти, типа записи, элемента данных и типа набора. Комитет ЯОД ввел также возможность применения этого предло- жения на уровне схемы и, что более важно, уточнил и расширил его использование на других уровнях. Для иллюстрации изложенного покажем применение предложения ON на уровне элемента данных, которое в отчете КЯОД (с. 3.3.6) име- ет вид: STORE GET MODIFY ONfERROR DURING] CALL имя-процедуры-1 Мы уже в некоторой степени знакомы с оператором STORE, поэто-1 му теперь можем рассмотреть пример: ON STORE CALL КОНТПРОЦ Это означает, что непосредственно после выполнения оператора 1 STORE (перед выполнением оператора, следующего за STORE в про- грамме на включающем языке с ЯМД) управление будет передано про- цедуре КОНТРПРОЦ, которая сделает все, что ей предписано делать. По завершении выполнения КОНТПРОЦ управление вернется к опе- ратору, следующему за STORE. Программист не может отказаться от выполнения процедуры КОНТПРОЦ, если ему требуется выполнять операторы STORE, а без них нельзя загрузить данные в базу данных. 104
Как развитие предложения ON КЯОД ввел вариант ON ERROR DURING (ПРИ ОШИБКЕ ВО ВРЕМЯ). Если наш пример изменить: ON ERROR DURING STORE CALL КОНТПРОЦ, то процедура КОНТПРОЦ будет вызываться только при появлении ошибок в процессе выполнения оператора STORE, а не после завер- шения его выполнения. (Далее мы увидим, что РГБД и РГЯБД сос- тавили достаточно полный список возможных ошибок.) Предложения ON для областей, типов записи и типов набора не отличаются существенно от рассмотренного выше варианта для эле- ментов данных. По чисто формальным причинам КЯОД несколько из- менил представленный РГБД вариант ON для типа записи. Следует помнить, что эти предложения на каждом из уровней, т. е. области, типа записи, элемента или типа набора, влияют на выполнение опе- раторов ЯМД, относящихся и к другим уровням. 10.5. ПРОЦЕДУРНО УПРАВЛЯЕМОЕ РАЗМЕЩЕНИЕ В ПАМЯТИ Язык описания данных схемы является определяющим (или декла- ративным). Это непроцедурный язык, который специфицирует, должно делаться, а не каким образом что-то должно делаться . Рассмот- рим в качестве примера предложение WITHIN область-1 [{, область-2... REALM-ID IS имя-данных-2] из разд. 4.8.1. Оно определяет, что записи данного типа должны раз- мещаться в одной или нескольких указанных областях, но не уточня- ет, как они будут размещаться. Решение оставляется на усмотрение разработчика или программиста, помещающего записи в базу дан- ных. Комитет ЯОД выдвинул идею, что администратор данных при же- лании может контролировать размещение записей по областям, для чего ему предоставляется возможность определять и вызывать соот- ветствующую процедуру базы данных. В связи с этим синтаксис предложения WITHIN модифицирован следующим образом: WITHIN область-1 [ {,область-2} ...[REALM-ID IS имя-данных-2 [USING PROCEDURE имя-проц-2]] т. е. добавлен вариант использования процедуры базы данных. Другой вариант использования процедур базы данных уже обсуж- дался (см. разд. 4.5.3) при рассмотрении способа размещения CALC. К вопросам размещения в памяти относится и определение поиско- вого ключа (см. параграф 6.10). Теперь два непроцедурных варианта CALC и INDEX дополняются процедурным: SEARCH KEY IS ид-данных-1 [, ид-данных-2]„ Г fCALC П USING INDEX PROCEDURE имя-проц-1 105
Определив возможность процедурного распределения записей по областям, КЯОД мог бы пойти еще дальше и включить процедурный вариант для упорядочения набора. Однако он этого не сделал, хотя администратору данных легче написать процедуру, осуществляющую включение записи в набор, чем процедурно размещать запись в опре- деленной области. Здесь предполагается, что при написании процедур базы данных может применяться включающий язык программирова- ния и ЯМД. 10.6. ПРОЦЕДУРЫ БАЗЫ ДАННЫХ НА УРОВН Е ЭЛЕМЕНТОВ ДАННЫХ На уровне элементов процедуры базы данных могут применяться в трех случаях, один из которых связан с расширением уже рассмот- ренного в предыдущей главе предложения, а два других — с предло- жениями, которые еще не обсуждались. 10.6.1. Предложение CHECK (ПРОВЕРКА) Полный синтаксис предложения CHECK имеет вид: PICTURE CHECK IS ™я-пР°^УР“-1 ------VALUE [NOT] литерал-1 [THRU литерал-2] [, литерал-3 [THRU литерал-4]]... Все варианты, кроме процедурного, уже встречались в параграфе 9.8. Процедура базы данных дает администратору данных возможность осуществлять «комплексную» проверку значений элементов, т. е. до- стоверность их комбинации в записи. Возможности проверки с помо- щью процедуры базы данных этим не ограничиваются, так как адми- нистратор данных может включить в нее любые вычисления или про- цессы обработки информации. 10.6.2. Элементы-результаты (RESULT) Чтобы лучше уяснить концепцию элементов-результатов, следует вспомнить элементы-копии (см. параграф 9.7), с которыми они имеют много обид его. Различие их заключается в том, что элемент-копия оп- ределяется как элемент типа записи-члена, а элемент-результат — как элемент типа записи-владельца. Значение элемента-результата вычисляется по значениям, размещенным в записях-членах, и помеща- ется (в некоторый момент выполнения программы) в запись-владель- ца. Для этих элементов также предусмотрены реальный и виртуаль- ный варианты, определяющие, когда нужно выполнять вычисления и соответственно помещать значение в запись-владельца. Напомним чи- тателю, что в «Журнале развития Кобола» виртуальные и реальные элементы называются производными (с. IV—2—5). 106
При использовании элементов-результатов возникают некоторые осложнения, связанные с выбором области определения вычислений, заданных в процедуре базы данных. В самой идее такой возможности подразумевается что-то вроде вычисления суммы или аналогичной функции на множестве значений элементов записей-членов, хотя это явно и не оговорено правилами. Для применяемой здесь процедуры базы данных можно выбрать одну из следующих областей определения вычислений: 1. Экземпляр записи, в котором размещается элемент-результат. 2. Все записи, связанные с экземпляром записи, я котором разме- щается элемент -результат (они могут соединяться с этим экземпляром через различные типы набора). 3. Все записи, связанные с экземпляром записи, в котором раз- мещается элемент-результат (они могут быть различного типа, но долж- ны принадлежать одному типу набора). Синтаксис КЯОД в этом случае имеет вид: (ACTUAL 1 IS jVIRTUAL( RESULT OF имя-процедуры-1 ON THIS RECORD ON ALL MEMBERS OF имя-пабора-1 [, имя-набора-2]... ON имя-записи-l [, имя-записи-2]... OF имя-набора-3 rUSING ид-дан- ных- 1 (, ид-данных-2ф. J Напомним, что параллельные вертикальные линии позволяют вы- брать любой вариант или любую комбинацию вариантов, в частности все варианты, в любой последовательности. Элементы-результаты открывают широкие возможности. Рассмот- рим относительно несложный пример применения элемента-результата в банковской системе для представления в записи ОТДЕЛЕНИЕ сум- мы значений элемента ТЕКУЩИЙ-СЧЕТ записей КЛИЕНТ. Если мы определим ОБЩИЙ-БАЛАНС IS VIRTUAL RESULT OF ВЫЧИСЛ-БАЛАНСА USING ТЕКУЩИЙ-СЧЕТ OF КЛИЕНТ то значение ОБЩИЙ-БАЛАНС будет подсчитываться с помощью про цедуры ВЫЧИСЛ-БАЛАНСА всякий раз, когда запись ОТДЕЛЕ- НИЕ выбирается из базы данных. Фразы ON не разрешается исполь- зовать в варианте VIRTUAL. Если администратор данных предпочитает постоянно поддержи- вать значение общего баланса, то он может определить: ОБЩИЙ-БАЛАНС IS ACTUAL RESULT OF КОРРЕКЦИЯ-БАЛАНCA ON THIS RECORD ON КЛИЕНТ OF ОТД-КЛИЕНТ USING ОБЩИЙ-БАЛАНС OF ОТДЕЛЕНИЕ, ТЕКУЩИЙ-СЧЕТ OF КЛИЕНТ 107
Конечный результат этого определения тот же самый, но достига- ется он другим методом. Значение общего баланса корректируется с помощью процедуры КОРРЕКЦИИ-БАЛАНСА каждый раз, когда изменяется значение элемента ТЕКУЩИЙ-СЧЕТ какой-либо записи КЛИЕНТ, или при исключении (включении) записи КЛИЕНТ, из набо- ра, владельцем которого является запись ОТДЕЛЕНИЕ. Процедура КОРРЕКЦИИ-БАЛАНСА существенно отличается от процедуры ВЬЕ ЧИСЛ-БАЛАЕ1СА в предыдущем примере. Заметим также, что мы спе- циально использовали здесь сам определяемый элемент-результат в качестве одного из параметров процедуры. Квалификация в стиле Ко- бола имен элементов являлась в принципе необязательной и применя- лась для элементов, указанных после USING, только для большей наглядности. 10.6.3. Предложение ENCODING / DECODING (КОДИРОВАНИЕ / ДЕКОДИРОВАНИЕ) Этот вариант связан с преобразованием между схемным и подсхем- ным представлениями элементов данных. Он вводится по определению РГБД (с. 102) «для указания процедуры, которая должна выполнять- ся в случаях выборки или модификации элемента данных, требую- щего специального преобразования представления». Синтаксис предложения ENCODING/DECODING имеет вид: [ENCODING 1 FOR < } [ALWAYS] CALL имя-проце дуры-1 . DECODING !-------J --- 1 Процедура ENCODING вызывается при выполнении оператора STORE или MODIFY, а процедура DECODING—при выполнении GET. Рассматриваемый вариант нигде не реализован, поскольку разра- ботчики в основном стараются избегать каких-либо преобразований представления в процессе выполнения прикладной программы, что еще будет обсуждаться при изучении подсхем. Кроме того, немаловаж- ную роль здесь играет наличие процедур базы данных. На практике указанные процедуры можно было бы использовать для упаковки значений элементов при помещении их в базу данных и для распаковки при выборке. Пока еще не вполне ясно, будет ли это соответствовать назначению обсуждаемого варианта, который призван заменить стандартное преобразование представления, предусматри- ваемое в случае несовпадения характеристик элемента в схеме и под- схеме (си. разд. 12.6.3). Если в предложение включено необязательное слово ALWAYS (ВСЕГДА), то преобразование выполняется в любом случае. Если же это слово отсутствует, то преобразование выполняет- ся лишь при различающихся характеристиках представления элемен- та. 108
Г Л А В A 11 СИНТАКСИС ЯОД СХЕМЫ 11.1. ВВЕДЕНИЕ Выше мы более или менее подробно рассмотрели все предложения, выдвинутые РГБД и КЯОД. Широко распространенные и, следова- тельно, особо важные концепции были представлены полнее, чем ре- ализуемые редко. Единственный вопрос, который еще не затрагивал- ся,—об управлении доступом (обеспечении секретности) — специ- ально вынесен в одну из последующих глав. Настоящая глава имеет целью собрать воедино фрагменты синтак- сиса, представленные в гл. 2—9, и показать его «структуру». Один из наиболее быстрых способов ознакомиться с возможностями конкрет- ной системы — это рассмотреть структуру ее синтаксиса. Читатель заметит, что представленная в данной книге структура не копирует предложения какого-либо комитета или конкретной разработки. Она ближе всего к предложениям КЯОД, но содержит некоторые, элементы из «Журнала развития Кобола» (например , realm вместо area для обозначения области) и сохраняет предложение РГБД о виде представ- ления набора. 11.2. ОБЩАЯ СТРУКТУРА СИНТАКСИСА Общая структура синтаксиса ЯОД состоит из следующ их четырех статей: статьи схемы, статьи области, статьи записи и статьи наборт В каждой схеме базы данных должны присутствовать статьи схе- мы, области и записи. Статья набора является необязательной. На- помним, что две из перечисленных статей имеют подстатьиТаким сб- разом, «общий» синтаксис ЯОД схемы можно представить в виде: статья схемы » {статья области}... {подстатья записи {подстатья данных}13 ...}... [подстатья набора {подстатья члена} ... ] ... Это обзорное представление не содержится в отчетах РГБД и КЯОД, хотя «Журнал развития Кобола» предусматривает нечто аналогичное для подсхемы последнего. Что касается необязательности статьи на- бора, то она имеет чисто теоретическое значение, так как полноценное использование ЯОД схемы, как правило, предполагает ее пр именение. 11.3. СТАТЬЯ СХЕМЫ Статья схемы здесь пока еще не рассматривалась. Пользователи Кобола могут заметить концептуальную аналогию этой статьи с раз- делом идентификации. Она невелика и состоит из одного предложения: SCHEMA NAME IS имя-схемы-1 109
Следует отметить, что в конкретной установке некоторой системы может содержаться несколько «известных СУБД» схем. Каждая из них, очевидно, должна иметь имя, отличное от других имен схем. Н.4. СТАТЬЯ ОБЛАСТИ Статья области уже частично обсуждалась в разд. 4.8.1. Синтак- сически определение области и указание о том, является ли она по- стоянной или временной, не представляет трудностей. Для каждой области администратор данных должен написать предложение: REALM NAME IS имя-области-1 [REALM IS TEMPORARY] Как и схема, любая область базы данных должна иметь имя, от- личное от имен других областей в той же базе данных. При использо- вании нескольких баз данных не предусматривается возможность ква- лификации имени области именем схемы. Поэтому на практике поль- зователь может обнаружить, что область эквивалента файлу операци- онной системы, т. е. в конкретной установке системы каждая область будет иметь индивидуальное имя. Несмотря на то что представленный синтаксис довольно прост, определение числа применяемых областей, их размеров и характерис- тик представляет собой серьезную проблему. При ее решении адми- нистратор данных может воспользоваться дополнительными возмож- ностями Я УВН (они будут рассматриваться в одной из следующих глав) для обеспечения максимальной общей эффективности системы. 11.5. СТАТЬЯ ЗАПИСИ Отдельные фрагменты статьи записи рассматривались в данной книге неоднократно. Для уточнения важных понятий размещения записей в памяти и их внутренней структуры читатель может вновь обратиться соответственно к гл. 4 и 9. Полный синтаксис статьи записи выглядит следующим образом: RECORD NAME IS имя-записи-l; LOCATION MODE IS f имя-данных-1 T —DIRECT 4 > V ид-данных-l J CALC [имя-проц-l] USING ид-данных-2 [, ид-данных-3]... DUPLICATES ARE [NOT] ALLOWED i ; У1Аимя-набора-1 SET SYSTEM [имя-области-1 [{, имя-области-2)... REALM-ID IS имя-данных-2] WITHIN L --------(REALM OF OWNER 110
[ н омег -у ровня] и и я - дан н ы х-3 ( «спейификauия-литеоиым-шаблоном »’ ; PICTURE IS 4 4 —------ ( с пен; J (p и к ац и я -ч и с лов ым -ш а б лоном ( BINARY ) [целое-1 [, целое-2]] • TYPE IS | .----- ? [BIT У CHARACTER! !целое‘31 DA1A-BASE-KEY нмя-разрабстчика целое-4 ид-данных-1 f ACTUAL) ’ IS {VIRTUAL j SOURCE IS ид-данных-4 OF OWNER OF имя-набора-4] ; CHECK IS PICTURE VALUE [NOT] литерал-l [THRU литерал-2) [, литерал-3 [THRU литерал-4]] ... Здесь не показана возможность определения комплексных (COM- PLEX) элементов данных. Кроме того, некоторые из перечисленных выше вариантов могут не встречаться в конкретных системах. 1L6. СТАТЬЯ НАБОРА Вопросы, связанные с типом набора, были рассмотрены гораздо подробнее многих других аспектов ЯОД схемы. Основные концепции, относящиеся к представленному ниже синтаксису, читатель может найти в гл. 5, 6, 7 и 8. Для полноты изложения мы сохранили здесь предложенный РГБД вариант определения вида представления набо- ра. SET NAME IS имя-набора-l; тгл f имя-записи-l 'I 1S [ SYSTEM } ’ (CHAIN (LINKED TO PRIORI SET MODE IS /------ ---------------- ------ [POINTER-ARRAY ORDER IS PERMANENT INSERTION IS
FIRST LAST NEXT PRIOR IMMATERIAL SORTED INDEXED [NAME IS имя-индекса-1] BY DA TA-BASE-KEY~ BY RECORD-NAME WITHIN RECORD-NAME rFIRSTl BY DEFINED KEYS [DUPLICATES ARE LAST ALLOWED] NOT (AUTOMATIC) (MANDATORY) MEMBER .S «-.пи»-. мдмиль (LINKED TO OWNER] (ASCENDING] ; W”-CE| K-S 's descend.no Г ASCENDING 1 DESCENDING |:д-даниых-4] [; SEARCH KEY IS ид-данных-5 [, ид-данных-6] .... ( CALC ) USING jINDEX [NAME IS имя-индекса-1] У DUPLICATES ARE [NOT] ALLOWED] ... ; SET SELECTION IS THRU имя-набора-l OWNER IDENTIFIED SYSTEM CURRENT OF SET [f ид-данных-1 *) I EQUAL TO < И . V имя-данн ых-l J J гмг T/cv Гплтглт -ггт ( ид-данных-2 ) Г, ид-данных-3 ] 1 CALC-KEY EQUAL TO < л УI л ••• ------[ имя-данных-2 J [, имя-данных-3 J J MEMBER имя-записи-l SELECTION [THEN THRU имя-набора-3 JwiIERE OWNER IDENTIFIED BY ид-данных-4 ^EQUAL TO {ид-данных-5 TTY 1 14 имя-данных-4 JJj* J *** r 112
117. ЗАКЛЮЧЕНИЕ Представленная выше структура синтаксиса отражает те варианты, которые пользователь может встретить в конкретных системах, а не те, которые ему рекомендуется использовать. Какой из них выбрать и при каких обстоятельствах — это основная проблема проектиро- вания баз данных, заслуживающая отдельного рассмотрения. ГЛАВА 12 ПОДСХЕМЫ 12.1 ВВЕДЕНИЕ В предыдущих главах мы настолько часто обращались к понятию подсхемы, что читатель, уже имеет о ней представление и знаком с ме- тодами ее использования. В функционально полной СУБД, основан- ной на предложениях КОДАСИЛ, ЯОД подсхемы является компонен- той, которая должна поставляться разработчиком и соответственно использоватьсй администратором данных. В основном ЯОД подсхемы предназначен для определения под- структуры схемы базы данных. А так как ЯОД схемы применяется для спецификации областей, типов записи, элементов данных и типов на- бора, ЯОД подсхемы можно использовать для выделенця некоторых из этих элементов схемы, соответствующих той части базы данных, в которой должна работать одна или несколько прикладных программ. 12.2. СВЯЗЬ С ВКЛЮЧАЮЩИМ ЯЗЫКОМ Комитеты КОДАСИЛ указывали, что ЯОД подсхемы в каком-то смысле «принадлежит» соответствующему процедурному языку, на- пример Коболу. Таким образом, можно говорить о ЯОД подсхемы Ко- бола или Фортрана. Напомним, однако, что для каждого процедурно- го языка имеется соответствующий компилятор и что транслятор опе- раторов ЯОД подсхемы не является частью этого компилятора. Та- кой транслятор является самостоятельной компонентой СУБД и, как правило, должен применяться для трансляции подсхемы до компиля- ции использующих ее программ. Зависимость ЯОД подсхемы от процедурного языка проявляется в том, что он отражает внутреннюю структуру записи последнего. Это позволяет разрабатывать СУБД, поддерживающие как Кобол, так и ПЛ/1 с соответствующими трансляторами ЯОД подсхем, причем трансляторы будут отличаться лишь в той части ЯОД подсхемы, кото- рая относится к внутренней структуре записи. Как уже отмечалось, существующие системы не поддерживают ПЛ/115 и ЯОД схемы в них не отражает внутренней структуры записи этого языка. Однако, имея СУБД, работающую в Коболом, т. е. под- держивающую внутреннюю структуру его записи в ЯОД схемы и под- схемы, нетрудно расширить ее для работы с ПЛ/1, ограниченной внут- ренней структурой записи Кобола. 113
Изложение в данной главе и в главах, посвященных операторам ЯМД, основано на спецификациях «Журнала развития Кобола» КО- ДАСИЛ, изданного в 1976 г. Эти спецификации были разработаны РГЯБД и опубликованы еще в 1973 г. После традиционного обсужде- ния и внесения соответствующих изменений предложения РГЯБД получили официальное одобрение Комитета по языку программирова- ния КОДАСИЛ и вошли в указанный журнал развития. Некоторые из широко распространенных систем, использующих предложения КОДАСИЛ, все еще применяют терминологию РГБД 1971 г. Поэтому мы будем придерживаться представления РГЯБД, обращаясь к работам РГБД лишь при наличии существенных расхож- дений. В любом случае наше представление ориентируется только на Кобол. 12.3. ОПРЕДЕЛЕНИЕ ПОДСХЕМЫ В разд. 2.4.1 мы уже отмечали, что РГБД не дала однозначного указания о том, кто должен использовать ЯОД подсхемы. В отчете РГБД 1971 г. записано, что за определение подсхем может нести от- ветственность администратор данных. Однако будет ли он действи- тельно этим заниматься в обстановке конкретно эксплуатируемой системы — зависит, по-видимому, от решения вопроса о контроле до- ступа (подробности которого обсуждаются ниже). Если администра- тору данных требуется контролировать доступ к некоторым частям базы данных, то очевидно, что определение подсхем должно входить в его функции. Если же контроль доступа не является обязательным, то администратор данных может предоставить прикладным програм- мистам копии схемы и дать им возможность специфицировать свои собственные подсхемы. В этом случае появляется необходимость хра- нить последние в некоторой библиотеке подсхем, через которую адми- нистратор данных сможет контролировать их заведение и использо- вание. Как правило, каждая подсхема составляется в соответствии с нуж- дами какой-либо конкретной прикладной программы. И хотя подсхе- ма может использоваться несколькими прикладными программами, на практике их число обычно невелико. Одним из аргументов в поль- зу того, чтобы подсхема удовлетворяла требованиям конкретной про- граммы, является минимальный расход оперативной памяти. Вопро- сы, связанные с выделением оперативной памяти, рассматриваются в следующем параграфе. 12.4. РАБОЧИЕ ОБЛАСТИ ЗАПИСЕЙ (РАБОЧАЯ ОБЛАСТЬ ПОЛЬЗОВАТЕЛЯ) Каждый пользователь Кобола знает, что в разделе данных програм- мы должна быть определена секция рабочей памяти. С ее помощью в оперативной памяти резервируются области, в которые данные будут считываться из внешних файлов и, наоборот, помещаться в эти фай- лы. А так как формат типа записи в оперативной памяти по определе- нию совпадает с форматом записей во внешней памяти, в разделе дан- ных программы возможен излишний расход памяти и дублирование. 114
При обработке данных, расположенных в базе данных, а не в тра- диционных файлах, также требуется выделять в программе рабочую область оперативной памяти для размещения записей базы данных. РГБД решила освободить программиста от определения указанной области, сделав это определение неявным. Таким образом, специфика- ция с помощью ЯОД подсхемы Кобола типов записи и элементов под- схемы приводит к выделению в каждой использующей ее программе соответствующей рабочей области. Если применяется подсхема, содержащая типы записи или эле- менты данных, которые не обрабатываются данной программой, то в этом случае, очевидно, происходит излишнее выделение рабочей опе- ративной памяти. Пространство оперативной памяти, резервируемое во время вы- полнения программы для типов записи подсхемы, по предложению РГБД получило название рабочей области пользователя (РОП). В от чете РГБД (с. 20) дается следующее определение концепции рабочей области пользователя: «Рабочая область пользователя (РОП) по су- ществу есть зона загрузки и разгрузки, в которую передаются все дан ные, предоставляемые СУБД (т. е. резидентным модулем СУБД) в от- вет на запрос, и в которой размещаются все данные, предназначенные для передачи СУБД. РОП должна быть предусмотрена в каждой вы- полняемой программе. Данные в РОП программы не могут быть изме- нены иначе как при выполнении некоторых команд ЯМД или через процедуры включающего языка программы пользователя. Элементы РОП не обязательно должны быть смежными в оперативной памяти. Рабочая область пользователя размещается СУБД в соответствии с вызываемой подсхемой. Каждому элементу данных, включенному в подсхему, выделяется позиция в РОП, что позволяет программам об- ращаться к нему по имени, объявленному в подсхеме». Специально ли или по небрежности, но это объяснение было опу- щено в предложениях РГЯБД и тем самым из спецификаций оказал- ся исключенным термин «рабочая область пользователя». По-видимо- му, считалось достаточным существование в Коболе термина области записи. Определенную роль здесь, очевидно, сыграло и то, что идея РГБД о неявном определении рабочего пространства подсхемы, по мне- нию некоторых разработчиков, вводит слишком серьезные ограниче- ния. Термин «область записи» подчеркивает однозначное соответствие между типами записи подсхемы и резервируемым рабочим пространством оперативной памяти, тогда как понятие рабочая область пользователя подразумевает (а в этом иногда возникает необходимость) совокуп- ность всех областей записи выполняемой программы. 12.5. ПЕРЕОПРЕДЕЛЕНИЕ ИМЕН Один из необязательных разделов ЯОД подсхемы был назван РГБД секцией переименований и изменен РГЯБД на раздел отображения. РГЯБД ввела разделы в ЯОД подсхемы, чтобы он вы- глядел более естественным для пользователей Кобола. Раздел отобра- 115
жения содержит одну секцию, которая называется секцией псевдони- мов. Раздел отображения может использоваться в двух случаях. Преж- де всего, в нем переопределяются имена, допустимые во включающем языке, если в ЯОД схемы они таковыми не являются. Необходимость в этом не возникает для пользователей Кобола. Имена ЯОД схемы по определению составляются по тем же правилам, что и имена Кобола, и поэтому пользователю ЯОД подсхемы Кобола вряд ли понадобится секция псевдонимов для переопределения недопустимых имен. С другой стороны, данная секция может понадобиться при ре- шении проблемы зарезервированных слов. К сожалению, РГБД заимст- вовала из Кобола идею зарезервированных слов для ЯОД схемы. Это означает, что администратор данных не должен выбирать для типов записи, элементов и типов набора такие имена, как AREA, ERROR, INDEX, KEY, LOCATION, MEMBER, MODE, NAME, OWNER, RANGE, RECORD, RESULT, SE LECTION, SOUR- CE, STORE, SYSTEM, TIMES. Здесь перечислены не все зарезервированные слова, а лишь наиболее «подходящие» в качество имен. Если же обратиться к списку зарезервированных слов Кобола, то окажется, что администратор данных, который определил в ЯОД схе- мы имена ALTERNATE, AUTHOR, BLANK, CODE, CONFIGURATION, CONTROL, COPY, COUNT, DATA, DATE, DAY, DEPTH, DETAIL, DISPLAY, DIVISION, ENVIRONMENT, GROUP, INSTALLATION, LABEL, LIMIT, LINE, MESSAGE, PAGE, POSITION, REPORT, SUPERVISOR, TABLE, TEXT вынужден будет воспользоваться секцией псевдонимов, так как эги имена не должны применяться в Кобол-программах. 12.6. ПРЕОБРАЗОВАНИЯ МЕЖДУ СХЕМОЙ И ПОДСХЕМОЙ В параграфах 9.2 и разд. 10.6.3 уже указывалось, что РГБД вы’ двинула идею преобразования представления записи схемы в пред- ставление записи подсхемы (и наоборот) в процессе выполнения про- граммы. Для конкретизации рассуждений мы будем говорить о пред- ставлении типа записи в базе данных и о представлении того же типа записи в прикладной программе. В отчетах КОДАСИЛ в таких слу- чаях обычно речь идет о записи схемы и записи подсхемы. В кон- кретных системах, как правило, разрешается не включать в запись подсхемы некоторые элементы записи схемы, но преобразование пред- ставления элементов почти нигде не реализовано. Организации КОДАСИЛ не выработали четкой терминологии для обсуждения вопросов преобразования представления: Поэтому мы здесь определим и рассмотрим три уровня — записи, групповых эле- ментов или агрегатов и простых элементов данных, на которых возни- кают проблемы-преобразования представлений. П6
12.6. L Преобразования на уровне записи Из трех перечисленных выше уровней именно этот встречается на практике. Если допускается возможность включения не всех элемен- тов типа записи схемы в соответствующий тип записи подсхемы, то воз- никает необходимость преобразования одного представления в другое в процессе выполнения программы. Такое преобразование связано с рядом проблем. Действительно ли можно опустить любой элемент записи схемы? Некоторые элементы могут играть в схеме особую роль, в частности CALC-ключа; ключа сортировки {возрастающий/убывающий); поис- кового ключа; идентификатора-области. Прежде всего здесь следует отметить разницу между выборкой ин- формации из базы данных и модификацией последней. Если програм- ма, работающая с каким-либо типом записи подсхемы, не будет мо дифицировать экземпляры этой записи, то чаще всего можно опустить элементы данных, играющие указанные выше роли. Предположим, что нам понадобилось не включать элемент, являю- щийся поисковым ключом. Будет ли это иметь значение, если програм- ма, выбирающая экземпляры требуемого типа записи, не пользуется данным поисковым ключом?' Аналогичные рассуждения применимы и в трех остальных случаях. При определении подсхемы нужно очень осторожно подходить к исключению элементов, выполняющих определенные функции в типе записи базы данных. В запросных программах иногда можно опускать такие элементы, по в программах модификации этого, как правило, делать нельзя. При модификации записи подсхемы, соответствующей части записи схемы, возникает еще одна проблема. Разумеется, она имеет место не при всех способах модификации, но что же, в частности, происходит при помещении в базу данных новой записи, некоторые элементы кото- рой не отражены в подсхеме программы? Пэ официальным специфи- кациям, значение этих элементов «не определено» (что равноценно от- сутствию значения). Реальные значения им могут быть присвоены позднее, но уже е помощью другой программы, использующей дру- гую подсхему, в которой они присутствуют. 12.6.2. Преобразования на уровне групповых элементов или агрегатов Если тип записи схемы содержит повторяющиеся группы (возмож- но, вложенные), рассмотренные в параграфе 9.5, а тип записи подсхе- мы также содержит повторяющиеся группы, но отличающиеся от оп- ределенных в схеме, то в процессе выполнения программы необходи- мо преобразовать представление внутренней структуры записи. Эга проблема не рассматривалась РГБД, но была отмечена РГЯБД и под- робно освещена в разделе «Отображение элементов таблиц» «Журна- ла развития Кобола» (с. IV—2—3). В Коболе повторяющаяся группа 117
внутренней структуры записи называется таблицей, а каждый ее эле- мент — элементом таблицы. Агрегат подсхемы может быть больше или меньше соответствующе- го агрегата схемы. В первом случае в него помещаются экземпляры структуры схемы, во втором — возникает необходимость в отбрасы- вании части экземпляра структуры схемы согласно правилам, пред- ложенным РГЯБД. Вполне вероятно, что второй случай никогда не будет реализован, а если и будет, то вряд ли получит широкое распро- странение. Даже если СУБД поддерживает в качестве включающего языка ПЛ/1, совсем не обязательно при этом поддерживать его слож- ную внутреннюю структуру записи. Впрочем, проблема преобразова- ний на уровне агрегатов существует не только для структуры записи ПЛ/1. При внутренней структуре записи Кобола также имеется воз- можность различать структуры типа записи подсхемы и типа записи схемы на уровне агрегатов. В такой ситуации должны применяться правила РГЯБД. Однако все указывает на то, что внутренние струк- туры записи не имеют будущего, так как они вытесняются более гибкими «внешними» наборными структурами. По этой причине преобразование на уровне агрегатов считается не очень существенным и здесь подробно не рассматривается. 12.6.3. Преобразования на уровне элементов данных Проблема преобразования на уровне элементов возникла перед РГБД при переходе от внутренней структуры записи Кобола к внут- ренней структуре записи ПЛ/1. В общих правилах для предложения TYPE были сформулированы основные принципы преобразования представления во всех возможных случаях (с. 120—122, правила 9— 19). Применительно к ЯОД схемы эти преобразования могут показать- ся несколько неожиданными, но КЯОД здесь ничего не изменил. Преобразование представления на уровне элементов гораздо акту- альнее, чем на уровне агрегатов. В научных кругах постоянно растет интерес к СУБД и ищутся пути использования их для обработки все- возможных научных данных. В современном Коболе введены сущест- венные ограничения на работу с числовыми данными и в этом отноше- нии ПЛ/1 имеет перед ним заметные преимущества. Впрочем, будет ли кто-нибудь пытаться применить Кобол для обработки числовых дан- ных (типа ПЛ/1), представленных в базе данных? По определению РГБД существуют три типа преобразования пред- ставления на уровне элементов данных: специфицированные РГБД (с. 120—122), разработчиком и администратором данных. Администратор данных может оказать на процесс преобразования представления элементов некоторое влияние. Во-первых, он может за- дать для элемента вариант CHECK IS PICTURE, что, как указыва- лось в параграфе 9.8, эквивалентно навязыванию ЯОД подсхемы неко- торого синтаксического правила. Если в схеме используется этот ва- риант, то элемент данных подсхемы должен иметь характеристики со- ответствующего элемента схемы. Преобразование представления в та- ком случае не допускается, да и не требуется. 118
Во-вторых, администратор данных может воспользоваться вари- антом ENCODING/DECODING (см. разд. 10.6.3), который автомати- чески отменяет стандартные преобразования первых двух типов. Он может определить свои собственные преобразования в обоих направ- лениях. Так, если он задает кодирование какого-либо элемента, помещаемого в базу данных, то он должен задать и способ его декоди- рования при выборке. Причина появления преобразований второго типа (специфициру- емых разработчиком) состоит в том, что в некоторых случаях РГБД просто не могла определить соответствующее преобразование из-за различий в аппаратном представлении и была вынуждена передать эту функцию разработчику. Сводная таблица правил РГБД представлена на рис. 12.1. Определяя преобразования на уровне элементов, администратор данных должен помнить о том, что элемент данных может играть осо- бую роль в типе записи, т. е. входить в CALC-ключ, ключ сортировки и т. п. Преобразования представлений этих элементов в схеме в пред- ставление их в подсхеме не связано с такими трудностями, как при не- включении элемента в запись подсхемы. Тем не менее подобных пре- образований рекомендуется избегать. 12.6.4. Заключительное замечание Мы рассмотрели три уровня преобразований представлений схемы и подсхемы. В используемых на практике системах преобразования на уровне записи встречаются уже сегодня, преобразования на уров- не агрегатов, будем надеяться, никогда не потребуются, а преобразо- вания на уровне элементов найдут, по-видимому, применение в бли- жайшие годы. 12.7. ИЗМЕНЕНИЕ КРИТЕРИЯ ВЫБОРА НАБОРА В гл. 8 обсуждалась сложная проблема выбора набора. При опре- делении подсхемы алгоритм выбора, указанный в схеме, можно изме- нить. Зачем это может понадобиться? В основном для решения неко- торых задач, связанных с иерархическим выбором набора (см. гл. 8). Напомним, что при иерархическом выборе набора указывается путь к члену определяемого типа набора от некоторой «верхней» точка иерархической структуры, в которой экземпляр записи-владельца ло- кализуется однозначно. В подсхеме на этом пути выбора могут быть опущены один или два узла (т. е. типа записи). Если применяющая данную подсхему программа должна помещать в набор новые записи- члены или находить в нем уже имеющиеся с использованием критерия выбора набора, то для нее необходимо определить новый путь выбора. Проблема выбора набора концептуально слишком сложна. Решение, предложенное РГБД и КЯОД, оказалось несколько запутанным и не- доопределенным. РГЯБД попыталась выработать более четки й подход, но ее определения касаются только ЯОД подсхемы, что не решяает проб- лему в целом. В результате мы имеем три различных подход.3 к выбо- 119
X. Целевое X. представление Исходное X. представление Х^ Битовая строка USAGE IS DISPLAY USAGE IS COMPUTATIONAL TYPE IS BIT [целое] Целевое представление длиннее — справа добавляются нули. Целевое представление короче — если справа имеются нули, они отбрасываются, иначе фиксируется ошибка Бит 1 преобразуется в литеру 1, бит 0 — в литеру 0 Преобразует целое двоичное без знака в соответствии с ос- нованием, масштабом, типом и точностью целевого представ- ления. Возможны ошибки TYPE IS CHARACTER Литера 1 преобразуется в бит 1, ли- тера О-в бит 0. Для других литер преобразование не выполняется — ошибка Целевое представление длин- нее — справа добавляются про- белы, целевое представление короче — пробелы справа от- брасываются, иначе фиксирует- ся ошибка Определивгея разработчиком [целое] TYPE IS CODED ARITHMETIC целое-! [целое-2] Абсолютное арифметическое значение преобразуется в двоичное с фиксиро- ванной точкой. Нулевые биты добав- ляются или отбрасываются слева. Возможны ошибки Определяется разработчиком Специальные правила Рис. 12.1. Таблица преобразований на уровне элемента данных
ру набора в трех разных отчетах КОДАСИЛ. К счастью, на практике известна лишь одна система, в которой реализован иерархический выбор набора, базирующийся на первых предложениях РГБД. Боль- шинство разработчиков предпочитают применять неиерархические варианты. Для этих вариантов не требуется переопределять в ЯОД подсхемы указанный в ЯОД схемы критерий выбора набора. 12.8. СИНТАКСИС ЯОД ПОДСХЕМЫ КОБОЛА Согласно спецификациям РГБД возможно следующее деление ЯОД подсхемы: SUB-SCHEMA IDENTIFICATION DIVISION SUB-SCHEMA DATA DIVISION RENAMING SECTION AREA SECTION RECORD SECTION SET SECTION Язык описания данных подсхемы по «Журналу развития Кобола» содержит больше разделов, но меньше секций: TITLE DIVISION (РАЗДЕЛ ЗАГЛАВИЯ) MAPPING DIVISION (РАЗДЕЛ ОТОБРАЖЕНИЯ) [ALIAS SECTION] (СЕКЦИЯ ПСЕВДОНИМОВ) STRUCTURE DIVISION (РАЗДЕЛ СТРУКТУРЫ) [REALM SECTION] (СЕКЦИЯ ОБЛАСТЕЙ) [SET SECTION] (СЕКЦИЯ НАБОРОВ) [RECORD SECTION] (СЕКЦИЯ ЗАПИСЕЙ) Отметим, что РГЯБД изменила порядок следования секгхий запи- сей и наборов. Новый порядок вряд ли удобен с точки зрения как раз- работчика, так и пользователя. При определении подсхемы естествен- но сначала рассмотреть типы записи, которые необходимо в нее вклю- чить, а уже затем— типы набора, которые должны связывать выбран- ные записи. Во всех остальных отношениях РГЯБД удалось приблизить ЯОЦ подсхемы Кобола к самому Коболу, и поэтому мы будем придержи- ваться далее ее предложений. 12.9. ОБЩИЙ СИНТАКСИС Общий формат ЯОД подсхемы Кобола имеет вид: TITLE DIVISION статья-описан и я-подсхемы [ALIAS SECTION {статья-описания-псевдонима} ...] STRUCTURE DIVISION [REALM SECTION {статья-описания-области} ...] [SET SECTION {статья-описания-набора} ...] [RECORD SECTION {статья-описания-записи} ...] Как и в предыдущих главах, мы не касаемся здесь вопросов управ- ления доступом. Кроме того, «статья-описания-записи» в предложе- ниях РГЯБД почти полностью соответствует Коболу КОДАСИЛ и не является поэтому предметом нашего обсуждения. Таким образом, ниже будут представлены только наиболее существенные предложения. 121
12.10. раздел заглавия Синтаксис именования подсхемы записывается следующим обра- зом (с. IV—4—4): TITLE DIVISION SS имя-под.схемы WITHIN имя-схемы Важно отметить, что подсхема может быть связана с одной и толь- ко одной схемой. Как уже указывалось, при эксплуатации конкрет- ной СУБД допускается существование нескольких схем, каждой из которых может соответствовать несколько подсхем. Мы здесь фактически рассматриваем дополнительные компоненты Кобола, и поэтому все имена, определяемые в ЯОД подсхемы, в част- ности имя подсхемы, должны выбираться в соответствии с правила- ми для имен Кобола. 12.11. РАЗДЕЛ ОТОБРАЖЕНИЯ — СЕКЦИЯ ПСЕВДОНИМОВ Эта секция является необязательной. Если она использует- ся, то ее синтаксис в соответствии с «Журналом развития Кобола» (с. IV—4—5) имеет вид: j ALIAS SECTION AD = псевдо-текст ~ ' REALM-NAME SET-NAME .RECORD-NAME BECOMES имя-области имя-набора имя-записи идентификатор. Псевдо-текст обозначает имя, определенное в схеме, которая соот- ветствует данной подсхеме. Указанные после BECOMES (СТАНОВИТ- СЯ) имена могут использоваться в программах для обращения к дан- ным, включенным в подсхему. Новые имена могут применяться также в секциях областей, записей и наборов. Они не замещают имена схе- мы, а выступают по отношению к ним как имена-синонимы. Присутствующий в синтаксисе «идентификатор» соответствует в Коболе «итмени-данных» или «идентификатору-данных» ЯОД схемы. 12.12. РАЗДЕЛ СТРУКТУРЫ Раздел структуры предназначен для определения структуры и со- держимого части базы данных, соответствующей подсхеме. Он состоит из секций областей, наборов и записей. По всей видимости, можно использовать раздел структуры, содержащий только секции областей и записей, хотя это и не совсем ясно из спецификаций «Журнала раз- вития Кобола». 122
12 12.1 Секция областей В секции областей пользователь может указать все области схемы с помощью одного предложения или перечислить имена только тех об- ластей, которые требуются данной подсхеме. Синтаксис данной сек- ции (с. IV—4—7): R.-.M.M SECTION (ALL ) RD ----- — (имя-области J Статья RD может повторяться нужное число раз. Заметим также, что данная секция должна присутствовать в описании подсхемы, т. е. последняя должна включать, по крайней мере, одну область. Если не- которая область не включена в подсхему, то использующая ее програм- ма не может, явно или неявно, обращаться к данным, расположенным в этой области. Под «неявным обращением» подразумевается случай, когда область содержит некоторый тип записи, участвующий в иерар- хическом варианте выбора набора, или индекс поискового ключа. Мо- жет возникнуть также ситуация, при которой одна из областей содер- жит некоторые экземпляры типа записи-члена, а другая (вошедшая в подсхему) — все остальные экземпляры. При обработке экземпляра набора в доступной области может встретиться запись, указывающая на запись в недоступной области, и тогда дальнейшее продвижение по набору становится невозможным. 12.12.2. Секция записей Рассмотрим вначале секцию записей, а затем секцию наборов, хотя это и противоречит предложенному РГЯБД следованию секций. Синтаксис этой секции сложнее, чем других. Объединяя обе его части из «Журнала развития Кобола» (с. IV—4—10 и IV—4—12), получаем: R ECORD SECTION 01 имя-записи [(WITHIN {имя-области-1} ...J REALM-ID IS идентификатор-1] {номер-уровня имя-данных-1 [PICTURE IS строка-символов] [USAGE IS] • COMPUTATIONAL [-nj DB-KEY DISPLAY |-n] i INDEX [-nj Г; OCCURS целое-1 TIMES ; OCCURS целое-2 ТО целое-3 TIMES DEPENDING ON имя-данных-бд Здесь к Коболу КОДАСИЛ добавляется предложение AVITHIN и связанная с ним фраза REALM-ID, а также появляется возможность определять USAGE DB-KEY. 123
Действие предложения WITHIN объясняется в журнале развития иначе, чем в спецификациях РГБД. Мы будем следовать более строго- му изложению журнала развития. Если какой-либо тип записи приписан в схеме к двум или более об- ластям, то, возможно, в подсхеме требуется доступ лишь к некоторым (не ко всем) из этих областей и соответственно не ко всем записям ука- занного типа. Определения пользователя в секции областей и в пред- ложении WITHIN не должны быть противоречивыми. Фраза REALM- ID, вообще говоря, является избыточной, так как выбор области можно считать неявно определенным в секции областей. Возможность определять использование DB-KEY для некоторого элемента данных существует и в ЯОД схемы (см, параграф 9.4), но в «Журнале развития Кобола» принято более короткое обозначение. Как уже отмечалось, практика хранения ключей базы данных в самой базе данных не получила одобрения, но пользователи еще могут встре- титься с этим в конкретных системах. Программисту следует предоста- вить право помещать значения ключа базы данных в рабочую область оперативной памяти своей программы в процессе ее выполнения. Од- нако если для этого он должен определять элемент типа ключа базы данных в типе записи схемы, а затем специфицировать его еще и в ти- пе записи подсхемы, то в таком случае цель не оправдывает средства. К счастью, в соответствии с журналом развития теперь разрешено определять элементы типа ключа базы данных в обычных описаниях записи раздела данных. 12.12.3. Секция наборов Если не учитывать указанную в параграфе 12.7 возможность пе- реопределения критерия выбора набора схемы, то синтаксис секции наборов становится таким же простым, как и для секции областей. Следуя спецификациям «Журнала развития Кобола» (с. IV—4—19), запишем его следующим образом: SD / ~ I — (имя-на бора-1 J С другой стороны, если пользователь собирается переопределять выбор набора, то он должен отдельно указывать его имя и, следова- тельно, не может использовать вариант ALL. Приведем для полноты изложения вариант переопределения не- иерархического выбора набора по «Журналу развития Кобола»: S_D имя-набюра-1 [; SET SELECTION FOR имя записи IS SYSTEM CURRENT идентификатор-1 I... VALUE OF идентификатор-2 IS идентификатор-3 (идентификатор-4 IS идентификатор-5]... VIA имя- набора-1 OWNER 124
fl ОД node л с мы SYSTEM CURRENT идентификатор-1 VALUE OF соответствующая возможность отсутствует Сравним обсуждаемый вариант ЯОД подсхемы с аналогичным ва- риантом ЯОД схемы, рассмотренным в гл. 8: ДОД схемы SYSTEM CURRENT DATA-BASE-KEY CALC-KEY ) MEMBER Здесь можно заметить, что КЯОД в ЯОД схемы явно синтаксичес- ки указывает смысл третьего и четвертого вариантов, тогда как РГЯБД следует менее удачной практике объяснять смысл в семантических правилах. 12.13. ТРАНСЛЯТОР ЯОД ПОДСХЕМЫ КОБОЛА Подсхема должна быть преобразована в объектное представление с помощью компоненты СУБД, называемой транслятором подсхем. Последнему должно быть доступно объектное представление схемы, указанной в разделе заглавия транслируемой подсхемы. ГЛАВА 13 ЯЗЫК МАНИПУЛИРОВАНИЯ ДАН НИМИ 13.1. ВВЕДЕНИЕ Чтобы получить полное представление о подходе КОДАСИЛ к уп- равлению базами данных, необходимо хорошо уяснить концепции ЯМД. Многие вводные курсы ограничиваются изложением концепций типа набора, цепочек, а иногда также способа размещения и подсхем, оставляя у читателя или слушателя ощущение, что он видит только верхнюю часть айсберга. Язык манипулирования данными часто считают излишне сложным, но в большинстве случаев это утверждают те, кто просто не смог в нем разобраться. Действительно, предлагаемые РГБД и РГЯБД тексты трудно усваиваются, однако это характерно для формального изло- жения любого языка. Читатель обычно легко воспринимает идеи типа набора и цепочек, но некоторые тонкости манипулирование сложны- ми наборными структурами остаются непонятыми. Здесь >1 в после- дующих главах делается попытка представить ЯМД полно, подробно и со всеми необходимыми объяснениями. 13.2. ВЗАИМОДЕЙСТВИЕ С ВКЛЮЧАЮЩИМ ЯЗЫКОМ Как указывалось ранее, подход РГБД к манипулированию базами данных основан на использовании включающего языка. Эхо означа- ет, что прикладной программист может обрабатывать данные в базе данных, используя расширенную версию некоторого стандартного языка программирования, как правило, Кобола, но иногда и ПЛ/1 125
или Фортрана. Расширение стандартного языка программирования представляет собой в основном операторы манипулирования связями между записями. Для работы с внутренней структурой записи приме- няются уже существующие операторы языка программирования. Новые операторы по формату должны быть во всех отношениях неотличимы от старых. Более того, лет через десять в некоторых языках программирования, скорее всего, перестанут выделять эти операторы как «операторы ЯМД». Мы же пока еще вынесем операторы, вводимые для работы с записями базы данных, в отдельную группу ЯМД-операторов. Что касается Кобола, то новые операторы в нем в основном относятся к разделу процедур. В некоторых случаях бы- ли расширены уже существующие операторы. Пользователь Кобола фактически пишет прикладную программу на расширенной версии этого языка. Теоретически исходный текст его программы должен компилироваться соответственно модифициро- ванным и расширенным компилятором с Кобола. На практике боль- шинство разработчиков решило не модифицировать существующий компилятор с Кобола, а предоставить предтранслятор ЯМД/КОБОЛ (см. разд. 2.5.1). При этом исходный текст программы пользователя сначала обрабатывается предтранслятором ЯМД, после чего передает- ся компилятору с Кобола. Такой «предтранслированный» исходный текс! уже может обрабатываться стандартным компилятором с Кобо- ла, так как каждый ЯМД-оператор раздела процедур заменен в нем на оператор CALL с параметрами, формально соответствующими дан- ному оператору и в то же время оператору ЯМД исходной программы. Эти параметры будут затем в процессе выполнения программы пере- даны исполнительному резидентному модулю СУБД. Возможности ЯМД не зависят от того, применяется ли метод пред- трансляции или модифицированный компилятор с Кобола. Конкрет- ные предтрансляторы отличаются друг от друга по степени выпол- няемой ими работы. Простейший предтранслятор лишь распознает ЯМД-оператор и переводит его в оператор CALL с параметрами. Более развитые предтрансляторы могут учитывать семантику выполнения операторов ЯМД. 13 3. ПРИВЯЗКА К ПОДСХЕМЕ Любая прикладная программа, предназначенная для обработки записей в базе данных, должна быть «привязана» к соответствующей подсхеме. С точки зрения программиста, это означает, что он должен указать в программе имя применяемой подсхемы. Последняя должна быть предварительно оттранслирована в объектное представление. Предложенный РГБД синтаксис указания подсхемы предусматри- вает предложение INVOKE (ВЫЗВАТЬ) в новой секции схемы су- ществующего раздела данных. Программист в этом случае должен написать: DATA DIVISION SCHEMA SECTION INVOKE SUB-SCHEMA имя-подсхемы OF SCHEMA имя-схемы/ 126
В каждой прикладной Кобол-программе допускается только одно предложение INVOKE. Этот синтаксис был модифицирован РГЯБД, которая приблизи- ла его к формату Кобола. В результате в раздел данных теперь следу- ет включать предложение: DB имя-подсхемы WITHIN имя-схемы. Действие этого предложения такое же, как и варианта РГБД, хотя их синтаксические форматы несколько различаются. Здесь уместно вспомнить одно из важных следствий использования подсхемы, а именно резервирование рабочей области оперативной па- мяти для каждого типа записи, включенного в подсхему. Этот вопрос подробно рассматривался в параграфе 12.4, и мы не будем к нему воз- вращаться. Заметим только, что для правильного восприятия ЯМД необходимо хорошо представлять себе роль области записи в процес- се выполнения программы. 13.4. ПРИКЛАДНЫЕ ПРОГРАММЫ И ПРОЦЕССЫ У РГБД имелись основания предполагать, что прикладные сис- темы, использующие базы данных, будут все чаще разрабатываться как системы прямого («on-line») доступа. Существует несколько типов таких систем, однако в обработке коммерческих данных, как правило, применяются системы, в которых непрограммисты (так на- зываемые «конечные» или «параметрические» пользователи) вызыва- ют заранее составленные программы обработки сообщений (transacti- on). Подобные системы обычно называют системами обработки сооб- щений. К системам прямого доступа относятся также системы под- готовки программ (все еще часто называемые системами разделения времени) и системы интерактивной обработки запросов. Примерами применения систем обработки сообщений могут слу- жить системы обработки заказов, банковские системы поддержки ба- ланса и учета приходных и расходных операций, а также системы ре- зервирования мест на авиалиниях. Здесь важно отметить, что в по- добных системах одна и та же конкретная программа обработки сооб- щений может быть одновременно вызвана с нескольких различных тер- миналов. Каждый отдельно выполняемый экземпляр этой программы называется процессом. Следует четко различать свойства прикладной программы и про- цесса. Впрочем, если определение процесса правильно понято, то эта задача не является сложной. Чтобы ее решить, нам прежде всего нужно вернуться к понятию области записи. Область записи выделяется в оперативной памяти для каждого типа записи подсхемы в любом процессе, использующем данную подсхему. Рассмотрим эту ситуацию на примере, показанном на рис. 13.1. Здесь представлены три подсхемы СХЕМЫ-1. Две прикладные про- граммы используют ПОДСХЕМУ-1 (программы ПП1 и ПП2), одна прикладная, программа (ППЗ) — ПОДСХЕМУ-2 и еще две — ПОД- 127
СХЕМУ-3. В данный момент времени выполняются следующие пять процесса в: один процесс программы ПП1, а именно ПРИ; три процесса программы ППЗ, а именно ПР31, ПР32 и ПРЗЗ; один процесс программы ПП5, а именно ПР51. Заметим, что в этот момент не выполняется ни один процесс про- грамм ПП2 и ПП4. Рис. 13.1. Соотношение между процессами, прикладными программами и подсхемами Что касается процессов ПР31, ПР32 и ПРЗЗ, то каждый из них име- ет свои собственные области записи для каждого типа записи ПОД- СХЕМЫ-2. И это естественно, так как между указанными процессами нет ничего общего, кроме того, что все они соответствуют одной и той же прикладной программе. 13.5. РЕКИ СТРЫ БАЗЫ ДАННЫХ Программа взаимодействует с резидентным модулем СУБД с ис- пользованием обычной техники передачи параметров. Эти параметры либо предусматриваются синтаксисом оператора ЯМД, либо оператор ЯМД содержит ссылки на элементы данных в оперативной памяти, значения которых передаются в качестве значений параметров. В свою очередь, резидентный модуль может передавать некоторые сообщения программе через введенные РГЯБД так называемые ре- гистры базы данных. Имеется несколько таких регистров. Основной из них — DB-STATUS (СОСТОЯНИЕ БАЗЫ ДАННЫХ) — уста- навливается при каждом выполнении некоторого ЯМД-оператора в процессе. При этом если оператор ЯМД выполняется успешно, то в регистр DB-STATUS ставится нуль. В случае неуспешного выполнения в него вводится специальное значение, указывающее причину его невыпол- нимости. Теперь нам нужно выяснить, почему РГЯБД назвала 128
этот регистр DB-STATUS, а не ERROR-STATUS (СОСТОЯНИЕ ОШИБКИ), как было предложено РГБД. Выполнение оператора ЯМД может завершиться неуспешно по ря- ду причин. Наиболее часто (но не всегда) это происходит из-за какой- либо ошибки. Для таких ситуаций РГЯБД введен термин исключитель- ное состояние базы данных, не связанный безоговорочно с ошибками. В спецификациях РГБД все эти состояния определены как «состояния ошибки» и именно это определение встречается во многих конкретных системах. Предложения РГЯБД и РГБД несколько различаются и по пред- ставлению исключительных состояний. В представлении РГБД ис- пользуются четыре цифры, а в представлении РГЯБД — семь. В обо- их случаях первые две цифры обозначают код выполняемого оператора ЯМД, но сами коды операторов в предложениях не одинаковы. Мы не приводим полный список исключительных состояний базы данных, так как он интересен лишь в спецификациях конкретной си- стемы. Состояния, которые могут возникнуть при выполнении отдель- ных ЯМД-операторов, будут обсуждаться в соответствующих разде- лах. Здесь же мы ограничимся лишь некоторыми общими замечаниями Программисту предоставляется возможность планировать дейст- вия, выполняемые при возникновении тех или иных исключительных состояний. Так, если программист считает, что при каком-либо ис- ключительном состоянии в любое время в любом месте программы сле- дует выполнять одни и те же действия, то он может воспользоваться так называемой «декларативной» процедурой (для не знакомых с Ко- болом пользователей поясним, что эта процедура должна выполнять- ся при определенной ситуации в программе, в нашем случае — при исключительном состоянии базы данных, хотя в Коболе можно уста- новить реакции и на другие условия). Если же программисту требует- ся выполнять различные действия каждый раз при возникновении некоторого исключительного состояния, то он может написать следую- щую проверку IF DB-STATUS EQ ... после каждого оператора ЯМД, при котором возможно появление это- го исключительного состояния. Естественно, первый подход приме- няется гораздо чаще второго. Действия, выполняемые при возникновении исключительного сос- тояния, часто должны включать некоторый анализ сложившейся си- туации. Для облегчения такого анализа резидентный модуль СУБД поддерживает значения еще нескольких специальных регистров базы данных, в частности, следующих: DB-REALM-NAME (ИМЯ-ОБЛАСТИ-БД) DB-SET-NAME (ИМЯ-НАБОРА-БД) DB-RECORD-N АМЕ (ИМЯ-ЗАПИСИ-БД) Эти регистры выделяются для любого процесса. Каждый регистр может содержать 30-символьное имя Кобола. При возникновении исключительного состояния базы данных ре- гистры соответственно должны содержать имена области, типа набо- 5 Зак. 145 129
ра н тина записи, связанные с этим исключительным состоянием. Как правило, в ситуации разобраться нетрудно и обычно всегда ясно, по- чему именно тот или иной тип записи указан в регистре. Впрочем, по- следнее зависит от типа исключительного состояния. Следует упомянуть также о двух других специальных регистрах— о ERROR-TYPE (ТИП ОШИБКИ) и ERROR-COUNT (СЧЕТЧИК- ОШИБОК), предложенных РГБД. Первый из них связан с проблема- ми одновременного доступа, а второй — с числом «ошибок», встретив- шихся при выполнении ЯМД-оператора. (Содержимое первого ре- гистра относилось к первой обнаруженной ошибке.) РГЯБД отказа- лась от идеи «счетчика ошибок» и переименовала ERROR-TYPE в DB-CONFLICT (КОНФЛИКТ-БД), что более соответствует его роли в анализе ситуации. 13.6, ИНДИКАТОРЫ ТЕКУЩЕГО СОСТОЯНИЯ Индикаторы текущего состояния являются одной из наиболее важ- ных концепций ЯМД. Мы были вынуждены ввести такой индикатор при изучении хронологических типов набора в разд. 6.4.2 и возвраща- лись к нему при обсуждении выбора набора в параграфе 8.3. Поэтому читатель уже имеет некоторое представление об этих индикаторах. Рассмотрим их теперь полностью п подробно. Индикатор текущего состояния есть поддерживаемый системой объект, как правило, указывающий на некоторую запись в базе дан- ных. Это означает, что каждый такой индикатор должен содержать некоторое значение ключа базы данных, возможно и нулевое (напри- мер, в начале выполнения процесса). Число индикаторов текущих, поддерживаемых для каждого про- цесса, и их типы полностью зависят от подсхемы программы, к которой принадлежит данный процесс (если можно сказать, что процесс «при- надлежит» программе). Различают следующие типы индикаторов: текущей записи процесса — только один; текущей записи в типе набора — один для каждого типа набора в подсхеме; текущей записи в типе записи — один для каждого типа записи в подсхеме; текущей записи в области — один для каждой области подсхемы. Таким образом, если подсхема включает четыре типа набора, шесть типов записи и три области, то для каждого процесса программы, ис- пользующей данную подсхему, будет автоматически поддерживаться 1 + 4 т 6 + 3 14 индикаторов текущего состояния. Заметим, что индикаторы различного типа имеют существенно раз- личное значение. Первые два — текущей записи процесса и текущей записи в типе набора — гораздо важнее двух последних. По прибли- зительной оценке 80% прикладных программ могут быть вполне эф- фективно написаны без использования индикаторов текущей записи в типе записи и текущей записи в области. Установка значений и обновление индикаторов текущего состояния осуществляется при выполнении двух ЯМД-операторов FIND и STO- 130
RE. Однако используются эти значения в процессе выполнения мно- гих операторов ЯМД, включая два названных выше. Индикатор текущей записи процесса играет несколько особую роль, так как именно он часто указывает резидентному модулю СУБД ту запись базы данных, над которой нужно выполнить текущее действие. Например, может встретиться следующий оператор ЯМД: ERASE имя-записи В базе данных может быть 10 000 экземпляров указанного типа записи и системе необходимо знать, который из них здесь следует уда- лить. Это определяет индикатор текущей записи процесса и поэтому программист должен перед выполнением оператора ERASE найти под- лежащую удалению запись с помощью оператора FIND. Индикатор текущей записи в типе набора часто используется в опе- раторах ЯМД для выбора конкретного экземпляра набора указанно- го в операторе типа набора. Рассмотрим, например, оператор CONNECT имя-записи ТО имя-набора В данном случае индикатор текущей записи процесса применяется для указания записи, включаемой в набор, а индикатор текущей в ти- пе набора — для определения экземпляра набора (тип которого ука- зан «именем-набора»), в который будет включаться эта запись. Программисту следует помнить, что в начале выполнения процес- са все индикаторы содержат нулевые значения. Поэтому он должен проследить за тем, чтобы первые выполняемые ЯМД-операторы про- граммы не использовали значений индикаторов текущего состояния. В заключение следует заметить, что имеются специальные вариан- ты операторов FIND и STORE, при выполнении которых не произво- дится обновление значений некоторых или всех индикаторов текуще- го состояния. Такая возможность существует для всех индикаторов, кроме индикатора текущей записи процесса. Для подобных ситуа- ций РГБД ввела термин «подавление изменения текущего состоя- ния», а РГЯБД заменила этот термин на «сохранение текущего со- стояния», но смысл этих терминов один и тот же. Предоставление программисту средств управления установкой ин- дикаторов текущего состояния существенно расширяет его логические возможности, но пользоваться ими следует с большой осторожностью» Начинающему программисту не рекомендуется пытаться эксперимен- тировать с этими индикаторами. 13.7. ОБЩИЕ ПРИНЦИПЫ ЯМД Прежде чем перейти к обсуждению каждого ЯМД-операгора в от- дельности, рассмотрим некоторые общие принципы подхода РГБД к манипулированию записями данных. Этот подход возник еще в нача- ле 60-х годов в системе IDS и фактически совпадает с подходами дру- гих широко используемых СУБД, в частности IMS и TOTAL. Как уже указывалось, в оперативной памяти для каждого типа записи подсхемы процесса выделяется так называемая область записи. 5* 131
Некоторые операторы ЯМД, выполняющие действия на уровне запи- си, осуществляют пересылку данных между этой областью записи и базой данных. Заметим, что действия такого оператора относятся к одной и только одной записи, Аэтя косвенно в процессе его выполне- ния могут быть затронуты и другие записи. Подход РГБД к ЯМД можно охарактеризовать как «одна запись за один шаг». Этот подход был испытан и доказал свою состоятельность в реально эксплуатируемых системах. Возможно, в буду- щем он будет дополнен или даже полностью вытеснен ка- ким-либо более сложным под- ходом, манипулирующим мно- жествами записей. Пока же это «эталон», с которым дол- жны сравниваться все дру- гие подходы. Уровень «Журнал раз- РГБД Область вигн я Кобола» READY FINISH OPEN CLOSE Набор ORDER ORDER Запись (только) FIND, ERASE STORE FIND DELETE STORE Запись и элементы GET MODIFY GET MODIFY Связи CONNECT DISCONNECT INSERT REMOVE Индикаторы текущего состояния ACCEPT MOVE Условия IF IF Объявлен ия USE USE Одпозрем ен ный доступ - KEEP FREE REMONITOR KE Е е FREE (нет соот- ветствия) Рис. 13.2. Соотношение между ЯМД-опера- торами в спецификациях «Журнала разви- тия Кобола» и РГБД 13.8. ОПЕРАТОРЫ ЯМД Операторы ЯМД представ- лены РГБД и РГЯБД в ал- фавитном порядке. Такое представление может оказать- ся полезным лишь в случае испо л ьзова н и я соответств у ю- щего отчета в качестве спра- вочника по правилам приме- нения операторов. В учебном руководстве это не является обязательным. Имеет смысл классифици- ровать операторы ЯМД по уровням, на которых они вы- полняют свои действия. Здесь мы постараемся дать читате- лю общее представление о всей совокупности операторов, посвятив каждому из них один параграф с кратким изложением его роли и функций. Многие из предложенных РГБД названий операторов были изме- нены РГЯБД по разным причинам. На рис. 13.2 представлено распре- деление операторов по уровням с указанием обоих названий. Причи- ны изменения названия будут приведены при обсуждении отдельных операторов. 132
13.8.1. Оператор READY Оператор READY должен быть первым ЯМД-оператором в про- грамме, обрабатывающей содержимое базы данных. С его помощью программист сообщает резидентному модулю СУБД, к какой области или областям он собирается обращаться, какова цель обращения (по- иск или обновление) и, наконец, что разрешается другим процессам, которые также могут потребовать доступа к тем же областям. Этот оператор особенно важен потому, что он имеет отношение к проблеме одновременного доступа. Концептуально оператор «READY область» аналогичен оператору «OPEN файл» в традиционной обработке дан- ных. 13.8.2. Оператор FINISH Оператор FINISH дополняет READY и при стандартном исполь- зовании должен быть последним выполняемым в программе операто- ром ЯМД. Он аналогичен оператору «CLOSE файл». 13.8.3. Оператор FIND Оператор FIND, очевидно, является основным оператором ЯМД. Он применяется для установления наличия в базе данных некоторой записи. Если он выполняется, то после применения соответствующего оператора GET данные этой записи можно обрабатывать операторами включающего языка (такими, как MOVE). Поскольку существует не- сколько вариантов оператора FIND при выборе требуемого варианта программист должен учитывать такие декларации ЯОД, как типы на- бора и способы размещения записей. 13.8.4. Оператор STORE Программист может образовать в области записи новый экземпляр записи и поместить его в базу данных с помощью оператора STORE. Для области, в которой будет располагаться данная запись, предва- рительно должен быть выполнен оператор READY FOR UPDATE (ОТКРЫТЬ ДЛЯ ОБНОВЛЕНИЯ). При некоторых способах разме- щения и критериях выбора набора программист перед выполнением оператора STORE должен присвоить значения определенным пара- метрам. Этот оператор синтаксически прост, но имеет довольно слож- ную семантику. 13.8.5. Оператор GET Оператор GET связан с оператором FIND, так как он использует- ся для перемещения найденной записи из системного буфера резидент- ного модуля СУБД в область записи процесса, соответствующую дан- ному типу записи. При этом в область записи можно пересылать все или лишь некоторые элементы указанного типа записи. 133
13.8.6. Оператор ERASE Оператор ERASE используется для «стирания» некоторой записи е базе данных. Перед его выполнением присутствие в базе данных соответствующей записи должно быть предварительно установлено с помощью оператора FIND. Оператор ERASE имеет несколько вари- антов, позволяющих одновременно удалять из базы данных несколько записей. Действие этих вариантов зависит от указания допустимости исключения, которое рассматривалось в параграфе 7.2. 13.8.7. Оператор MODIFY Оператор MODIFY заменяет некоторую запись в базе данных на такую же (т. е. с тем же ключом базы данных) новую запись из обла- сти записи в оперативной памяти. Как правило, выполнению этого оператора предшествует последовательность операторов FIND, GET и MOVE. Операторы MOVE (в нужном количестве) вносят изменения в значения элементов данных в оперативной памяти, которые затем переносятся в базу данных оператором MODIFY. Последний можно использовать и на уровне элементов данных. 13.8.8. Операторы CONNECT и DISCONNECT Если для типа записи определено автоматическое включение в ка- ком-либо типе набора (см. параграф 7.1), то запись будет включена в некоторый набор этого типа при помещении в базу данных с помощью оператора STORE. Однако впоследствии допускается ее исключение из набора с помощью оператора DISCONNECT и, наоборот, включение в него с помощью оператора CONNECT. Последний может быть свя- зан с критерием выбора набора. 13.8.9. Оператор ORDER Этот оператор редко встречается в конкретных системах, но если он реализован, то может оказаться весьма полезным. Он связан с оп- ределением упорядочения набора в ЯОД (см. параграф 6.2) и позво- ляет программисту по-своему упорядочить некоторый экземпляр хро- нологического типа набора, причем либо временно — на время выпол- нения данного процесса, либо постоянно, т. е. с изменением порядка записей в самой базе данных. Заметим, что в последнем случае не из- меняется способ упорядочения набора, в соответствии с которым в не- го включаются новые записи. 13.8.10. Оператор ACCEPT Оператор ACCEPT используется для пересылки значений индика- торов текущего состояния в определенные пользователем элементы данных. Последние должны быть специфицированы как элементы ти- па DB-KEY. Этот оператор может использоваться также для копиро- вания имени области в определенный пользователем буквенно-цифро- вой элемент данных. 134
13.8.11. Оператор If7 Оператор IF представляет собой расширение соответствующего оператора Кобола. С его помощью программист может осуществлять некоторые проверки по отношению к последней найденной записи для выяснения, входит ли она и в каком качестве в определенный тип на- бора. Существует еще один вариант этого оператора, который позво- ляет проверить, «пуст» ли некоторый экземпляр указанного типа на- бора. 13.8.12. Оператор USE Оператор USE также является оператором Кобола, в который бы- ла введена дополнительная возможность USE FOR DB-EXCEPTION (ИСПОЛЬЗОВАТЬ ПРИ ИСКЛЮЧИТЕЛЬНОМ СОСТОЯНИИ БА- ЗЫ ДАННЫХ). С его помощью теперь можно осуществлять проверки и определять реакции на различные исключительные состояния ба- зы данных, которые могут возникнуть при выполнении операторов ЯМД. 13.8.13. Операторы KEEP, FREE и REMONITOR Эти три оператора связаны с проблемами целостности при одновре- менном доступе, когда два или более процессов обрабатывают данные в одной и той же области. Подход РГЯБД к данной проблеме достаточ- но сложен и будет подробно обсуждаться далее при рассмотрении воп- росов одновременного доступа. 13.9. Заключение Язык манипулирования данными Кобола состоит из тринадцати новых операторов раздела процедур и модификаций существующих операторов IF, USE и ACCEPT. Операторы ЯМД были представлены выше в последовательности, в которой они, по нашему мнению, долж- ны рассматриваться в учебном пособии. Этой последовательности мы и будем придерживаться в дальнейшем при подробном обсуждении операторов. ГЛАВА 14 ОПЕРАТОРЫ READY И FINISH 14.1. ВВЕДЕНИЕ Приступая к подробному обсуждению операторов ЯМД, напомним, что при составлении прикладной программы следует учитывать воз- можность ее выполнения одновременно с другими программами. Точ- нее, одновременно будут выполняться процессы, и проблема состоит в том, что они могут в один и тот же момент обратиться к одной и той 135
же записи в базе данных. Если эти процессы обращаются к некоторой записи для выборки данных, то осложнения не возникают. Изменение данных (включая удаление записей) связано с серьезными трудно- стями. Разработчики СУБД должны были бы освободить программиста от необходимости учета особенностей одновременного доступа, тем бо- лее что современные методы вполне могут обеспечить такую возмож- ность. Однако, как и во многих других подобных случаях, это приве- ло бы к снижению эффективности процесса выполнения программы. По предложению РГБД решение проблемы одновременного до- ступа предоставляется администратору данных, но только в том смыс- ле, что предусмотрены средства, позволяющие программисту в неко- торой степени освободиться от этой проблемы. В соответствии с подходом РГБД требуется прежде всего рассмот- реть оператор READY, аналогичный оператору «OPEN файл», так как он сообщает о намерении обрабатывать данные в некоторой части базы данных. 14.2. СИНТАКСИС ОПЕРАТОРА READY Прежде чем рассматривать особенности одновременного доступа, представим синтаксис и семантику оператора READY. По предложе- ниям РГЯБД (с. III—12—40) синтаксис данного оператора имеет вид: READY имя-набора-1 имя-области-1 USAGE-MODE IS "EXCLUSIVE " PROTECTED /RETRIEVAL] ~ UPDATE Этот синтаксис несколько отличается от предложенного РГБД (с. 247): (ALL. FOR SET имя-набора-1 [, имя-набора-2].., ) OPEN ----- --------- I *---- I^^HA имя-области-1 (, имя-области-2]... j Г EXCLUSIVE 1 (RETRIEVAL] "I ; USAGE-MODE IS — —---------- J------------ ------------- I PRQ£BCTED | [UPDATE ) В конкретных системах наметилась тенденция не указывать типы набора в первой части оператора, но тем или иным способом расширять фразу USAGE-MODE (РЕЖИМ-ИСПОЛЬЗОВАНИЯ). Один из этих способов заключается в введении дополнительного режима «первона- чальной загрузки», который используется при первичном помещении в область некоторой совокупности записей. Кроме того, определяется режим использования, неявно подразумеваемый в случаях, когда не указывается ни EXCLUSIVE (МОНОПОЛЬНЫЙ), ни PROTECTED (ЗАЩИЩЕННЫЙ). Этот режим называется NON-PROTECTED (НЕ- ЗАЩИЩЕННЫЙ). 136
14,2.1. Режимы использования Необязательная фраза USAGE-MODE содержит две декларации. Выбирая вариант UPDATE (ОБНОВЛЕНИЕ) или RETRIEVAL (ВЫБОРКА), программист сообщает, каким образом он собирается обрабатывать записи в области. Указывая RETRIEVAL, он может использовать только операторы FIND, GET и IF, а указывая UPDATE, также и операторы STORE, MODIFY, ERASE, CONNECT, DISCON- NECT, ORDER. Интересно отметить, что если программист полностью опускает фразу USAGE-MODE, то по умолчанию принимается режим RETRIE- VAL (в отличие от системы IDS/1, где по умолчанию принимался про- тивоположный вариант). Более существенной является та часть фразы USAGE MODE, в ко- торой производится выбор между EXCLUSIVE, PROTECTED и третьим так называемым «неограниченным» вариантом (UNREST— RICTED). Этот термин не используется комитетами КОДАСИЛ. Од- нако, поскольку неограниченный режим не менее важен, чем два дру- гих, нам следует ввести какой-то термин для его идентификации. Комбинируя варианты RETRIEVAL и UPDATE с каждым из ва- риантов EXCLUSIVE, PROTECTED и UNRESTRICTED, мы полу- чим шесть различных режимов использования. Фразу определения режима использования теперь можно специфи- цировать в виде: EXCLUSIVE USAGE-MODE IS --------- f1 PROTECTED Т UNRESTRICTED RETRIEVAL UPDATE Для обеспечения однозначности мы будем называть первый выби- раемый вариант режимом одновременного доступа, а второй — режи- мом обработки. Эти два режима в совокупности определяют режим ис- пользования. Комитеты КОДАСИЛ применяли только термин «режим использования», который явно недостаточен для полного представле- ния проблемы. 14.2.2. Монопольный режим доступа Если программист использует в своей программе вариант READY FOR EXCLUSIVE, то тем самым он сообщает, что готов подождать, пока все выполняемые одновременно процессы не закончат работу с данной областью. С того момента, когда его процесс начнет контроли- ровать данную область, и до тех пор, пока его выполнение не завер- шится, никакой другой процесс не может обратиться к этой области. Такой режим получил название «монопольного». При необходимости изменения записей в области монопольный режим обеспечивает «невмешательство» со стороны остальных про- цессов. Все они будут ждать, даже если им требуется всего лишь вы- 137
брать единственную запись из области. Очевидно, что при этом за- медляется работа всей прикладной системы, что может быть допустимо в одних случаях и крайне нежелательно в других. По крайней мере, здесь полностью исключается ситуация, когда обновляющий процесс вносит изменения в записи, обрабатываемые в этот момент процессом выдачи отчетов. Режим использования «для монопольного обновления» может иногда оказаться весьма полезным, но часто применять его не рекомендует- ся. Этот режим имеет место и при первоначальной загрузке записей в область. С другой стороны, режим использования «для монопольной выбор- ки» совершенно несостоятелен. Если все программисты возьмут на вооружение этот вариант, то общая производительность прикладной системы с прямым доступом чрезвычайно понизится. Однако РГБД предусмотрела средство, с помощью которого администратор данных может ограничить применение монопольной выборки. Этот вопрос бу- дет обсуждаться в главе, посвященной управлению доступом. 14.2.3. Защищенный режим доступа Режим защищенного одновременного доступа интерпретируется РГБД и РГЯБД по-разному. В отчете РГБД отмечается, что (с. 248, правило 7) «использование фразы PROTECTED предотвращает одно- временное обновление, но разрешает одновременную выборку из одной и той же области». В «Журнале развития Кобола» дается более простая и в то же вре- мя более четкая формулировка (с. III—12—41, правило 11): «Фраза PROTECTED не позволяет какому-либо другому процессу произво- дить обновление указанных областей». Там же приводится следующее определение режима использования PROTECTED: «Состояние области, при котором другие процессы не могут модифицировать записи в дан- ной области». Каждое из этих определений можно трактовать различным обра- зом. Однако правильнее всего дать им следующее объяснение. В тот момент, когда процесс открывает область в режиме «защищенного об- новления», не должен выполняться никакой другой процесс, обнов- ляющий данные в области, независимо от его режима одновременного доступа. Процессы, осуществляющие выборку из указанной области, при этом могут выполняться, но уже с точки зрения этих других про- цессов ни один из них не должен иметь режим «монопольной выборки». Если процесс открывает область в режиме «защищенной выборки», то одновременно с ним не может выполняться какой-либо другой об- новляющий процесс, но могут выполняться процессы выборки данных йз этой области. Таким образом, при использовании режима защищенного доступа одновременно могут выполняться один обновляющий процесс и не- сколько выбирающих. 138
14.2.4. Режим неограниченного доступа Когда программист открывает область в режиме неограниченного доступа, на первый взгляд может показаться, что он не собирается учи- тывать действия всех остальных выполняемых процессов. На само^ деле, применяя этот режим, программист делает попытку повысить общую эффективность группы одновременно выполняемых процессов, причем он должен каким-то образом обеспечить целостность базы дан* ных. Последнее достигается с помощью оператора KEEP (ЗАХВА- ТИТЬ, ДЕРЖАТЬ), который будет рассматриваться в гл. 17. Режим «неограниченной выборки» означает, что программа может выбирать данные из области, независимо от функций других прог- рамм. Аналогично в режиме «неограниченного обновления» програм- ма обновляет данные в области вне всякой связи с действиями дру- гих программ. 14.2.5. Общий обзор режимов использования Теперь, после того как мы рассмотрели каждый режим одновремен- ного доступа в отдельности, можно перейти к обсуждению всей ситуа- ции в целом. Для этого следует обратиться к так называемой матрице или таблице конфликтов. Таблица конфликтов строится в терминах всех возможных режи- мов использования, которые могут быть установлены каким-либо про- цессом, а также тех, которые может попытаться установить для той же области другой процесс. Нам известны шесть различных режимов использования, и поэтому мы получаем матрицу 6x6, состоящую из элементов «Да» и «Нет», которые указывают, допустима или недопус- тима следующая попытка открыть ту же область. Самая первая (по , времени) попытка какого-либо процесса открыть некоторую область всегда успешна независимо от режима использования. Следующий оператор READY Режимы монопольный защищенный неограниченный Первый оператор READY выборка обновле- ние выборка обновле- ние выборка обновив» ние Монополь* Выборка Нет Нет Нет Нет Нет Нет НЫЙ Обновление Нет Нет Нет Нет Нет Нет Защищен- Выборка Нет Нет Да Нет Да Нет ный Обновление Нет Нет Нет Нет Да Нет Неограни- Выборка Нет Нет Да Да Да Да ченный Обновление Нет Нет Нет Нет Да Да 139
Таблица конфликтов приводится из отчета РГБД (с. 250). К сожа- лению, в «Журнале развития Кобола» эта таблица, имеющая особен- но важное значение для учебного пособия, не приводится. Смысл указания «Да» предельно ясен, но что касается недопусти- мости открытия области из-за конфликта с предшествующим откры- тием для другого процесса, то этот вопрос требует дополнительного пояснения. В ответе РГБД по этому поводу отмечается, что (с. 250, несколько измененное правило 14) «любая попытка выполнить оператор READY, вызывающий конфликт режима использования некоторой области, приводит к тому, что пытающийся выполнить данный оператор про- цесс переходит в состояние ожидания». Здесь имеется в виду, что состояние недопустимости выполнения оператора READY является лишь временным. Что делать с процес- сом, находящимся в «состоянии ожидания», — полностью оставляет- ся на усмотрение разработчика. Возможно, ожидающие некоторую область процессы ставятся в очередь и при освобождении этой области (т. е. закрытии ее в использующем процессе) выбираются из очереди для выполнения по принципу «первый вошел — первый выбран». В подобной ситуации могут также применяться различные приори- тетные схемы, но мы их рассматривать не будем, так как эта проблема выходит за рамки тематики настоящей книги. Можно предложить и другой способ общего представления режимов одновременного доступа, а именно список допустимых комбинаций тех режимов, которые могут сосуществовать в данный момент времени. В первой (левой) позиции этого списка мы будем указывать режим ис- пользования первого обратившегося к области процесса, во второй — остальные допустимые режимы. Символ пх означает, что допускается любое число процессов с данным режимом. 1. Монопольная выборка. 2. Монопольное обновление. 3. Защищенная выборка 4. Защищенное обновление 5. Неограниченная выборка — пх пх пх Неограниченное обновление — пх Пх — пх Защищенная выборка. пх Неограниченная выборка. — пх : Неограниченная выборка. Защищенная выборка. Неограниченная выборка. Неограниченное обновление. Неограниченная выборка. Неограниченное обновление. Сравнение данной «таблицы сосуществования» с приведенной ра- нее таблицей конфликтов показывает, что эти представления эквива- лентны. 14.2.6. Открытие нескольких областей До сих пор мы рассматривали проблему открытия областей, счи- тая, что один оператор READY открывает одну область. Однако, как видно из синтаксиса данного оператора, его действие может относить- ся сразу к нескольким областям, что несколько усложняет ситуацию. В таких случаях применяется следующее простое семантическое 140
правило* Если оператор READY относится к нескольким областям, то он должен быть выполним для всех этих областей. Если хотя бы для одной из них возникает конфликт режимов, то.оператор не выполня- ется, и процесс переводится в состояние ожидания. Выше отмечалось, что вариант оператора READY, включающий типы набора, почти нигде не был реализован. Впрочем, его смысл очевиден. Если программист напишет READY СДО (СДО — имя типа набора, см. рис. 3.6) и если три типа записи СЛУ- ЖАЩИЙ, ДОЛЖНОСТЬ и ОБРАЗОВАНИЕ расположены в различ- ных областях, то будет сделана попытка открыть все три области. Заметим, что все области, явно или неявно открываемые операто- ром READY, должны быть включены в подсхему данной прикладной программы. Кроме того,, открытие области не означает, что последую- щие операторы ЯМД могут обрабатывать в ней записи. Для этого со- ответствующий тип записи должен быть включен в используемую под- схему. Если тип записи приписан к двум или более областям, то вполне возможно, что лишь часть из них включена в подсхему. В том случае, когда такой тип записи является членом типа набора, для которого выполняется оператор READY, открываются не все области, к кото- рым приписан этот тип записи, а только включенные в подсхему, 14.2.7. Тупиковые ситуации Если в некотором процессе требуется открыть две или более облас- тей в режиме, отличном от неограниченного, и если одновременно вы- полняемый процесс также пытается открыть две или более областей, то имеется вероятность возникновения тупиковой ситуации (dead- lock). Эту ситуацию образно называют «смертельным объятием». Тупиковую ситуацию лучше всего пояснить на примере двух про- цессов, пытающихся открыть области X и Y для монопольной выборки. Время Т Процесс А 1 READY X USAGE-MODE EXCLUSIVE 2 3 READY Y USAGE-MODE EXCLUSIVE 4 Процесс В READY Y USAGE-MODE EXCLUSIVE READY X USAGE-MODE EXCLUSIVE Проблема состоит в том, что если указанные выше операторы в мо- менты времени 1 и 2 будут выполнены, то попытка процесса А в момент Т-3 открыть Y окажется безуспешной и процесс А ставится в очередь ожидания. Управление передается процессу Вив момент ТА попытка открыть область X также является безуспешной, так как процесс А уже «захватил» эту область. Таким образом, данные процессы попа- 141
дают в тупиковую ситуацию. Ни один из них не может продолжить вы- полнение, пока другой не освободит требуемую область. Существует несколько решений этой проблемы. Самое простое сос- тоит в определенной дисциплине программирования. Вместо двух опе- раторов READY программисту следует написать лишь один; READY X, Y USAGE-MODE EXCLUSIVE Другими словами, программист должен писать по возможности меньше операторов READY, учитывая, что каждый из них может оп- ределить только один режим использования. Кроме того, ему следует избегать излишнего открытия и закрытия областей в процессе выпол- нения программы. В некоторых реализациях указанная проблема решается путем разработки специальной системной программы, контролирующей дей- ствия всех процессов. Когда такая программа обнаруживает, что не- который процесс находится в состоянии ожидания дольшз определен- ного периода времени, она распознает и ликвидирует тупиковую ситуа- цию. 14.2.8. Возможные исключительные состояния базы данных Так как в настоящей книге впервые подробно обсуждается один из операторов ЯМД, мы здесь сформулируем методику представления ис- ключительных состояний базы данных. Попытаемся представить исключительные состояния, идентифици- рованные как РГБД, так и РГЯБД, используя тексты, которыми ра- бочие группы определяли эти состояния. В тех случаях, когда какой- либо текст окажется не вполне соответствующим нашим целям, мы предложим альтернативный вариант. Исключительные состояния, связанные с вопросами контроля доступа, будут рассматриваться в главе, посвященной управлению доступом. В «Журнале развития Кобола» идентифицируются четыре не свя- занных с контролем доступа исключительных состояния, которые мо- гут возникнуть при выполнении оператора READY; 1. Обращение к недоступной области. 2. Область в режиме готовности. 3. Конфликт режима использования в одновременно исполняемом процессе. 4. Исчерпано пространство СУБД. Не вполне ясно, как при выполнении оператора READY может возникнуть первое из перечисленных состояний. Это состояние, ско- рее, относится к другим операторам ЯМД, связанным с иерархичес- ким критерием выбора набора (см. параграф 8.6.). Второе исключительное состояние было бы правильнее определить как «область уже открыта для данного процесса». Именно это, по-ви- димому, и имелось в виду. Возникновение такого состояния, очевид- но, связано с ошибкой в программе, в результате которой управление было передано опять на ее начало. В подобной ситуации естественно прекратить исполнение процесса. 142
Третье исключительное состояние встречается чаще других. Дей- ствия, которые должны быть предприняты в этом случае, оставляют- ся, как правило, на усмотрение программиста. Четвертое состояние связано с открытием области для обновления (независимо от режима одновременного доступа). Однако РГЯБД предполагает, что оно может возникнуть при выполнении любого опе- ратора ЯМД. Очевидно, критической является ситуация, когда это состояние обнаруживается впервые, что возможно лишь при выполне- нии модифицирующих ЯМД-операторов, таких, как STORE, MODIFY или CONNECT. Вероятность появления данного состояния при дру- гих операторах ЯМД остается неясной. 14.3. ОПЕРАТОР FINISH Оператор FINISH (ЗАКОНЧИТЬ, ЗАКРЫТЬ), который обозна- чается так же, как CLOSE, значительно проще оператора READY. Его синтаксис имеет вид (с. III—12—31): FINISH ([имя-набора-1}... ------ ([имя-области-1]... В отношении использования имен наборов можно привести те же рассуждения, что и для оператора READY. После выполнения опера- тора FINISH все остальные операторы ЯМД не могут уже обращаться к записям в данной области. Здесь возникает проблема индикаторов текущего состояния, ука- зывающих на записи в закрываемой области. В частности, самой за- крываемой области соответствует индикатор ее текущего состояния. Для подобных ситуаций необходимо ввести какое-то регулирующее правило. Пэ предложению РГБД всем затронутым индикаторам теку- щих должны быть присвоены нулевые значения. Впрочем, если про- граммист закрывает свои области в конце программы, у него нет труд- ностей, связанных со значениями (в том числе нулевыми) индикаторов текущих. Единственное исключительное состояние, возможное при выпол- нении данного оператора, — «область не была открыта». Как и при открытии уже открытой области, такое состояние сигнализирует, как правило, об ошибке в программе, и в этом случае нужно прекратить исполнение процесса. Заметим, что если исполнение процесса прекращается вследствие возникновения иных исключительных состояний при каких-либо дру- гих операторах ЯМД, то все открытые области автоматически закры- ваются. 14.4. СИНТАКСИЧЕСКИЕ ОШИБКИ В READY И FINISH Исключительные условия базы данных возникают во время выпол- нения программы. Синтаксические же ошибки обнаруживаются, как правило, компилятором или предтранслятором. 143
Во время компиляции необходимо проверять основное синтакси- ческое правило, согласно которому все указанные области или типы набора должны содержаться в используемой подсхеме. Если компиля- тор или предтранслятор не распознает ошибку, то это приводит к из- лишнему увеличению функциональной нагрузки резидентного моду- ля СУБД.. ГЛАВА 15 ОПЕРАТОРЫ FIND И GET 15.1. ОПЕРАТОР FIND. ВВЕДЕНИЕ Оператор FIND — основной оператор в ЯМД. Чтобы выполнить какое-либо действие над записью, необходимо прежде всего ее найти. Единственное исключение из этого правила представляет собой опе- ратор STORE, который будет рассматриваться позднее. Существует несколько различных форматов оператора FIND. В отчете РГБД и в «Журнале развития Кобола» (с. Ill—12-7-12) пред- ставлено семь форматов этого оператора, причем в журнале развития форматы РГБД переупорядочены и изменен их синтаксис. В обоих слу- чаях последовательность представления выбрана, очевидно, произ- вольно и для учебного пособия не вполне подходит. Мы разделим форматы данного оператора на три категории и обсудим каждую из них в отдельности. Ссылки на номера форматов РГБД и журнала здесь будут даны следующим образом: РГБД-4 для формата 4 отчета РГБД и Журнал развития-7 для формата 7 «Журнала развития Кобола». 15.2. ОБЩИЙ ФОРМАТ ОПЕРАТОРА FIND В отчете РГБД и в «Журнале развития Кобола» данный оператор имеет следующий общий формат: FIND выр ажение-выбора-записи [ ] В квадратных скобках специфицируется необязательное выраже- ние, определяющее подавление изменения индикаторов текущего со- стояния (по терминологии РГБД) или сохранение их значений (по журналу развития). По предложению РГБД часть оператора, следующая за словом FIND, названа «выражением-выбора-записи». Это название несколько претенциозно, и может создаться впечатление, что речь идет, например, об определении логических условий выбора. Разумеется, это не так. Как уже указывалось в параграфе 13.7, в ЯМД принят принцип «одна загтись за один шаг». При каждом выполнении оператора FIND либо находится одна запись, либо не находится ни одна из записей. В процессе выполнения некоторых вариантов данного оператора мо- жет осуществляться доступ к нескольким записям, но они не пре- 144
доставляются прикладной программе после завершения выполнения этого оператора. Многие исследователи считают отсутствие множест- венного оператора FIND главным недостатком подхода КОДАСИЛ. 15.3. КАТЕГОРИИ ОПЕРАТОРА FIND Для уяснения действий оператора FIND полезно выделить следую- щие его варианты: непосредственный; относительный; повторный. к \ Необходимо подчеркнуть, что поскольку база данных расположе- на в памяти прямого доступа, то всякое обращение к ее записям мож- но было бы назвать «прямым», в связи с чем этот термин неудобен длж обозначения какого-либо класса обращений. Каждая категория оператора FIND обладает свойствами, которые программист должен учитывать при использовании данного операто- ра. Иногда эти свойства относятся к декларациям ЯОД схемы, иногда— к индикаторам текущего состояния. В любом случае программист обя- зан знать, какие типы записи и типы набора содержатся в подсхеме его программы. При рассмотрении вариантов оператора FIND мы будем указывать те свойства, которые должны учитываться программистом. Единст- венным обязательнььм результатом выполнения FIND является уста- новка значения индикатора текущей записи процесса. Кроме того, возможно также обновление остальных индикаторов, но программист может запретить это обновление. 15.4. НЕПОСРЕДСТВЕННЫЙ ВАРИАНТ FIND Непосредственный (out of the blue) вариант FIND обеспечивает доступ к базе данных безотносительно к какой-либо ранее найденной записи. Он не использует индикаторы текущего состояния, и поэтому первый выполняемый в программе оператор должен принадлежать к этой категории. К непосредственным вариантам относятся два формата оператора FIND: РГБД-3 и РГБД-5 или соответственно Журнал развития-4 и Журнал развития-2. Один из них используется только для типов запи- си с CALC-размещением. Этот формат представляет больший интерес и применяется чаще других. 15.4.1. Поиск записей по способу размещения CALC Синтаксис РГБД-5 этого варианта имеет вид: FIND имя-записи-1 RECORD Журнал развития-2 представляет несколько измененный синтак- сис: FIND ANY имя-записи-1 145
Как уже отмечалось выше, для имени-записи-1 должен быть опре- делен способ размещения CALC, который подробно обсуждался в па- раграфе 4.5. Программист должен, знать, что указанный тип записи имеет спо- соб размещения CALC. Ему также должно быть известно, из каких элементов типа записи состоит CALC-ключ. Более того, непосредст- венно перед выполнением данного варианта FIND он обязан присвоить значения элементам CALC-ключа в области записи. Мы здесь имеем дело со случаем, когда область записи используется для передачи параметров резидентному модулю СУБД. При выполнении оператора FIND обновляется значение индикатора текущей записи процесса, причем найденная запись не передается в область записи (для этого нужно выполнить соответствующий опе- ратор GET). Напомним, что для записей с CALC-размещением администратор данных может разрешить или запретить дубликаты значений CALC- ключа. Если дубликаты запрещены и в базе данных нашлась запись с заданным значением ключа, то она и является требуемой записью. Если же дубликаты разрешены и в базе данных имеется несколько записей с заданным значением CALC-ключа, то возникает вопрос: ка- кую же из них выберет непосредственный оператор FIND? На этот вопрос может быть дан вполне естественный, хотя и не- сколько произвольный ответ — будет выбрана запись с минималь- ным значением ключа базы данных. Программист должен знать, что в базе данных могут оказаться записи-дубликаты и в его распоряжении имеется средство доступа к ним. Оператор FtND, используемый для поиска записей-дубликатов некоторой непосредственно найденной записи, принадлежит к категории относительных операторов и будет рассматриваться позднее. Наконец, возможна ситуация, при которой в базе данных отсут- ствует запись с заданным значением CALC-ключа (допустимость или недопустимость дубликатов здесь не имеет значения). Такая ситуация является хорошим примером исключительного состояния базы данных, которое, очевидно, нельзя считать ошибкой программиста. Этот при- мер наглядно показывает, почему РГЯБД отказалась от термина «со- стояние ошибки», заменив его более длинным выражением «исключи- тельное состояние базы данных». Допустим, что мы имеем дело с типом записи «клиент» в системе с прямым терминальным доступом и нам требуется выяснить, имеется ли клиент по фамилии Адамс. Пользователь вводит название програм- мы, предназначенной для обработки подобного типа запросов, и зна- чение-параметр «Адамс». В программе выполняется оператор FIND и возникает исключительное состояние базы данных, после чего програм- ма проверяет наличие этого состояния и выдает правильный ответ: «Клиента по фамилии Адамс нет». Данный вариант оператора FIND представляет собой один из трех- четырех наиболее часто применяемых вариантов. Поэтому важно еще раз Подчеркнуть те свойства, которые должен учитывать программист при его использовании: 146
способ размещения типа записи; CALC-ключ типа записи; разрешены или запрещены дубликаты. Исключительные состояния базы данных, которые могут возник- нуть при выполнении оператора FIND, будут рассматриваться в кон- це главы. 15.4.2. Поиск записи в наборе Данный вариант является одним из самых сложных вариантов опе- ратора FIND. Он предоставляет программисту большие возможности и при правильном использовании может оказаться весьма полезным. Форматы синтаксиса РГБД-6 и Журнала развития-7 для этого ва- рианта различаются незначительно. В обоих случаях выделяется спе- циальный вариант формата, зависящий от индикатора текущей запи- си в типе набора. Он входит в категорию относительных и будет обсуж- даться позднее. Здесь же мы рассмотрим часть формата РГБД-6: FIND имя-записи-l VIA имя-набора-1 [USING ид-данных-1 [,ид-данных-2]...] и соответствующую часть формата Журнала развития-7! FIND имя-записи-l WITHIN имя-набора-1 [USING ид-данных-1 (,ид-данныя -2]...] ~ Именно в данном варианте оператора FIND используется критерий выбора набора, который рассматривался в гл. 8. Если выбор набора основан на значении индикатора текущей записи в типе набора, то, следовательно, мы опять имеем дело с вариантом из категории относи- тельных. Наиболее интересен случай, когда владелец указанного типа на- бора имеет способ размещения CALC (см. параграф 8.4). В этом случае дубликаты значения CALC-ключа запрещены, и программист должен задать его значения перед выполнением оператора FIND. Далее мы должны рассмотреть проблему поиска записи в выбранном наборе, Здесь возможны следующие ситуации: 1. Фраза USING не используется. 2. Ид-данных-1, ид-данных-2 соответствуют поисковому ключу. 3. Ид-данных-1, ид-данных-2 соответствуют ключу сортировки. 4. Другие варианты. В первой ситуации выбирается первая запись набора. Во второй ситуации для ускорения поиска используется поисковый ключ (см. параграф 6.10). Если выбор набора базируется на способ® размещения CALC записи-владельца, то оператор FIND выполняет- ся в два этапа. Сначала выбирается экземпляр записи-владельца, ко- торый определяет требуемый экземпляр типа набора, а затем с помо- щью поискового ключа данного типа набора в выбранном экземпляре набора находится запись, значения ключевых элементов которой сов- падают с заданными в области записи. Как и при поиске записей по способу размещения CALC (см. разд. 15.4.1), может оказаться, что 147
разрешены дубликаты значений поискового ключа. Однако в этом слу- чае нет четкого определения, какой из дубликатов будет выбран. В соответствии с правилом РГЯБД «выбирается первая запись, которая удовлетворяет этому требованию», т. е. требованию совпадения значе- ний ключевых элементов в записи со значениями в области записи. Третья ситуация предполагает последовательный перебор запи- сей-членов набора. Поскольку поиск производится по ключу сорти- ровки (или ключу упорядочения, см. параграф 6.7), он ускоряется только в том смысле, что система может прекратить перебор при дости- жении искомых значений16. В последней ситуации возможен перебор всех записей в наборе, что может потребовать значительного времени при больших наборах. 15.4.3. Поиск первой и последней записей в области Хотя эти варианты и принадлежат к категории непосредственных операторов FIND, вряд ли программист будет их использовать для поиска некоторой конкретной записи в базе данных. Однако иногда на начальном этапе последовательного поиска в области их примене- часть синтаксиса Журнала развития-4: ние целесообразно. Соответствующая /FIRST _ LAST FIND целое- 1 идентификатор-1, или РГБД-3: /FIRST LAST [имя-записи-3) WITHIN имя-области-1 FIND целое-1 и;ентификатор-1 , [имя-записи] RECORD OF имя-области-2 REALM Если программист не указывает тип записи, то тем самым он заяв- ляет, что ему безразлично, какого типа запись будет найдена, лишь бы она удовлетворяла остальной части выражения выбора записи. Этот формат позволяет программисту находить в области запись, возможно, указанного типа, с наименьшим (FIRST) или наибольшим (LAST) значением ключа базы данных. Если в операторе применяется идентификатор-!, то он подлежит определению в прикладной програм- ме или в некотором типе записи подсхемы и должен содержать положи- тельное или отрицательное целое число. Далее правила одинаковы для данного случая и для случая, когда программист явно использо- вал в операторе целое-1. Задание целого числа (непосредственное или через идентификатор) означает последовательный отсчет по возрастанию от записи с наимень- шим значением ключа базы данных или по убыванию от записи с наи- большим значением ключа. Это все еще непосредственный вариант 148
FIND, так как программисту не требуется выполнять предварительно FIND FIRST или FIND LAST и не применяются индикаторы текуще- го состояния. Вариант FIND FIRST требуется изредка в тех случаях, когда программист собирается перебрать все записи, возможно, определен- ного типа, в данной области. Этот вариант осуществляет первоначаль- ную установку соответствующего индикатора текущего состояния. При просмотре всех записей учет их взаимного расположения в об- ласти не обязателен. Остальные три варианта (с указанием LAST или целого числа) при- меняются крайне редко. Для правильного использования такого опе- ратора как FIND 13 имя-записи необходимо точно знать расположение в области записей, указанного типа и способ выделения ключа базы данный- По чсей видимости, раз- работчики разделяют это мнение, и потому вариант с указанием пози- ции записи в области на практике встречается нечасто. 15.5. ОТНОСИТЕЛЬНЫЙ ВАРИАНТ FIND Большинство вариантов оператора FIND принадлежит именно к категории относительных. Это означает, что некоторый непосредствен- ный оператор FIND (не обязательно непосредственно предшествую- щий) используется для установки начала поиска, а затем © помощью относительных операторов FIND осуществляется переход от послед- ней найденной записи к некоторой другой по какому-либо пути досту- па. Естественно, относительному оператору FIND довольно часто не- посредственно предшествует такой же относительный оператор FIND. Следовательно, общий алгоритм обработки представляет собой, как правило, инициализацию поиска с участием непосредственного FIND и следующую за ним серию выполнений относительных FIND, воз- можно, в цикле с проверкой после оператора FIND. Различают шесть относительных вариантов оператора FIND: использование связей в типе набора; поиск значения-дубликата CALC-ключа; А поиск записи-владельца с применением связи в типе набора; поиск в наборе с возможным использованием поискового ключа; поиск следующего дубликата значения поискового ключа или клю- ча сортировки; поиск следующей или предыдущей записи в области. 15.5.1. Поиск с применением связей в тиле набора Данный вид поиска использует связи, соответствующие некоторо- му типу набора, объявленному в ЯОД схемы. И в отчете РГБД, и в журнале развития этот вариант синтаксически определяется в том же формате, что и непосредственный вариант, представленный в 149
разд. 15.4.3. Он соответствует РГБД-3 и Журналу развития-4. Без указания области формат РГБД имеет вид: I FIRST LAST FIND NEXT > [имя записи] RECORD WITHIN имя-набора-l PRIOR целое-1 идентификатор-1 Прежде всего рассмотрим проблему выбора набора. Программист указывает в операторе имя типа набора, и оператор должен выполнять- ся на некотором конкретном наборе данного типа. Обсуждавшийся в гл. 8 критерий выбора набора здесь неприменим. Семантика рассмат- риваемого варианта FIND определяет выбор набора только на осно- гании значения индикатора текущей записи указанного типа набора. Это означает, что перед выполнением данного оператора FIND про- граммист должен обеспечить соответствующую установку индикато- ра. Здесь следует вспомнить о том, что индикатор текущей записи ти- па набора может указывать как владельца набора, так и одного из подсоединенных членов. Разрешив проблему выбора набора, обратимся к отдельным вари- антам приведенного выше формата. Варианты FIRST и LAST явля- ются относительными лишь наполовину. Аналогичные варианты по- иска в области мы без колебаний отнесли к непосредственным, так как в них не используются индикаторы текущего состояния. Когда же указано имя типа набора, для выбора конкретного набора исполь- зуется значение индикатора текущей в типе набора. «Первой» записью в наборе является логически непосредственно следующая (NEXT) за записью-владельцем. Если программист собирается последовательно перебрать все запи- си в наборе, то он может, во-первых, с помощью какого-либо непосред- ственного варианта FIND найти владельца набора и затем выполнить серию операторов FIND NEXT, а во-вторых, тем пли иным образом установить индикатор текущего состояния в типе набора и затем вы- полнить FIND FIRST и серию FIND NEXT. Заканчивая обсуждение варианта FIND FIRST, рассмотрим неко- торый гипотетический пример. Пусть в каком-либо наборе имеется 590 записей-членов и индикатор текущего состояния набора указывает 250-ю запись. При выполнении FIND FIRST система должна перейти от 250-го члена к первому. Она может это сделать следующим образом: 1. Если имеется указатель на владельца, то перейти по нему на владельца, а затем найти первую запись-члена. 2. При наличии указателей предыдущей записи перейти по ним до первого члена. 3. Пользуясь указателем следующей записи, дойти до последнего члена, затем перейти к владельцу, а от него — к первому члену. 4. Если применяется массив указателей, то переход к первому чле- ну осуществляется за один шаг. 150
Конкретные системы различаются по степени своей «интеллекту- альности». Высокоразвитая система способна выбрать самый корот- кий путь к требуемой записи, учитывая способ представления набора и Наличие тех или иных указателей. Программисту полезно знать, ка- ким образом система выполняет FIND FIRST, чтобы избегать приме- нения этого варианта в определенных ситуациях. Вариант FIND LAST так же редко используется для поиска з на- боре, как и для поиска в области. Читатель сам может проследить раз- личные пути перехода из некоторой точки в середине большого набо- ра к последней записи. Из всех многочисленных вариантов FIND наиболее часто приме- няется FIND NEXT. С его помощью находится запись-член, логически следующая в направлении «указателя следующей» за записью, кото- рую указывает индикатор текущего состояния в наборе. Если же этот индикатор указывает последнюю запись в наборе, то возникает исклю- чительное состояние базы данных. Исключительное состояние имеет место и в том случае, когда индикатор указывает владельца пустого набора. Оператор FIND NEXT всегда выполняется достаточно быстро. Ес- ли система хотя сколько-нибудь эффективна, то для его выполнения потребуется не более одного физического обращения к базе данных, чего нельзя сказать о варианте FIND PRIOR, который эффективно вы- полняется лишь при реализации на массиве указателей или при нали- чии указателя предыдущей записи. Однако, если применяется цепочка с одним указателем следующей записи, системе может понадобиться пройти по всей цепочке в направлении этого указателя, чтобы перейти к записи, логически предшествующей текущей в наборе. Возможность указания в данном варианте целого числа—номера записи (явно или через идентификатор) используется редко, да и не всегда реализуется в системах. Что же касается указания имени типа набора, то это весьма важно при обработке многотипных набо- ров с хронологическим упорядочением, когда записи различного типа могут перемежаться в одном экземпляре набора. Работая с типом набора, представленным на рио. 3.6, программист, желающий пропустить записи другого типа члена, т. е. ДОЛЖНОСТЬ, может написать: FIND NEXT ОБРАЗОВАНИЕ RECORD WITHIN СДО Если же он хочет обрабатывать оба типа записи, ему следует указать: FIND NEXT RECORD WITHIN СДО Необходимо заметить, что в последнем случае программист сам должен предусмотреть проверку типа найденной в результате выпол- нения данного оператора записи, так как заранее он его не знает. Синтаксис оператора GET также позволяет не указывать имя типа записи. В данном случае это будет означать, что изменится содержимое либо области записи ОБРАЗОВАНИЕ, либо области записи ДОЛЖ- НОСТЬ. Программист может осуществить проверку значений элемен- тов в соответствующих областях записи. 151
15,5.2. Поиск дубликатов В разд. 15.4.1 было указано, что в результате выполнения непосред- ственного варианта FIND для записи с CALC-размещением, при кото- ром допускаются дубликаты значений CALC-ключа, будет найдена запись с наименьшим значением ключа базы данных. Чтобы получить доступ к другим записям с тем же значением CALC-ключа, программист должен воспользоваться другим вариантом того же формата, который применялся для нахождения первого дубликата. В формате РГБД-5 он имеет следующий вид: FIND NEXT DUPLICATE WITHIN имя-записи-l RECORD и существенно упрощен в Журнале развития-2: FIND DUPLICATE имя-записи-1 Этот вариант можно использовать только в том случае, если перед ним выполнялся такой же оператор или непосредственный FIND. Система выбирает значения CALC-ключа из области указанной записи и затем находит в базе данных запись того же типа и с тем же значением CALC-ключа, но с большим следующим значением ключа базы данных по отношению к текущей записи. Хотя в спецификациях об этом не упоминается, речь здесь, очевидно, идет о том, что для об- легчения перехода от одного дубликата к другому записи-дубликаты должны быть каким-то образом связаны. Решение этой проблемы вхо- дит в функции разработчика системы. Если он не примет соответствую- щие меры, то использование данного варианта может привести к зна- чительному росту времени выполнения программ. В заключение отметим, что следует обратить особое внимание на правило, согласно которому FIND выполняется относительно теку- щей записи процесса, а не относительно записи, расположенной в об- ласти записи указанного в операторе типа. Если программист обра- батывает два типа записи со способом размещения CALC, то он должен тщательно следить за порядком выполнения операторов FIND для этих типов записи. 15.5.3. Поиск записи-владельца Данный вариант — самый простой из всех семи вариантов опе- ратора FIND. Он заслуживает отдельного формата и представлен РГБД-4 и Журналом развития-6. Его формат в РГБД-4 имеет вид: FIND OWNER RECORD OF имя-набора-l SET Формат РГЯБД-6 несколько короче: FIND OWNER WITFIIN имя-набора-l Как и при обсуждении варианта, представленного в разд. 15.5.1, нам прежде всего следует решить проблему выбора набора. Решение здесь должно быть тем же, т. е. нужно использовать индикатор теку- щей записи в типе набора. Критерий выбора набора (см. гл. 8), опре- деленный в ЯОД схемы, в этом случае неприменим. 152
Мы рекомендуем читателю вновь обратиться к параграфам 5.4 и 5.5, где рассматривались цепочки с указателем владельца и массивы указателей. Программист может применять оператор FIND OWNER, независимо от того, имеется ли прямой доступ от записи, указанной индикатором текущего состояния в типе набора, к записи-владельцу. Однако скорость выполнения оператора, очевидно, зависит от наличия прямого пути доступа. Для выполнения функции FIND OWNER РГБД предложила еще несколько вариантов. РГБД-2 имеет вид: FIND [OWNER IN имя-набора-3] CURRENT OF имя-записи-l RECORD' имя-набора-l SET имя-области-l REALM RUN-UNIT Фраза «OWNER IN имя-набора-3» является необязательной. Ес- ли она опущена, то данный формат соответствует нескольким вариан* там третьей категории. При использовании этой фразы возникает че* тыре дополнительных варианта, семантика которых довольно сложна/ По-видимому, в связи с этим РГЯБД полностью от них отказалось. За- метим, что если имя-набора-3 и имя-набора-1 в приведенном формате совпадают, то мы получаем вариант, эквивалентный обсуждавшему- ся в начале настоящего раздела. 15.5.4. Поиск в наборе Этот вариант тесно связан с непосредственным оператором, кото- рый рассматривался в разд. 15.4.2. Фактически он представляет со- бой иной вариант того же самого формата (РГБД-6 и Журнал разви- тия-7): FIND имя-записи-1 VIA [CURRENT OF] имя-набора-1 [USING ид-данных-1 [,ид-данных-2]...J или FIND имя-записи-l WITHIN имя-набора-1 [CURRENT] [USING ид-данных-1 [,ид-данных-2]...] Следует заметить, что если для имени-записи-1 в имени-набора-1 выбор набора определен по индикатору текущего состояния в наборе, то можно опустить фразу CURRENT OF или CURRENT и смысл оператора при этом не изменится. Однако если выбор набора осуществ- ляется по другому критерию и фраза CURRENT используется, то она отменяет критерий выбора набора, специфицированный в схеме. В том случае, когда выбор набора осуществляется по индикатору текущего состояния, мы считаем данный вариант оператора относи- тельным, так как он зависит от записи, ключ базы данных которой на- ходится в индикаторе типа набора. 153
Необязательная фраза USING играет здесь такую же роль, как и в варианте, рассмотренном в разд. 15,4.2. Интересно, однако, срав- нить различные способы выполнения оператора. Предположим, что индикатор текущего состояния в наборе опять указывает на 250-ю запись в сортируемом наборе, имеющем 500 запи- сей-членов, и что идентификаторы фразы USING соответствуют ключу сортировки, но не соответствуют ни одному поисковому ключу. Про- граммист присваивает некоторые значения элементам, перечисленным в операторе. Пусть эти значения соответствуют 300, 301 и 302-й запи- сям набора, хотя ни программист, ни система об этом не знают. Разумная система сравнит искомые значения со значениями в запи- си, на которую указывает индикатор текущего состояния. В нашем случае искомые значения превышают (в смысле порядка сортировки) значения в текущей записи набора. Поэтому система должна «продол- жить» поиск от текущей записи к следующей и т. д., пока не дойдет до 300-й записи, на которой и остановится. Менее разумная система может начинать каждый поиск от записи-владельца, причем для получения доступа к послед- ней иногда требуется последовательно пройти от текущей записи по всей оставшейся части набора. Таким образом, рассматриваемый вариант оператора, бесспорно, эффективен лишь в том случае, когда указанные в нем элементы со- ответствуют поисковому ключу. Собственно, именно использование в данном варианте и оправдывает существование поисковых ключей. Если же соответствия нет, то применение этого варианта имеет гораз- до меньшее значение. Осуществляя поиск в наборе, программист должен учитывать сле- дующее: установку индикатора текущей записи в типе набора для выбора нужного набора; соответствие элементов в операторе поисковому ключу, ключу сор- тировки или отсутствие соответствия; возможность содержания в наборе нескольких записей с одинако- выми значениями указанных элементов. В последнем случае нужно помнить, что здесь применимы все три известных способа контроля дубликатов. Для поисковых ключей и ключей сортировки это очевидно, но администратор данных имеет также возможность запретить дубликаты значений определенных элементов записей в хронологическом типе набора независимо от на- личия поисковых ключей17. Если дубликаты допускаются, то программист должен учитывать этот факт и иметь средство их выборки, которое обсуждается в сле- дующем разделе. 15.5.5. Поиск дубликатов в наборе Как РГБД, так и журнал развития предусматривают отдельный формат для поиска записей-дубликатов в наборе. В журнале развития данный формат представлен раньше, чем вариант, который обсуждал- 154
ся в предыдущем разделе книги. Такая последовательность представ- ления затрудняет его восприятие, но мы постарались исправить это положение. Для поиска записей-дубликатов используются форматы РГБД-7: FIND NEXT DUPLICATE WITHIN имя-набора-l USING ид-данных-1 [,ид-данных-2]... и Журнал развития-3: FIND DUPLICATE WITHIN имя-набора-l USING ид-данных-1 [,ид-данных-2]... Здесь фраза USING уже не является необязательной, как это было в варианте, рассмотренном в разд. 15.4.2 и 15.5.4. При совпадении указанных в формате элементов с поисковым клю- чом или ключом сортировки действие данного оператора очевидно. В обоих случаях следующая запись-дубликат будет найдена доста- точно быстро. Если же эти элементы не соответствуют ни поисковому ключу ни ключу сортировки, то складывается менее определенная ситуация. В журнале развития указывается, что «система начинает поиск идентифицированной записи с текущей записи типа набора # продолжает его в порядке, определяемом критерием упорядоченности данного типа набора». Заметим, что это правило сформулировано без учета той роли, ко- торую играют перечисленные в формате элементы. Такой подход со- вершенно неприемлем при соответствии элементов поисковому ключу, но вполне оправдан в двух других случаях. Целесообразно рассмотреть еще одну проблему, касающуюся дан- ного формата. Если уж программист решился пойти на издержки, свя- занные с определением и ведением индекса поискового ключа, то он вправе воспользоваться всеми преимуществами, которые может пре- доставить это средство. Имеется вариант FIND, позволяющий с по- мощью поискового ключа найти требуемую запись в определенном на- боре, не обращаясь предварительно к другим его записям. Кроме то- го, предусмотрена возможность доступа к дубликатам только что най- денной записи. Тут, впрочем, уместен вопрос: что происходит при по- пытке найти следующий дубликат, когда дубликатов больше нет? От- вет очевиден — возникает исключительное состояние базы данных. Однако программисту может понадобиться обработать записи со зна- чениями элементов, большими, чем в последней найденной. Иными словами, он может захотеть перебрать записи в наборе в порядке воз- растания значений элементов поискового ключа. Эго вполне вероят- но, если индекс поискового ключа реализован, например, с помощью метода доступа ISAM. Но в существующих спецификациях такой спо- соб обработки не предусмотрен. Иногда желательно располагать подобным типом обработки, осно- ванным на способе размещения CALC, но он также не допускается, поскольку CALC исторически подразумевает рандомизацию, а не ис- 155
[имя-записи-2] WITHIN имя-области-1 FIND пользование индексов. По-видимому, недопустимость последователь- ной обработки при рандомизации каким-то образом повлияла на то, что эту возможность не предусмотрели и для индексированных поисковых ключей. 15.5.6. Поиск следующей или предыдущей записи в области Последний вариант из категории относительных FIND обеспечи- вает обработку на физическом уровне. Он связан с непосредственным оператором, рассмотренным в разд. 15.4.3, и синтаксически представ- ляет собой другой вариант того же формата. Синтаксис РГБД-3 в этом случае имеет вид: [NEXT] FIND ~ г [имя-записи-2] RECORD ---- |PR1QIM —-------- OF имя-области-1 REALM а соответствующий синтаксис Журнала развития-4 — вид: : NEXT PR IOR При явном указании имени-записи-2 оператор находит запись данного типа со следующим большим (NEXT) или меньшим (PRIOR) значени- ем ключа базы данных по отношению к записи, определяемой индика- тором текущей в области. Искомая запись не обязательно должна быть того же типа, что и текущая в области, хотя чаще всего программист подразумевает именно это. Обсуждаемый вариант имеет два применения. Во-первых, он ис- пользуется для быстрого и эффективного поиска всех записей некото- рого типа в какой-либо области. Такой поиск может потребоваться, ес- ли типы набора, в которых запись присутствует в качестве члена, не соответствуют критерию поиска. При этом программисту достаточно лишь знать, какие типы записи включены в область и совершенно не важно, каким образом они в ней размещаются. Во-вторых, данный вариант весьма полезен при работе «на физи- ческом уровне», когда программисту известно расположение записей в области, определяемое, скорее, через ЯУВН, чем через ЯОД схемы. Записи здесь могут обрабатываться на основании более сложных кри- териев выбора, чем в предыдущем случае. 15.6, ПОВТОРНЫЙ ВАРИАНТ FIND Операторы данной категории находят запись, которая была уже найдена в некоторый предшествующий момент времени, как правило, в том же самом процессе. Отсюда следует, что значение ключа базы данных указанной записи должно быть сохранено в некотором регистре системы или программы. Регистрами системы, предназначенными для запоминания значений ключа базы данных являются, очевидно, индикаторы текущего состоя- ния, но их значения может устанавливать лишь сама система. Програм- ме
мисту не предоставляется явная возможность засылки в индикатор те- кущего состояния определенного значения, но он может обеспечить это другими средствами. Администратор данных может определять в типах записи базы дан- ных элементы типа ключа базы данных (см. параграф 9.4). Такая воз- можность была предусмотрена, по-видимому, для сохранения ключей базы данных в самой базе данных — опасная практика, которая не по- лучила одобрения. В «Журнале развития Кобола» теперь рекоменду- ется определять элементы данных типа ключа базы данных в секции рабочей памяти. При любом способе определения элементов типа ключа базы дан- ных программист имеет возможность с помощью некоторого варианта оператора ACCEPT (ПРИНЯТЬ) перемещать содержимое любого ин- дикатора текущего состояния в один из таких элементов. Повторные операторы FIND, естественно, распадаются на два класса. В первый входят операторы, базирующиеся на системных ре- гистрах, во второй — базирующиеся на элементах данных программы пользователя. В первом классе подразумевается использование инди- каторов текущего состояния, и мы будем его рассматривать именно с этой точки зрения. 15.6.1. Поиск по значениям индикаторов текущего состояния Если какой-либо индикатор текущего состояния содержит ключ базы данных некоторой записи базы данных, то, следовательно, эта запись уже была найдена ранее с помощью одного из операторов FIND в том же процессе. У читателя может возникнуть вопрос: зачем нужно вновь находить уже найденную когда-то запись? Проблема состоит в том, что только один экземпляр записи каждого типа может размещаться в соответст- вующей области записи оперативной памяти. Если программисту в процессе выполнения его программы требуется часто обращаться к двум или более конкретным записям определенного типа, то он, ко- нечно, может выделить место в оперативной рабочей памяти и перемес- тить в него эти записи при первом обращении к ним. Однако соотно- шение между расходом оперативной памяти и временем обработки, как правило, таково, что программист предпочитает сохранять в опера- тивной памяти ключ базы данных записи и повторно находить ее в тех случаях, когда в этом появляется необходимость. Синтаксис РГБД-2 данного варианта имеет вид: имя-записи-1 RECORD ' FIND CURRENT OF имя-набора-l SET им я- обл а сти -1 REALM RUN-UNIT а Журнала развития-5 — вид: FIND CURRENT [имя-записи] WITHIN имя-набора-1 имя-ооласти-1 157
Без фразы WITHIN рассматриваемый вариант эквивалентен поис- ку Текущей записи процесса или текущей указанного типа записи, так что эти варианты синтаксиса РГБД здесь также учитываются. Операторы FIND приведенного выше формата предназначены для повторной установки в индикатор текущей записи процесса значения, которое он имел ранее в процессе и которое было изменено последую- щими операторами FIND. Любой выполненный оператор FIND или STORE изменяет значение индикатора текущей процесса, а также и других индикаторов, если только программист явно не «заблокировал» их изменение. При обработке сетевой структуры, содержащей несколько типов набора, программе может потребоваться пройти в ней по некоторому пути, а затем вернуться к одной из пройденных точек, чтобы выбрать другой путь. Для этого необходимо иметь возможность восстановле- ния ранее имевшегося значения индикатора текущей записи процесса. Блокировкой изменения значений индикаторов текущего состояния может пользоваться лишь достаточно опытный программист. Именно в случаях применения такой блокировки оказывается полезным ва- риант FIND CURRENT OF RUN-UNIT который обновляет ранее заблокированные значения индикаторов. Из всех вариантов данного формата наиболее существенным яв- ляется тот, который использует индикатор текущей записи в типе набо- ра. Варианты с текущей в области и в типе записи применяются гораз- до реже. 15.6.2. Поиск по значениям элементов типа ключа базы данных Наконец, мы переходим к обсуждению последнего варианта, кото- рый в отчете РГБД и в журнале развития представлен первым. Син- таксис РГБД-1: FIND [имя-записи-1] USING идентификатор-! Формат Журнала развития-1 несколько изменен для повышения наглядности: FIND [имя-записи-1]; DB-KEY IS идентификатор-1 Одно время предполагалось, что данный формат предназначен ис- ключительно для типов записи со способом размещения DIRECT. Дей- ствительно, на с. 40 отчета РГБД мы читаем: «DIRECT. Поиск про- изводится на основе уникальных идентификаторов, присваиваемых СУБД каждому экземпляру записи в базе данных. Чтобы этот метод можно было использовать, уникальные идентификаторы выбираемых записей необходимо передать СУБД из процесса, для чего они должны быть предварительно запомнены в нем». Если отвлечься от способа размещения DIRECT, то здесь хорошо объясняется, как с помощью Формата-1 осуществляется поиск запи- сей, имеющих любой из трех возможных способов размещения. 158
Программист может не указывать имя-записи-1 в том случае, ког- да он либо не знает имени типа записи, либо для него это несущест- венно, Как отмечалось в разд 15.5.1, программа при этом должна содержать проверку типа записи. Дополнительным доводом в пользу указания имени типа записи в данном и других форматах, где оно является необязательным, является то, что присутствие этих имен облегчает чтение и понимание программ. Вариант, позволяющий запоминать запись, которая была найдена в некоторый момент выполнения программы, и затем вновь находить эту запись, весьма полезен и занимает третье или четвертое место сре- ди наиболее часто применяемых вариантов оператора FIND. Он быст- ро выполняется и не создает семантических проблем. 15.7. ИСКЛЮЧИТЕЛЬНЫЕ СОСТОЯНИЯ БАЗЫ ДАННЫХ В журнале развития указаны три исключительных состояния ба- зы данных, которые могут возникать при любых форматах или вари- антах оператора FIND: 1. Область не открыта в данном процессе. 2, Произведена попытка доступа к отсутствующей записи. 3. Тип записи или тип набора не определены в подсхеме. (Последнее иногда распознается как синтаксическая ошибка.) Остальные исключительные состояния зависят от применяемого варианта оператора. К ним относятся следующие: 4. Достигнут конец набора или области. 5. Происходит обращение к недоступной области. Номер параграфа или раздела Категория и вариант оператора FIND (НАЙТИ) 4 б 6 7 8 9 10 15.4 15.4.1 15.4.2 15.4.3 Н епосред ст венные По CALC-ключу В наборе с использованием выбора набора Первую и последнюю в области X XXX X 15.5 15.5.1 15.5.2 15.5.3 15 5.4 15.5.5 15.5.6 Относительные С использованием связей типа набора Дубликат CALC-ключа Владельца В текущем наборе Дубликат в наборе Следующую или предыдущую в об- ласти X XXX X XX XX X XX X XX 15.6 15.6.1 15.6.2 Повторные По индикаторам текущего состояния По элементам типа ключа базы дан- ных X X X X 159
6. Отсутствует набор, удовлетворяющий критерию выбора набора. 7. Отсутствует запись, удовлетворяющая выражению выбора за- писи. 8. Не определена текущая запись области, типа записи или типа набора. 9. Не определена текущая запись процесса. 10. Текущая запись процесса имеет несоответствующий тип. В приведенной выше таблице показано, какие из перечисленных семи исключительных состояний (с 4-го по 10-е) могут возникнуть при выполнении рассмотренных в данной главе вариантов оператора FIND. Здесь исключительное состояние 7 не указано для тех случаев, когда в процессе выполнения FIND ему должно предшествовать дру- гое исключительное состояние. Эта таблица включена в настоящий параграф исключительно для обеспечения наглядности представления. Она не входит ни в один из отчетов КОДАСИЛ и не заимствована из спецификаций какой-либо конкретной системы. 15.8. ОПЕРАТОР GET. ВВЕДЕНИЕ Оператор GET (ВЗЯТЬ) дополняет оператор FIND и, как прави- ло, выполняется непосредственно после него. В некоторых системах в дополнение к этим двум операторам предоставляется нестандартный комбинированный оператор, объединяющий их действия. 15.8.1. Общие положения Оператор GET переносит содержимое записи, указанной индикато- ром текущего состояния процесса, в область записи, соответствующую ее типу. Конкретные действия GET зависят от реализованных разра- ботчиком в используемых программистом возможностей. Синтаксис данного оператора определяется РГБД в двух форматах. Формат. /: GET имя-записи] Формат 2: GET имя-записи: ид-данных-t [.ид-дяпных-2]... Журнал развития предлагает одна, ни в принципе эквивалентный приведенным выше формат: GET идентификатор-!]... В этом формате предполагается, что идентификатор может быть как именем элемента данных, так и именем записи. В обоих случаях имеют место два основных варианта. Первый из них относится к типу записи подсхемы в целом, второй — к элементам, групповым элементам и агрегатам, перечисленным в операторе GET. Рассмотрим сначала первый вариант. 160
15.8.2. GET без параметров Если выполняется простой оператор GET (в противоположность GET имя-записи), система прежде всего обращается к индикатору текущей записи процесса, чтобы определить, к какой записи относит- ся данный оператор. Во всех имеющихся конкретных системах запись при этом уже будет находиться в оперативной памяти, но еще не в области записи. Как правило, она размещается в системном буфере, который недоступен для прикладной программы. Теперь мы вновь должны вернуться к вопросу о преобразовании на уровне записей схемы и подсхемы, который рассматривался в па- раграфе 12.6.1. Если тип записи в схеме содержит 31 элемент, а соот- ветствующий тип записи в подсхеме только 23 элемента, то в области записи данного типа будет выделено место лишь для 23 элементов и при выполнении GET «невидимые» прикладной программе 8 элемен- тов не должны передаваться Кроме того, необходимо выполнить преобразования на уровне аг- регатов и элементов данных (см. разд. 12,6.2 и 12.6.3). В большинстве конкретных систем на этом все и заканчивается. Однако в тех редких случаях, когда мы имеем дело, например, с виртуальным элементом- копией (см. параграф 9.7), виртуальным элементом-результатом (см. разд. 10.6.2) или декодированием (см. разд. 10.6.3), выполнение оператора GET может оказаться довольно сложным и длительным про- цессом. Здесь следует учитывать фразы ON, которые можно опреде- лять для любого типа оператора и тогда они будут вызываться при каж- дом выполнении соответствующего оператора. Напомним, что значение виртуального элемента-копии не хранится вместе с остальными элементами записи в базе данных, а берется из записи-владельца при выполнении оператора GET над записью дан- ного типа. Практически это означает, что система должна обратиться к записи-владельцу. Проблема решается просто, если в типе набора, через который определяется виртуальный элемент, имеется указатель на владельца, однако в правилах это не предусмотрено. Таким образом, если тип записи подсхемы содержит виртуальные элементы-копии (или виртуальные элементы-результаты), то для вы- полнения оператора GET может потребоваться больше времени, чем для серии непосредственных перемещений в оперативной памяти с по- мощью операторов MOVE. Задание оператора GET без параметров означает, что программис- ту не известен (или для него не имеет значения) тип текущей записи процесса. После выполнения этого оператора изменится содержимое одной из областей записи, какой именно — должен проверить сам программист. Такой подход соответствует вариантам оператора FIND, представленным в разд. 15.4.3, 15.5.1 и 15.5.6, в результате выполне- ния которых индикатор текущей записи процесса устанавливается на некоторую запись неизвестного типа, впрочем, это всегда один из ти-, пов записи подсхемы. б Зак. 115 161
15.8.3. GET имя-записи Если в программе оператору GET предшествовал один из перечис- ленных выше вариантов FIND, то программист может выяснить тип найденной записи с помощью серии операторов GET имя-записи. При этом предполагается, что число возможных типов текущей записи не- велико. Действительно, при выполнении оператора GET имя-записи тип текущей записи процесса должен совпадать с указанным в опера- торе, в противном случае возникает исключительное состояние базы данных. Таким образом, программисту достаточно написать последо- вательность операторов GET имя-записи, проверяя за каждым из них наличие соответствующего исключительного состояния. 15.8.4. GET элементы Если программист указывает в операторе конкретные элементы данных типа записи, то в область записи будут перемещены только зна- чения этих элементов, групповых элементов или агрегатов. Что же происходит с остальными элементами в области записи, не перечис- ленными в операторе GET? По мнению РГБД, эти элементы прини- мают «неопределенные» значения. В журнале развития утверждается, что их значения остаются без изменений. На практике могут встре- титься оба подхода. 15.8.5. Исключительные состояния базы данных Между РГБД и журналом развития здесь имеются расхождения по поводу возможных исключительных состояний и в данном случае идеи РГБД кажутся более обоснованными. Мы же будем продолжать представление исключительных состояний в виде, не связанном ни с одним из этих отчетов. Присутствие виртуальных элементов может стать причиной воз- никновения дополнительных исключительных состояний, которые были рассмотрены выше. Однако можно назвать несколько исключи- тельных состояний, не зависящих от этих элементов: 1. Индикатор текущего состояния имеет нулевое значение. 2. Происходит обращение к удаленной из базы данных записи (имеется в виду, что запись была удалена каким-либо одновременно исполняемым процессом после того, как оператор FIND установил зна- чение индикатора текущей записи в данном процессе). 3. Текущая запись процесса не соответствует типу записи, ука- занному в операторе GET (именно это состояние обсуждалось в разд. 15.8.3). 4. Невозможно выполнить преобразование значения элемента (ли- бо стандартное преобразование, либо процедуру декодирования). Если оператор GET выполняется над виртуальными элементами, то могут возникнуть следующие исключительные состояния. 5. Запись, содержащая элемент-источник (т. е. запись-владелец), находится в области, которая не была открыта. 162
6. Текущая запись процесса не включена ни в один из экземпля- ров типа набора, указанного в определении виртуального элемента- копии. 15.9. СООТНОШЕНИЕ МЕЖДУ FIND И GET Разделение операторов FIND и GET часто вызывает недоумение у тех, кто привык пользоваться такими методами доступа, как ISAM, при которых содержимое записи становится доступным для обработки с момента ее нахождения в файле. Это разделение было предложено РГБД в соответствии с методикой, принятой в системе IDS. Оно свя- зано с тем, что довольно часто требуется выполнять оператор FIND лишь для локализации в базе данных определенной записи, т. е. без последующего применения GET. Кроме того, иногда при использова- нии GET система может выполнять некоторые редкие, но занимающие много машинного времени функции. В нескольких конкретных системах предусматривается оператор, совмещающий действия FIND и GET, который обычно называют FETCH или OBTAIN. Этот оператор не заменяет, а дополняет отдель- ные операторы FIND и GET. Как правило, о форматом оператора FIND комбинируется формат оператора GET, полностью включаю- щий тип записи подсхемы. ГЛАВА 16 ОБНОВЛЯЮЩИЕ ОПЕРАТОРЫ ЯМД 16.1. ВВЕДЕНИЕ После того как мы подробно рассмотрели оператор FIND и GET, можно перейти к обсуждению обновляющих операторов ЯМД, кото- рые в совокупности менее сложны, чем один оператор FIND. Не сле- дует забывать, что FIND является оператором, обеспечивающим пере- мещение, или, как говорят, «навигацию» по базе данных. Его основ- ная роль состоит в установке значения индикатора текущей записи процесса с тем, чтобы другие операторы могли совершать различные действия над этой записью. Операторы GET, MODIFY п ERASE име- ют одно общее свойство — они выполняются по отношению к теку- щей записи процесса. Оператор STORE с этой точки зрения отличает- ся от остальных — он действует над представлением записи в области записи указанного типа. Существует ряд правил, которые применимы при всех обновляю- щих операторах, и вряд ли стоит их повторять для каждого отдель- ного случая. В основном они сводятся к тому, что участвующая в опе- раторе область или области должны быть открыты для обновления (см. разд. 14.2.1) до начала выполнения обновляющего оператора. Это от- носится не только к области, в которой расположены записи указан- ного в операторе типа (см. параграф 4.8), но и к косвенно участвую- 6* 163
щим областям, которые могут содержать типы записи иерархического критерия выбора набора (см. параграф 8.6), или типы записи, распо- ложенные в структуре наборов «ниже» типа записи, упомянутого в об- новляющем операторе. Обновляющие операторы мы будем рассматривать в следующем по- рядке: MODIFY, ERASE, STORE, CONNECT и DISCONNECT. 16.2. ОПЕРАТОР MODIFY Оператор MODIFY (ИЗМЕНИТЬ, МОДИФИЦИРОВАТЬ) заме- няет запись, указанную индикатором текущего’состояния процесса, на запись, расположенную в области записи программы. Как и в слу- чае оператора GET, действие выполняется над всей записью или над некоторыми ее элементами. В отчете РГБД предложены следующие два формата данного оператора: Формат 1: MODIFY [имя-записи] [USING ид-данных-1 [, ид-данных-2]... J Формат 2: MODIFY имя-записи; ид-данных-3 [, ид-данных-4], [USING ид-данных-5 [, ид-данных-6]...] Необязательная фраза USING в этих форматах предусмотрена для ситуации, когда программист собирается сменить экземпляр набора, в который включена данная запись. Не совсем ясно, как выполняется вариант модификации текущей записи процесса, в котором не указано имя типа записи. Как правило, это имя должно содержаться в операторе MODIFY. Иногда оказыва- ется полезным применять формат 2, позволяющий заменить отдельные элементы записи. Значения элементов записи, не перечисленных в нем, в базе данных не меняются. В «Журнале развития Кобола» приведен другой синтаксис опера- тора MODIFY, также имеющий два формата: Формат 1: MODIFY [имя-записи] Формат 2: INCLUDING] [ALL ) ZZT------- 7-- к 11 MEMBERSHIP ONLY J [{имя-набора-l}...] MODIFY {идентификатор-1}... (ALL 1 INCLUDING -— 1 ---------- [{имя-набора-l}... ] MEMBERSHIP Эти форматы полнее предложенных РГБД, и поэтому в дальнейшем мы будем ориентироваться только на них. Назначение оператора MODIFY в данном случае состоит в том, что- бы либо изменить значения одного или нескольких элементов записи, либо исключить запись из одного набора и включить ее в другой, ли- бо выполнить обе эти функции. 164
Отсутствие в форматах необязательной фразы, заключенной в квад- ратные скобки, означает, что оператор должен только изменить зна- чения элементов данных. Заметим, что изменение содержимого записи в базе данных нужно выполнять в три этапа: 1. Найти и при необходимости выбрать из базы данных запись, ко- торая должна быть изменена. 2. Изменить значения элементов в области записи с помощью опе- раторов MOVE. 3. Заменить запись в базе данных на ее новое представление, взяв его из области записи. Оператор MODIFY применяется только на последнем этапе. Если в операторе присутствует фраза INCLUDING (ВКЛЮЧАЯ) или ONLY (ТОЛЬКО), то это означает, что запись, над которой он выполняется (т. е. текущая запись процесса), должна быть исключена из одного набора и включена в другой. А так как тип записи может быть членом нескольких типов набора, должна существовать возмож- ность спецификации типов набора, к которым применим данный опе- ратор. Такие типы набора сокращенно указываются с помощью вари- анта ALL (ВСЕ). Программист при этом должен учитывать критерий выбора на- бора каждого типа набора, явно определенного в операторе или неяв- но подразумеваемого в варианте ALL. Критерий выбора набора может быть задан в ЯОД схемы (см. гл. 8) или в ЯОД подсхемы (см. разд. 12.12.3). Чтобы обеспечить такой критерий, для каждого участ- вующего типа набора в программе должна быть предусмотрена одна из следующих операций: 1. Установка индикатора текущей записи в типе набора. 2. Засылка значения ключа базы данных в элемент, указанный в фразе определения выбора набора. 3. Установка значений CALC-ключа данного типа записи в элемен- ты, указанные в фразе выбора набора. 4. Засылка значений в элементы, определяющие иерархический путь, в соответствии со спецификациями фразы выбора набора. В формате 1 вариант ONLY означает, что изменяется только при- надлежность к набору, т. е. элементы записи в базе данных не модифи- цируются. Предполагается, что содержимое области записи в данном случае несущественно. При использовании же варианта INCLUDING изменяется как содержимое записи, так и принадлежность к одному или нескольким наборам. В формате 2 перечисляются один или несколько элементов записи, над которыми должен выполняться оператор, поэтому вариант ONLY, очевидно, не имеет смысла. 16.2.1. Возможные осложнения при выполнении MODIFY Осложнения при выполнении оператора MODIFY могут возникнуть в том случае, когда модифицируется значение элемента, играющего для некоторого типа записи в базе данных особую роль, в частности: 165
CALC-ключа; ключа сортировки (упорядочения); поискового ключа. Существуют системы, в которых не разрешается модифицировать значения элементов CALC-ключа. Если все-таки требуется внести по- добное изменение, то программа должна удалить запись из базы дан- ных и заменить ее новой. При модификации значения элемента ключа сортировки система должна изменить позицию записи в соответствующем наборе. В случае изменения значения элемента поискового ключа необхо- димое изменение должно быть внесено в индекс этого ключа. В результате выполнения MODIFY над элементами CALC-ключей, ключей сортировки и поисковых ключей не должны нарушаться огра- ничения в отношении дубликатов значений. 16.2.2. Исключительные состояния базы данных На практике при выполнении оператора MODIFY могут возник- нуть следующие исключительные состояния базы данных: 1. Индикатор текущей записи процесса имеет нулевое значение. 2. Запись-объект изменена одновременно выполняемым процессом. 3. Тип текущей записи процесса не соответствует типу записи в операторе. 4. Новые значения вызывают дубликаты значений элементов CALC-ключа, ключа сортировки или поискового ключа. 5. Новое значение элемента имеет неправильный тип. 6. Новое значение элемента не удовлетворяет фразе CHECK. 7. Область не открыта для модификации (т. е. недоступна). 8. Исчерпано пространство в области. В случае перемещения записи из одного набора в другой возмож- ны также и другие исключительные состояния: 9. Отсутствует набор, удовлетворяющий критерию выбора набора. 10. Владелец набора находится в области, не открытой для обнов- ления. ' 11. Владелец набора не включен в подсхему. 12. Неявно изменяется принадлежность к набору. IS.3. ОПЕРАТОР ERASE В спецификациях РГБД оператор, стирающий запись в базе дан- ных, получил название DELETE (УДАЛИТЬ, СТЕРЕТЬ). Этот тер- мин широко применяется для обозначения указанного действия как в системах управления базами данных, основанных на предложениях РГБД, так и в других системах. В «Журнале развития Кобола» по ре- комендации РГЯБД вместо него введен термин ERASE, поскольку слово DELETE уже используется в Коболе при удалении записи из файла в массовой памяти. В отчете РГБД и в журнале развития специфицированы четыре варианта данного оператора: один — часто применяемый, другой — 166
используемый лишь изредка, и два остальных — семантически слож- ные варианты, которые, будем надеяться, со временем выйдут из упо- требления. Варианты РГБД представлены в виде: DELETE [имя-записи] 'ONLY SELECTIVE ALL Варианты журнала развития в той же последовательности:' "PERMANENT SELECTIVE ALL ERASE [имя-записи] MEMBERS Как уже отмечалось, оператор ERASE выполняется над записью, выбираемой по индикатору текущей записи процесса. Если в этом опе- раторе содержится имя-записи, то тип текущей записи процесса дол- жен совпадать g указанным в нем типом. Если же имя-записи опуще- но, то текущая запись может принадлежать к любому типу. При выполнении любого варианта оператора ERASE в индикатор текущей записи процесса помещается нулевое значение, другие инди- каторы текущего состояния не затрагиваются. 16.3.1 . Простой ERASE Простой ERASE, не содержащий дополнительные необязательные слова, употребляется чаще других вариантов данного оператора. Он удаляет текущую запись процесса из базы данных в том и только в том случае, если она не является владельцем непустого набора. Запись- владелец такого набора не удаляется, и возникает исключительное состояние базы данных. Что происходит при удалении записей, читатель может выяснить, вернувшись к параграфам 5.5 и 5.6, где этот вопрос подробно рассмат- ривался при обсуждении цепочек. 16.3.2 . Вариант ERASE ALL Вариант ERASE ALL (УДАЛИТЬ ВСЕ) применяется гораздо ре- же, чем предыдущий. Используя данный вариант, программист должен полностью отдавать себе отчет в его действии. Так, при неправильно выбранной записи может быть стерта половина базы данных. Оператор ERASE ALL удаляет текущую запись процесса незави- симо от того, является ли она владельцем непустого набора. Собствен- но, только в этом случае и начинают проявляться специфические свой* ства рассматриваемого варианта, а именно удаляются все записи-чле- ны непустого набора. Если какая-либо из них принадлежит также не- которому набору другого типа, то для данного варианта ERASE это не имеет значения. Более того, если одна из этих записей-членов в 167
свою очередь является владельцем непустого набора, то удаляются и записи-члены этого набора, и т. д. в порядке иерархии. Каждая запись, участвующая в описанном процессе, должна при- надлежать области, открытой для обновления. Если хотя бы одна из них не удовлетворяет указанному требованию, удаление не производит- ся. Это ставит перед разработчиком определенные проблемы, так как система должна сначала тем или иным способом последовательно прой- ти по иерархии и убедиться в том, что все записи могут быть удалены, а уж затем инициировать процедуру, удаляющую записи. Заметим, что если удаляемая запись принадлежит некоторому набору, не имеюще- му отношения к выполнению данного оператора, то этот набор должен тем не мен^е целиком содержаться в областях, включенных в подсхе- му и открытых для обновления. Последнее особенно важно для набо- ров с несколькими типами членов. 16.3.3 . Вариант ERASE PERMANENT Семантика рассмотренных выше вариантов была достаточно про- стой. Действия же двух оставшихся вариантов зависят от вида допу- стимости исключения, который обсуждался в параграфе 7.3. Напом- ним читателю, что каждый член типа набора должен иметь постоян- ный или временный вид допустимости исключения (РГБД ввела для них термины «обязательный» и «необязательный»). Допустимость ис- ключения учитывается при выполнении варианта ERASE PERMA- NENT (УДАЛИТЬ ПОСТОЯННЫЕ). Текущая запись процесса удаляется здесь так же, как и в пре- дыдущих вариантах. Если она является владельцем непустого набора, то удаление^записей-членов последнего зависит от допустимости исклю- чения в данном наборе. Постоянные записи удаляются, а временные лишь исключаются из этого набора и оставляются в базе данных Вы- ражение «постоянные записи удаляются» может показаться несколько странным. Однако следует помнить, что постоянной объявляется не сама запись, а ее принадлежность к некоторому набору. 16.3.4 . Вариант ERASE SELECTIVE Данный вариант в основном аналогичен предыдущему и отлича- ется от него лишь действием по отношению к записи, являющейся временным членом набора, у которого удаляется владелец. Если эта запись принадлежит еще каким-либо наборам (естественно, другого типа), то она не удаляется. Запись, не принадлежащая никакому иному набору, удаляется из базы данных. 16.3.5 . Исключительные состояния базы данных В этом разделе, как и ранее, мы сначала перечислим наиболее часто встречающиеся исключительные состояния, а затем те, которые могут возникнуть лишь при выполнении трех последах вариантов операто- ра ERASE. 168
Итак, исключительные состояния базы данных: 1. Не определена текущая запись процесса. 2. Тип 'текущей записи процесса не совпадает с типом записи, ука- занном в операторе. 3. Область не открыта для обновления. 4. Текущая запись процесса уже удалена одновременно исполняе- мым процессом. В вариантах, действующих более чем на одну запись, возможны сле- дующие ис ключительные состояния: 5. Удаляемая или исключаемая из набора запись не находится в области, открытой для обновления. 6. Владелец удаляемой или исключаемой из набора записи не на- ходится в области, открытой для обновления. 16.4. ОПЕРАТОР STORE Оператор STORE (ЗАПОМНИТЬ , ПОСТАВИТЬ) в предложениях : РГБД и журнале развития имеет вид: STORE имя-записи [ ] Квадратные скобки здесь содержат ту же синтаксическую конструк- цию для отмены обновления индикаторов текущего состояния, что и в общем формате оператора FIND. Программист должен составить новый экземпляр записи в области записи в оперативной памяти. Затем, после некоторых подготови- тельных действий, он выполняет оператор STORE, который помещает запись в базу данных. При этом учитывается большинство деклара- ций схемы, а именно: 1. WITHIN, определяющая области, в которые может быть поме- щена запись. 2. REALM-ID, специфицирующая конкретную область, если дан- ный тип записи может находиться в одной из нескольких областей. 3. LOCATION MODE, задающая способ размещения в области. 4. Декларации типов набора, определяющие необходимость соз- дания новых наборов. 5. Декларации способа включения в наборы, определяющие не- обходимость включения данной записи в какие-либо существующие наборы. 6. Критерии выбора набора, указывающие способ выбора конкрет- ных наборов, в которые должна быть включена запись., 7. Декларации упорядочения наборов, специфицирующие точки включения записи в каждый набор. 8. Декларации поисковых ключей, определяющие необходимость модификации индексов. Кроме того, проверяются декларации допустимости дубликатов значений CALC-ключей, ключей сортировки и поисковых ключей в тем, чтобы не нарушить условие запрещения дубликатов, если оно где-нибудь задано. Наконец (если этого требует какой-либо из критериев выбора на- бора), система обращается к соответствующему индикатору текущего 10®
состояния в типе набора для определения конкретного набора, в кото- рый должна быть включена данная запись. Будем надеяться, что все изложенное выше поможет читателю ра- зобраться в процессе выполнения оператора STORE. Здесь необходи- мо заметить, что в некоторых системах предоставляется язык управ- ления размещением на внешних носителях, с помощью которого не только распределяются области на внешних носителях, но и детально контролируется способ размещения записей в этих областях, а воз- можно, и на их страницах. Подобные декларации также учитываются системой при выполнении STORE, но это вовсе не означает, что их дол- жен учитывать и программист., Попытаемся выяснить, какое воздействие оказывают на выполне- ние данного оператора некоторые наиболее существенные деклара- ции. 16 .4.1. Фраза WITHIN Если в бсеме все записи некоторого типа приписаны только к одной области, '/о программисту остается лишь открыть ее для обновления перед выполнением оператора STORE. Если же администратор данных определил размещение записей этого типа в нескольких областях (см. разд. 4.8.1), то программист должен поместить в элемент, указанный в фразе REALM-ID, имя области, которую он выбирает для размеще- ния данной записи. Разумеется, эту область также необходимо открыть для обновления. 16. 4.2. Декларации способа размещения Программист всегда обязан учитывать способ размещения записи, которую он помещает в базу данных. При нескольких способах разме- щения он должен обеспечить выполнение определенных предваритель- ных действий. Если задан способ размещения CALC, то программист должен при- своить соответствующие значения элементам CALC-ключа в области Записи. В том случае, когда дубликаты значений CALC-ключа запреще- ны, он предусматривает еще и проверку на исключительное состояние, сообщающее, что значения ключа записи уже соответствуют некоторой записи в базе данных. С другой стороны, программисту, как правило, не известны особенности применяемого CALC-алгоритма, в частности, является ли он рандомизирующим или реализован с помощью индекса. При способе размещения VIA SET в функции программиста входит установка начальных значений для алгоритма выбора набора. Возмож- но, он должен сделать то же самое и для других наборов, в которых данный ти п записи является автоматическим членом, независимо от спо- соба размещения этого типа записи. Если же тип записи имеет способ размещения DIRECT, то имеется элемент типа ключа базы данных (не обязательно в типе записи), в который программист должен поместить нулевое или некоторое до- пустимое значение ключа базы данных (см. разд. 4.6.3). В последнем 170
случае он мог бы использовать значение ключа базы данных записи, удаленной ранее в той же программе из базы данных. С другой стороны, если прогр аммист хорошо знаком с техникой выделения значений клю- чей, то он гложет сам генерировать эти значения, хотя РГБД, по-види- мому, такой метод не предусмотрен. Все-таки надежнее иметь дело с нулевым значением, так как система тогда размещает запись по своему усмотрению. А поскольку ей не приходится учитывать особенности последующей выборки, естественно предположить, что оператор в этом случае будет выполнен максимально быстро. Приведенный вариант ис- пользования способа размещения DIRECT эквивалентен определению способа размещения SYSTEM. 16. 4.3. Декларации типов набора и способов включения Тип помещаемой в базу данных записи может участвовать в качест- ве владельца или члена в произвольном числе типов набора. Для каж- дого типа набора, в котором данная запись является владельцем, сис- тема должна создать новый экземпляр набора. Последнее, возможно, и не потребует дополнительного расхода машинного времени. Для всех типов набора, в которых данный тип записи является чле- ном, система должна проверить способ включения. При ручном вклю- чении никаких дополнительных действий по отношению к набору вы- полнять не требуется, а при автоматическом запись должна быть вклю- чена в определенный экземпляр такого типа набора. Выбор этого эк- земпляра и точки включения в него специфицируется другими декла- рациями. 16. 4.4. Критерий выбора набора При автоматическом включении записи в набор система исследует критерий выбора набора (см. гл. 8). Приведенные ниже рассуждения относятся к каждому такому типу набора. Если выбор набора основан на значении индикатора текущей запи- си в типе набора, то процесс выбора выполняется очень быстро. Однако программист должен позаботиться о том, чтобы этот индикатор был ус- тановлен соответствующим образом до выполнения оператора STORE. В том случае, когда при выборе набора используется способ разме- щения владельца, программист присваивает начальные значения эле- ментам выбора, по которым выполняется неявный FIND записи-вла- дельца по CALC-ключу (см. разд. 15.4.1). При определении иерархического критерия выбора набора (см. параграф 8.6) программист задает значения выбора всего пути от точки входа до записи-владельца набора. Это сложный и предрасположенный к ошибкам метод, которым лучше не пользоваться 18. К сожалению, если администратор данных выбрал именно такой вариант, то прог- раммист вынужден им пользоваться для выполнения оператора STORE. Иначе обстоит дело при варианте оператора FIND, использующем критерий выбора набора (см. разд. 15.4.2). В этом случае программист может игнорировать иерархический выбор набора (см. разд. 15.5.4). 171
16. 4.5. Упорядоченность набора Для каждого типа набора, в котором данная запись является авто- матическим членом, система должна включить эту запись в выбран- ный экземпляр набора. Нахождение точки включения может оказать- ся весьма длительным процессом при выполнении оператора STORE. Как уже указывалось в гл. 6, упорядоченность набора является одной из самых сложных деклараций схемы, так как здесь имеется множество вариантов, по-разному влияющих на выполнение програм- мы. Впрочем, действия программиста не так уж сильно зависят от упо- рядоченности набора. Как правило, перед применением оператора STORE здесь не требуется выполнять какие-либо предварительные ус- тановки значений. Но некоторые факторы программист все-таки дол- жен учитывать. В разд. 6.2.2 указывалось, что упорядоченность набора либо опре- деляется администратором данных, либо оставляется на усмотрение программиста. В последнем случае программист вынужден принимать какие-то меры по упорядочению набора. Однако единственные два ва- рианта, имеющиеся в его распоряжении, позволяют вставлять запись в набор лишь вблизи текущей записи набора. Следует заметить, что при таком способе упорядочения бессмысленно использовать крите- рий выбора набора, основанный на чем-либо, кроме значения индика- тора текущей в типе набора, хотя это и не запрещено. Варианты, оставляющие упорядоченность на усмотрение програм- миста — INSERTION NEXT и INSERTION PRIOR (см. разд. 6.4.2) — в принципе могут не приниматься им во внимание, также как и ва- рианты, соответствующие решению администратора данных. Если же программист действительно хочет воспользоваться предоставленной ему возможностью и упорядочить набор каким-то специальным обра- зом, то он должен установить индикатор текущей записи этого типа на- бора на ту запись, рядом с которой он собирается включить новую. Одним из факторов, который программист должен всегда учиты- вать в связи с упорядоченностью набора, является возможность запре- щения дубликатов. В соответствии со спецификациями РГБД и КЯОД здесь имеются два аспекта. Администратор данных может запретить дубликаты значений ключа сортировки в некотором сортируемом типе набора (см. параграф 6.7), что часто предусматривается в конкретных системах, ио довольно редко используется. С другой стороны, РГБД (с. 131) и КЯОД (с. 3.70) позволяют администратору данных запретить дубликаты значений некоторых элементов типа записи-члена в типе набора (сортируемом или хронологическом). Эти элементы не обяза- тельно должны совпадать с ключами сортировки. Такая возможность па практике почти не реализуется. Программист должен знать, запрещены ли дубликаты значений ка- ких-либо элементов (ключа сортировки или любых других), так как в этом случае могут возникать исключительные состояния базы данных, которые он должен проверять после каждого выполнения оператора STORE. 172
16. 4.6. Поисковые ключи В разд. 6.10.3 отмечалось, что поисковый ключ предназначен для ускорения поиска записей, тогда как индекс сортируемого набора обеспечивает ускорение вставок и модификаций. Там же было предло- жено объединить эти две концепции. Если придерживаться существующих спецификаций, программисту нет необходимости как-либо учитывать существование индексов. Ему следует о них помнить лишь в связи с возможным запрещением дубли- катов значений поискового ключа. В этом случае он должен преду- смотреть соответствующую реакцию на исключительное состояние, которое может возникнуть при включении записи в набор в процессе выполнения оператора STORE. 16. 4.7. Вид. представления набора Вид представления набора, обсуждавшийся в гл. 5, является одним из основополагающих факторов в отчете РГБД. Как уже указывалось, КЯОД удалил фразу вида набора из ЯОД схемы именно потому, что программисту не обязательно знать вид представления набора. Оче- видно, применяя оператор STORE, программист никак не может вос- пользоваться таким знанием, и, следовательно, оно ему не требуется. 16. 4.8. Исключительные состояния базы данных При выполнении оператора STORE может возникнуть большее число исключительных состояний, чем при любом другом операторе. Для наглядности разделим их на три категории: начальные, состояния выбора набора и состояния включения в набор. Последние совпадают с исключительными состояниями, которые могут встретиться при вы- полнении оператора CONNECT, рассматриваемого в параграфе 16.5. На начальных стадиях выполнения оператора STORE возможны следующие исключительные состояния: 1. Область не открыта для обновления. 2. Исчерпано пространство области. 3. Нулевые значения CALC-ключа. 4. Значения CALC-ключа противоречат определению недопусти- мости дубликатов. 5. Представленное пользователем значение ключа базы данных уже занято в базе данных. 6. Пользователем представлено недопустимое значение ключа базы данных. 7. Значения некоторых элементов в записи имеют несоответствую- щий тип. 8. Значения некоторых элементов в записи не удовлетворяют фразе CHECK. Исключительные состояния могут возникать также при выборе на- бора, который осуществляется либо потрму, что задись имеет способ 173
размещения VIA SET, либо потому, что она должна быть включена в некоторый набор как автоматический член данного типа набора. К ним относятся ситуации: 9. Нет набора, удовлетворяющего критерию выбора набора. 10. В выборе набора участвует индикатор текущей записи в типе набора, содержащий нулевое значение. 11. Запись-владелец набора находится в области, не открытой для обновления. 12. Иерархический критерий выбора набора требует обращения к типу записи или типу набора, не включенным в подсхему. 13. Иерархический критерий выбора набора требует обращения к записи в области, не открытой для обновления. Если запись включается в набор (уже нормально выбранный), в котором данный тип записи является автоматическим членом, то мо- гут возникнуть следующие исключительные состояния: 14. Значения элементов ключа сортировки в записи противоречат определению недопустимости дубликатов. 15. Значения других элементов в записи противоречат определе- нию недопустимости дубликатов. 16. В наборе встречается запись, тип которой не включен в подсхе- ма. 17. В наборе встречается запись, расположенная в области, не от- крытой для обновления. 18. Точка включения в набор определяется по индикатору теку- щей записи в типе набора, содержащему нулевое значение. 19. Запись уже состоит членом выбранного экземпляра набора. 20. Члены набора не могут располагаться одновременно в постоян- ных и временных областях. 21. Значения элементов поискового ключа в записи противоречат определению недопустимости дубликатов. 16.5. ОПЕРАТОР CONNECT Из рассмотрения оператора STORE вытекает, что CONNECT (ВКЛЮЧИТЬ) берет на себя часть его функций. Оператор CONNECT выполняется над записью, которая уже присутствует в базе данных и на которую указывает индикатор текущей записи процесса. При выполнении данного оператора запись включается в некото- рый экземпляр каждого из перечисленных в нем типов набора. Выбор этого экземпляра определяется здесь исключительно значением инди- катора текущей записи типа набора. Смысл предлагаемого РГЯБД синтаксиса достаточно очевиден: г , (имя-набора-1 [, имя-набора-2] ...) CpJQNgGT [имя-записи] ТО j ALL и 1 [ Вариант с указанием имени-записи предусмотрен для той же цели, что и аналогичные варианты FIND и GET. Кстати, при таком вариан- те может возникнуть исключительное состояние, которое невозможно 174
в случае STORE. С другой стороны, исключительные состояния 14— 21 при STORE вероятны и для CONNECT. Как и при выполнении STORE, здесь нужно учитывать некоторые определения схемы. Наиболее существенными из них являются: упорядоченность наборов (см. разд. 16.4.5); поисковые ключи (см. разд. 16.4.6). Существует еще одно исключительное состояние — попытка вклю- чить запись в экземпляр набора, в котором она уже присутствует. Это состояние возможно только при CONNECT. В процессе выполнения STORE оно не возникает, так как данный оператор выполняется над совершенно «новой» записью. 16.5.1. Исключительные состояния базы данных Ниже перечислены исключительные состояния, встречающиеся при выполнении оператора CONNECT. До начала процесса выбора набора возможны следующие ситуации: 1. Текущая запись процесса не определена. 2. Текущая запись процесса удалена из базы данных одновремен- но исполняемым процессом. 3. Тип текущей записи процесса не совпадает с типом, указанным в операторе. 4. Область не открыта для обновления. Исключительные состояния, возникающие в процессе выполнения выбора набора (для каждого типа набора, указанного в операторе): 5. Не определена текущая запись набора. 6. Владелец выбранного набора не находится в области, открытой для обновления. 7. Владелец выбранного набора не включен в подсхему. И наконец, состояния, которые могут возникать в процессе вклю- чения в набор (для каждого указанного в операторе типа набора): 8. Запись уже является членом выбранного экземпляра набора. 9. Значения элементов ключа сортировки в записи противоречат определению недопустимости дубликатов. 10. Значения других элементов в записи противоречат определе- нию недопустимости дубликатов. И. В наборе встретилась запись, тип которой не включен в под- схему. 12. В наборе встретилась запись, расположенная в области, не от- крытой для обновления. 13. Члены набора не могут располагаться одновременно в постоян- ных и временных областях. 14. Значения элементов поискового ключа в записи противоречат определению о недопустимости дубликатов. 16.6. ОПЕРАТОР DISCONNECT Оператор DISCONNECT (ИСКЛЮЧИТЬ), так же как и CONNECT, выполняется по отношению к текущей записи процесса. Он позволяет исключить эту запись из нескольких указанных в операторе наборов, 175
причем з каждом случае выбор набора производится по значению ин- дикатора текущей записи в типе набора. Синтаксис РГЯБД данного оператора имеет вид: (имя-набора-1 I, имя-набора-21 . Д DISCONNECT (имя-записи] FROM j д л I Если текущая запись процесса действительно является членом вы- бранного экземпляра набора, тип которого указан в операторе, то опе- ратор DISCONNECT исключает ее из этого набора. Запись остается в базе данных, но к ней уже нет доступа через указанный тип набора. В отличие от CONNECT, при выполнении оператора DISCONNECT значения индикаторов текущего состояния не меняются, что может по- служить причиной некоторых затруднений. Если текущая запись на- бора совпадает с текущей процесса, то после исключения записи из набора индикатор текущей записи данного типа набора будет указы- вать на запись, не принадлежащую ни к одному из наборов этого типа. 16.6.1. Исключительные состояния базы данных При использовании оператора DISCONNECT для выполнения вы- бора набора могут возникнуть следующие исключительные состоя- ния: I. Текущая запись процесса не определена. 2. Текущая запись процесса была удалена из базы данных одно-- временно исполняемым процессом. 3. Тип текущей записи процесса не совпадает с типом, указан- ным в операторе. 4. Область не открыта для обновления. В процессе выполнения выбора набора (для каждого указанного в операторе типа набора) встречаются такие исключительные состояния: 5. Не определена текущая запись набора. 6. Владелец выбранного набора находится в области, не откры-, той для обновления. 7. Владелец выбранного набора не включен в подсхему. И наконец, состояние, которое может возникнуть в процессе исклю- чения записи из набора (для каждого указанного в операторе типа набора): 8. Текущая запись процесса не является членом выбранного эк- земпляра набора. ГЛАВА 17 ДРУГИЕ ОПЕРАТОРЫ ЯМД 17.1. ВВЕДЕНИЕ В настоящей главе будут рассмотрены шесть операторов, заверша- ющих представление ЯМД. Эти операторы функционально неоднород- ны, и поэтому мы их разделим на следующие категории: 173
управляющие одновременным доступом KEEP, FREE, REMONI- TOR; действующий на уровне набора ORDER; считывающий значения специальных регистров системы ACCEPT; условный IF; устанавливающий реакцию на исключительные состояния USE. 17.2. УПРАВЛЕНИЕ ОДНОВРЕМЕННЫМ ДОСТУПОМ Существует мнение, что прикладной программист ничего не должен знать о том, в какой программно-процессной среде будет выполняться его программа. В отчете РГБД и в журнале развития принята иная точ- ка зрения, согласно которой программист должен учитывать эту сре- ду, особенно если его программа выполняется в ситуации, когда один или несколько процессов (включая процесс данной программы) одно- временно обновляют записи. В том случае, когда все процессы только выбирают данные из базы данных, проблемы одновременного доступа в мультипрограммной сре- де фактически не отличаются от проблем однопрограммного пакетного режима. Трудности возникают лишь при появлении хотя бы одного об- новляющего процесса. Следует заметить, что в предложениях КОДА- СИЛ не присутствуют явно концепции «выбирающего данные» или «обновляющего» процесса, но смысл этих терминов очевиден. Для обновляющих программ РГБД ввела два оператора: KEEP (ДЕРЖАТЬ; СОХРАНЯТЬ) и FREE (ОСВОБОДИТЬ). В журнала развития в дополнение к ним указан оператор REMONITOR (ПЕРЕ- УСТАНОВИТЬ РЕЖИМ КОНТРОЛЯ). 17.2.1. Оператор KEEP Согласно отчету РГБД (с. 237) функции оператора KEEP состоят в том, чтобы «сообщать СУБД (т. е. резидентному модулю СУБД) о намерении процесса вновь обратиться к данному экземпляру записи». Другими словами, программисту предоставляется средство явно сообщать свое намерение вновь обратиться к некоторой записи. Как правило, это повторное обращение связано с выполнением одного из обновляющих операторов — MODIFY, ERASE CONNECT или DISCONNECT. Сообщение о том, что к некоторой записи будут осу- ществляться два или более обращения во время выполнения данного процесса, позволяет программисту предупредить возможные измене- ния ее одновременно выполняемым процессом между двумя после- довательными обращениями. Оператор KEEP применяется по отношению к записи, на которую указывает индикатор текущей записи процесса в момент выполнения данного оператора. Важно отметить, что пока запись является теку- щей, она подлежит действию неявного оператора KEEP. Функции KEEP в предложениях РГБД определяются следующим правилом (с. 237, правило 5): «Пока продолжается действие оператора 177
KEEP, выполненного в некотором процессе по отношению к какому- либо экземпляру записи, любая попытка изменить эту запись в ука- занном процессе будет успешной лишь в том случае, если никакой од- новременно исполняемый процесс не изменил ее с момента выполне- ния данного оператора». По существу, РГБД предложила систему предупреждения програм- миста (с помощью соответствующего исключительного состояния ба- зы данных) о том, что в промежутке между выполнением в данном про- цессе над записью оператора KEEP и до попытки выполнить над этой записью обновляющий оператор она была изменена некоторььм дру- гим одновременно исполняемым процессом. Описанный выше подход позднее подвергся модификации, и чтобы разобраться в выдвинутых «Журналом развития Кобола» идеях, не- обходимо прежде всего уяснить его концепции режима контроля до- ступа (мон иторизации) и расширенного режима контроля. Фактически, в журнале развития вместо двух предложенных РГБД состояний записи в процессе определяются следующие три; нормальное; режим контроля; расширенный режим контроля. Запись автоматически переходит из нормального режима в конт- ролируемый, когда она становится текущей записью процесса. Выпол- нение оператора KEEP согласно журналу развития переводит ее из режима контроля в расширенный режим контроля. (РГБД не делала различия между этими двумя состояниями.) Важным аспектом указанных режимов является то, что в каждый момент времени только одна запись может находиться в режиме конт- роля, в то время как в расширенном режиме контроля могут нахо- диться несколько записей. Собственно, подход журнала развития отличается от подхода РГБД только наличием этих двух состояний записи и введением свя- занной с ними терминологии. Другими словами, при попытке модифи- цировать запись, находящуюся в одном из таких состояний, может возникнуть исключительное состояние базы данных, если эта запись была изменена некоторым одновременно исполняемым процессом пос- ле установления для нее режима контроля или расширенного режима контроля. 17.2.2. Оператор FREE Оператор FREE предназначен для отмены действия оператора KEEP. В некоторых случаях требуется освободить сразу несколько записей, в связи с чем предусматриваются два варианта данного опера- тора, имеющих различные представления в предложениях РГБД и журнала развития. В отчете РГБД приведены два формата: FREE FREE ALL 178
Простой FREE (без ALL) действует по отношению к текущей записи процесса, т. е. программист часто вынужден найти запись перед тем как ее освободить. Вариант FREE ALL освобождает все записи, для которых явно выполнен оператор KEEP. Это, очевидно, исключает текущую запись процесса. Журнал развития отказался от варианта FREE по отношению к те- кущей записи процесса и предложил более полезную конструкцию: FALL ) FREE <--- г ---- (имя-записи-1 [, имя-записи-2] ...J Последний вариант позволяет перевести в нормальное состояние (в данном процессе) все записи перечисленных в операторе типов, ко- торые находились в расширенном режиме контроля. Как и в слу- чае FREE ALL, к текущей записи процесса это не относится. При использовании предложенных РГЯБД вариантов FREE дол- жна быть предусмотрена возможность освобождения всех указанных записей. В противном случае ни одна из них не освобождается. Однако в спецификациях не указано, что может помешать освобождению ка- кой-либо записи, и не выделено соответствующее исключительное со- стояние базы данных. 17.2.3. Оператор REMONITOR Как уже отмечалось, журнал развития добавил к списку ЯМД- операторов РГБД оператор REMONITOR, определив его функцию (с. III — 12—42) следующим образом: «Оператор REMONITOR пре- кращает режим контроля или расширенный режим контроля и тотчас устанавливает новый режим контроля или расширенный режим конт- роля для той же самой записи». Общий формат данного оператора: [ALL 1 REMONITOR ----- 1 r о I '— [имя-записи-1 [, имя-записи-2]...J Здесь, таким образом, предусмотрены три варианта, комбинирую- щие варианты РГБД и журнала развития для оператора FREE. Про- стой REMONITOR без дополнительных указаний действует на теку- щую запись процесса, a REMONITOR ALL и REMONITOR имя-за- писи — на все записи любых типов или на все записи перечислен- ных в операторе типов. В обоих последних вариантах текущая запись процесса не участвует. Назначение оператора REMONITOR остается неясным. Он не ме- няет состояния какой-либо затрагиваемой (или не затрагиваемой) записи. Непонятно, в каких случаях необходимо или хотя бы жела- тельно использовать данный оператор 19. 17.2.4. Заключительные замечания Предложения РГБД и журнала развития, позволяющие програм- мисту контролировать взаимодействие процессов своей программы в другими процессами, не нашли поддержки среди разработчиков сис- 179
тем. И это не удивительно: данный подход основан на том, что записи переводятся в особое состояние (режим контроля), при котором любое изменение записи в каком-либо процессе может быть обнаружено про- веркой наличия соответствующего исключительного состояния перед новым обращением к ней. Этот метод неудобен для программиста и не гарантирован от ошибок, связанных с недостаточной проверкой воз- можных исключительных состояний. Интересно отметить, что в системе DMS-1100 фирмы Univac преду- смотрены операторы KEEP и FREE: но их семантика отличается от предложен ной КОДАСИЛ. Программист здесь должен знать, что записи размещаются в областях, состоящих из определенного числа страниц с ди каково го размера. Оператор KEEP, выполняемый по отношению к текущей записи процесса, сообщает системе, что данный процесс со- бирается вновь к ней обратиться (как правило, для обновления). Си- стема при этом закрывает доступ к такой записи со стороны других процессов, блокируя страницу, на которой она расположена. Необходимость в операторе KEEP отпадает, если область была от- крыта в режиме использования EXCLUSIVE или PROTECTED (см. разд. 14.2.1). Подход фирмы Univac может несколько замедлить выпол- нение программ, но он значительно надежнее метода, предложенного КОДАСИЛ. 17.3. ОПЕРАТОР УПОРЯДОЧЕНИЯ НАБОРА Оператор ORDER (УПОРЯДОЧИТЬ) является единственным опе- ратором, который выполняется по отношению ко всему набору в це- лом. Насколько известно, он еще нигде не был реализован, но тем не менее заслуживает рассмотрения, так как представляет собой одну из важных концепций. Данный оператор аналогичен оператору SORT (СОРТИРОВАТЬ) в языке Кобол с той лишь разницей, что SORT действует над файлом, a ORDER — над экземпляром указанного в нем типа набора. Причи- на, по которой разработчики систем избегают применения оператора ORDER, состоит, по-видимому, в том, что программист почти всегда может добиться нужного результата с помощью оператора SORT. В периоде 1971 по 1976 г.,т. е. с момента опубликования предложе- ний РГБД до выхода в свет журнала развития, в оператор ORDER были внесены некоторые (в основном несущественные) синтаксичес- кие и семантические изменения. Для однозначности толкования этого пока еще не получившего распространения средства мы будем придерживаться последних спецификаций. Полный синтаксис оператора ORDER имеет вид (с. III—12—37): ORDER имя-набора [LOCALLY] |oN |KEY ' [имя-записи-1] ... RECORD-NAME • [имя-записи-1] ... DB-KEY ...... . [имя-данных-1]... 180
Его функции состоят в выборе набора указанного в операторе типа по индикатору текущей записи в типе набора и упорядочении записей- членов этого набора. Фраза LOCALLY (ЛОКАЛЬНО) определяет, будет ли установленный оператором порядок действителен только для данного процесса на время его исполнения или нет. Если указанный тип набора является сортируемым (см. параграф 6.3), то очевидно, должен использоваться вариант с LOCALLY, так как было бы неразумно позволять программисту изменять порядок набора, введенный администратором данных. Если же программисту требуется определенным образом логически упорядочить некоторый набор данного типа, чтобы оптимизировать его последующую обработ- ку в своей программе, то такая возможность допускается. В том случае, когда указанный тип набора является хронологичес- ким (см. параграф 6.4) или имеет неопределенный порядок (см. па- раграф 6.5), программист может упорядочить какой-либо экземпляр данного типа набора так, что и другие последующие выбирающие про- граммы также смогут воспользоваться этим новым порядком. Сле- дует, однако, учитывать, что всякая обновляющая программа, в ча- стности и программа, содержащая оператор ORDER, включает запи- си в «переупорядоченный» набор в соответствии с критерием, установ- ленным в ЯОД схемы, а не с порядком, определенным оператором ORDER. Присутствующая в формате фраза ON позволяет программисту указывать ключи сортировки, как и при фразе SET ORDER для сор- тируемых типов набора (см. параграфы 6.3 и 6.7). Аналогично спе- цификациям ЯОД схемы многочленные типы набора вызывают здесь некоторые осложнения, которых пользователю рекомендуется избе- гать. В качестве ключа сортировки можно использовать: имя записи; ключ базы данных записей (возможно, указанного типа); элемент данных. Применение имени записи не имеет смысла для типов набора с од- ним членом. Сортировка по значениям ключа базы данных встречается очень редко. Для многочленных типов набора желательно квалифици- ровать имя элемента данных именем записи. Синтаксис журнала развития несколько шире предложенного РГБД. Он дает программисту возможность задавать в любом поряд- ке ключи сортировки трех перечисленных выше типов. Впрочем, во- прос о реализации и использовании такой возможности остается от- крытым. 17.4. СЧИТЫВАНИЕ СИСТЕМНЫХ РЕГИСТРОВ В программе на Коболе с использованием ЯМД иногда возникает необходимость перенести в некоторую ее ячейку, например, значение ключа базы данных. В связи с этим РГБД предложила расширить дей- ствие существующего в Коболе оператора MOVE. Оператор MOVE предназначен для пересылки значений элемен- тов данных из одной определенной программистом области оператив- 181
пой памяти в другую, возможно, с одновременным преобразованием формата значения. В «Журнале развития Кобола/? вполне резонно бы- ло рекомендовано использовать в рассматриваемом. случае не MOVE, a ACCEPT (ПРИНЯТЬ, СЧИТАТЬ), что более согласуется с общими концепциями Кобола. Оператор ACCEPT применялся в Коболе для считывания из системных регистров таких величин, как дата и время. 17.4.1. Считывание значений индикаторов текущего состояния С помощью оператора ACCEPT можно пересылать два типа вели- чин, связанных с базой данных: значения индикаторов текущего сос- тояния и имена областей. В первом случае формат оператора имеет вид: г имя-записи /\CCEPT идентификатор-1 FROM имя-набор а _имя-области CURRENCY Поскольку значение, пересылаемое в элемент данных, представ- ленный идентификатором-1, им^ет формат ключа базы данных, этот идентификатор должен быть определен в ЯОД подсхемы как элемент типа ключа базы данных (см. разд. 12.12.2). Заметим, что в данном случае было бы удобно иметь возможность специфицировать элементы типа ключа базы данных в секции рабочей памяти программы (этот гопрос уже обсуждался в разд. 12.12.2). Если в операторе ACCEPT не указывать имя-записи, имя-набора или имя-области, то в идентификатор-1 переносится значение инди- катора текущей записи процесса. При указании этих имен в иденти- фикатор-1 переносится значение из соответствующего индикатора те- кущего состояния. Данный оператор удобно использовать для запоминания записей, которые были найдены в процессе выполнения программы и вновь по- требуются позднее в той же программе. Это связано с наличием форма- та 1 оператора FIND (см. разд. 15.6.2). Отмеченные два средства до- полняют друг друга и применяются, как правило, совместно. К сожалению, в сочетании с определением в типах записи базы данных элементов типа ключа базы данных рассмотренный вариант оператора ACCEPT позволяет также сохранять значения ключа в са- мой базе данных. Такой метод довольно часто может обеспечить повы- шенную эффективность выполнения программы, но вероятность оши- бок при этом столь велика, что рекомендуется им по возможности не псльзоватьс я. 17.4.2. Считывание имен областей Второй вариант оператора ACCEPT, предназначенный для работы с базой данных, представлен следующим образом: АС.СЕРТ идентификатор-2 FROM -имя-записи э имя-набора I REALM-NAME - идентификатор-3J 182
Он обеспечивает программисту возможность пересылать имя об- ласти в определенный в программе элемент данных. Область, имя ко- торой должно быть передано, указывается значением соответствующего индикатора текущего состояния. Имя области пересылается в элемент, представленный идентификатором-2, который может быть объявлен в разделе данных программы или в любом типе записи базы данных и должен быть простым буквенно-цифровым элементом данных. Если задано имя-записи, то пересылается имя области, в ко- торой расположена текущая запись данного типа. При указании име- ни-набора передается имя области, в которой расположена текущая запись этого типа набора. В том случае, когда специфицирован идентификатор-3, он должен представлять элемент типа ключа базы данных, содержащий ключ не- которой записи базы данных. При этом передается имя области, содер- жащей указанную запись. Обсуждаемый вариант оператора ACCEPT имеет крайне ограни- ченное применение. Он связан в основном с возможностью приписы- вать записи некоторого типа к двум или более областям (см. разд 4.8.1). Если тип записи приписан только к одной области, то исполь- зовать ACCEPT REALM-NAME не имеет смысла. Если же тип записи при писан к нескольким областям, то программисту может потребо- ваться выяснить, в какой области расположена запись, найденная в результате выполнения одного из вариантов оператора FIND. Имя этой области он может узнать с помощью данного варианта операто- ра ACCEPT. 17.5. ПРОВЕРКА УСЛОВИЙ БАЗЫ ДАННЫХ Оператор IF (ЕСЛИ) является одним из самых существенных в лю- бом языке программирования. Он позволяет программисту опреде- лить, что дальнейший путь выполнения его программы зависит от зна- чения некоторого условия, которое может быть истинным или лож- ным. Введение в Кобол средств, определяющих возможность работы с базами данных, потребовало расширения действия существующего оператора IF для проверки трех новых категорий «условий базы дан- ных», а именно: принадлежности к набору; наличия членов в наборе; неопределенности значений. Рассмотрим каждую из этих категорий. 17.5.1. Условия принадлежности к набору Если запись является членом или владельцем некоторого набора известного типа, то говорят, что она принадлежит данному набору. Иногда возникает необходимость проверить, принадлежит ли запись некоторому типу набора. Как видно из синтаксиса, первый вариант 183
оператора IF позволяет выяснить не только вопрос о принадлежности, но и нечто большее: IF [NOT] [измя-набора] OWNER MEMBER TENANT В спецификациях РГЯБД отмечается, что «если указано имя-на-’ бора, то невинность условия определяется лишь по отношению к дан- ному типу набора. Если же имя-набора не указано, то истинность ус- ловия определяется по отношению ко всем типам набора». Обратим внимание на то, что здесь (с. III—12—10) не сказано, вы- бирается лп участвующий в проверке набор указанного типа по зна- чению индикатора текущей записи в типе набора. Однако проверяе- мой записью является, естественно, текущая запись процесса. В данном варианте не предусматривается выбор пути доступа по имени типа записи. Существуют два варианта оператора FIND, позволяющих найти запись без указания в операторе ее типа (см. разд. 15.4.3 и 15.5.1). В этих случаях было бы полезно иметь возмож- ность определять тип найденной записи с помощью оператора IF. Иногда это можно сделать с помощью проверки условия принадлеж- ности набору, хотя такой метод выглядит несколько искусственным. 17.5.2. Условия наличия членов в наборе Название данной категории оператора IF («member conditions») предложено журналом развития (с. III—12—10). Этот вариант не следует путать с вариантом проверки на принадлежность к набору. Он позволяет проверить наличие каких-либо записей-членов (лю- бого типа) е выбранном экземпляре набора. Формат этого варианта: IF имя-набора IS [NOT] EMPTY При отсутствии NOT условие истинно в том случае, когда в на- боре (выбираемом по значению индикатора текущей записи в наборе) нет записей-членов. Если имя-набора соответствует сингулярному типу набора (см. разд. 3.4), то имеется лишь один экземпляр такого набора и системе не требуется обращаться к индикатору текущей за- писи в типе набора. 17.5.3. Условия неопределенности значений До сих пор мы избегали довольно сложного вопроса о неопреде- ленных значениях в основном потому, что эта проблема не была окон- чательно решена КЯОД и РГЯБД. КЯОД предложил (с. 3.8) внеш- ний формат неопределенной литерной константы NULL, и в различ- ных общих правилах стала часто упоминаться возможность наличия неопределенных значений элементов данных и даже присваивания таких значений. 184
Проблема состоит в том, что в существующих языках программи- рования, например в Коболе и ПЛ/1, нет встроенных средств для ра- боты с неопределенными значениями и решение, таким образом, полностью предоставляется программисту. В ситуации, когда програм- мы обработки одних и тех же данных в базе данных составляют не- сколько программистов, необходимо иметь какие-то общие рекоменда- ции. Согласно журналу развития (с. III—12—11) условие неопределен- ности позволяет выяснить, имеет ли некоторый элемент данных не- определенное значение. Формат этого условия: 1F идентификатор-1 IS [NOT] NULL Соответствующий элементу данных идентификатор-1 должен быть определен в подсхеме. 17.5Л. Еще одно полезное условие Прежде чем переходить к обсуждению оператора USE, рассмот- рим еще раз использование оператора IF для проверки правильно- сти выполнения операторов ЯМД. Этот вопрос уже частично изучал- ся в разд. 13.5. Для такой цели удобнее всего применять оператор USE. Однако большинство конкретных систем не имеют этого оператора. В подоб- ных случаях рекомендуется ставить после каждого оператора ЯМД соответствующий вариант IF. Например, IF DB-STATUS NE О Если регистр DB-STATUS отличен от нуля, то управление переда- ется блоку программы, в котором производится более детальная про- верка состояния. 17.6. ПРОВЕРКА ИСКЛЮЧИТЕЛЬНЫХ СОСТОЯНИЙ БАЗЫ ДАННЫХ Оператор USE (ИСПОЛЬЗОВАТЬ) существовал в Коболе и до вве- дения в него средств, позволяющих работать с базами данных. Пред- назначен он в основном для определения процедур обработки меток ввода-вывода и реакций на ошибки, но может использоваться и для других целей. В журнале развития предложено дополнить оператор USE двумя вариантами (с. III—7—158). Один из них служит для проверки ис- ключительных состояний базы данных, а другой — для определения процедур генерирования ключей защиты. Проблемы контроля досту- па, включая ключи защиты, будут обсуждаться в гл. 18. Синтаксис варианта оператора USE, предназначенного для рабо- ты с исключительными состояниями базы данных, имеет вид: USE FOR -DB-EXCEPTION on.[°™Ur [литерал-! 185
Оператор USE всегда должен ставиться непосредственно после заголовка секции в отделе объявлений раздела процедур. За ним следуют один или несколько параграфов процедур, которые исполня- ются только при возникновении определенных условий. В одной про- грамме может быть несколько операторов USE, каждый из которых связан со своей процедурой. Лучше всего пояснить это на примере. Многие исключительные состояния действительно свидетельст- вуют об ошибке. Другими словами, они сигнализируют об отклоне- нии от нормы, и в этих случаях, естественно, следует прекратить вы- полнение процесса. Но некоторые исключительные состояния не свя- заны с ошибками. Так, при попытке «непосредственно» найти запись по значению CALC-ключа (см. разд. 15.4.1) оператор FIND может оказаться невыполнимым просто потому, что в базе данных отсутст- вует запись с заданным значением ключа. Программист при этом от- нюдь не заинтересован в прекращении выполнения процесса. Здесь в соответствии с журналом развития (с. III-12-6) возникает исклю- чительное состояние 0502400. (Первые две цифры обозначают оператор типа FIMD, а остальные — исключительное состояние.) Если данное состояние — единственное, требующее специального вмешательства, то операторы USE могут быть написаны в виде: USE FOR DB-EXCEPTION ON 0502100, 0502400 ничего не делать USE FOR DB-EXCEPTION ON OTHER PRINT DB-STATUS, DB-RECORD-NAME, DB-REALM-NAME, DB-SET-NAME END Программист должен предусмотреть реакцию на все исключитель- ные состояния базы данных, которые могут возникнуть при выполне- нии его программы. Как правило, лишь отдельные из них нуждаются в особой обработке, как это было показано для двух состояний в при- веденном выше примере. Для всех же остальных желательно выда- вать на печать содержимое соответствующих регистров базы данных (см. разд,. 13.5). Написание процедур USE, которые ничего не делают, требует не- которой изобретательности. Журнал развития не отреагировал на это новое требование. Проблема состоит в том, что система автомати- чески передает управление процедуре USE, прежде чем перейти к выполнению оператора, следующего за оператором ЯМД. Она не мо- жет игнорировать наличие процедур USE даже в тех случаях, когда не- посредственно за оператором ЯМД стоит оператор IF. Естественным решением этой проблемы было бы разделение ис- ключительных состояний и состояний ошибки. Их концептуальное объединение является причиной многих очевидных затруднений. 186
ГЛАВА 18 СИСТЕМА КОНТРОЛЯ ДОСТУПА 18.1. ВВЕДЕНИЕ Мы рассмотрели почти все концепции отчетов РГБД и КЯОД, ко- торые вырабатывались различными комитетами и рабочими группами настолько тщательно, насколько это вообще возможно для специфика- ций синтаксиса и семантики. Единственное исключение составляет система контроля доступа (секретности или защиты доступа), которую правильнее назвать под- системой контроля доступа. Средства контроля доступа нельзя рас- сматривать как часть ЯОД схемы, ЯОД подсхемы или ЯМД. Получить общее представление об этой концепции, например из отчета РГБД, довольно трудно, так как относящиеся к ней описания и специфика- ции разбросаны по всему тексту документа. Здесь мы прежде всего попытаемся собрать воедино эти разроз- ненные описания и определения, объясним назначение концепции в целом и отдельных применяемых средств, обсудим соответствие пред- лагаемого подхода поставленным целям и, наконец, предложим не- сколько измененный подход, который, как нам кажется, в большей степени удовлетворяет различным требованиям данной проблемы. 18.2. КОМПОНЕНТЫ ПОДСИСТЕМЫ КОНТРОЛЯ ДОСТУПА Переходя к рассмотрению предложений КОДАСИЛ, предваритель- но заметим, что всякая подсистема’ контроля доступа состоит из трех частей: средств определения замков защиты; средств определения ключей; средств сравнения указанных замков и ключей. Чтобы идентифицировать моменты времени, в которые выполняется то или иное действие, нам здесь потребуются следующие понятия: момент определения замка защиты; момент определения ключа; момент сравнения ключа и замка. Следует отметить, что существует несколько видов замков и клю- чей, причем вид ключа не всегда совпадает с видом соответствующе- го замка. Кроме того, каждые замок и ключ имеют так называемую «область применимости», которая никак не связана с видом замка. Область применимости замка представляет собой часть базы дан- ных, доступ к которой регулируется этим замком. В нее может вхо- дить одно значение (т. е. один экземпляр элемента данных) или же вся база данных, все записи некоторого типа или все наборы данного типа. Наиболее простой вид замка защиты — это пароль. Обычно воз- можности современных операционных систем ограничиваются подобны- ми паролями. РГБД выдвинула концепцию существенно более разви- тых замков и ключей, но они до сих пор еще не приняты разработчика- 187
ми систем. Это, в частности, связано с тем, что одно из таких новых предложений зависит от наличия процедур базы данных, которые, как уже указывалось, нигде не реализованы. 18.3. ПРЕДЛОЖЕНИЯ РГБД ПО КОНТРОЛЮ ДОСТУПА Подход РГБД к контролю доступа в КЯОД и «Журнале развития Кобола» был изменен весьма незначительно, хотя это именно тог случай, когда следовало бы пересмотреть всю проблему заново. Здесь не имеется в виду, что идеи РГБД неприемлемы, но они яв- но неполно сформулированы и изложены. В то же время по своей сути предложения РГБД играют важную роль в данной области и стимулируют ее дальнейшее развитие. 18.3.1. Замки, определяемые в схеме Каждая статья ЯОД схемы, т. е. статья области, статья записи или статья набора (см. параграф 11.2), может включать предложе- ние PRIVACY (ЗАЩИТА), определяющее замки контроля доступа. Это предложение имеет следующий стандартный формат: PRIVACY LOCK [FOR || ||] IS L 'литерал-1 имя-замка-1 PROCEDURE и м я - п р о ij.e д у р ы -1 OR литер ал-2 имя-замка-2 PROCEDURE имя-процедуры-2 Во всех случаях оно является необязательным, но, с другой сто- роны, всегда можно определить более чем один замок для какой-либо области, типа записи или типа набора. В двойных вертикальных линиях приводится список операторов ЯМД, которые можно выполнять над определяемым элементом схе- мы, например READY и FINISH—для областей, ORDER, CON- NECT и DISCONNECT — для типа набора. Если фраза FOR (ДЛЯ), заключенная во внутренних квадратных скобках, не используется, то замок будет относиться к любой опера- ции, выполняемой над областью, типом записи, типом набора или элементом данных. Следуя спецификациям РГБД, в ЯОД схемы можно определять следующие замки защиты данных: EXCLUSIVE 1. Уровень областей — READY FOR PROTECTED RETRIEVAL U P D A1 h и функции поддержки. 188
2. Уровень записей —CONNECT, DISCONNECT, STORE, MODIFY, FIND, GET, ERASE, ERASE ONLY, ERASE SELECTIVE, ERASE ALL, 3. Уровень элементов данных—STORE, GET, MODIFY. 4. Уровень наборов—ORDER, CONNECT, DISCONNECT, FIND. Здесь нужно отметить некоторую несогласованность, связанную, вероятно, с тем, что в процессе подготовки отчета над различными уровнями работали разные члены рабочей группы. Действительно, общий формат определения замка защиты стандартизован во всем ЯОД схемы. Однако для двух операторов — READY и ERASE — можно задавать замки защиты на уровне вариантов операторов, а не на уровне самих операторов. Прежде чем перейти к рассмотрению следствий такого несоответствия, заметим, что КЯОД в своем отчете 1973 г. отменил возможность определения замков на уровне вариан- тов оператора ERASE (DELETE). В дополнение к замкам защиты данных в ЯОД схемы РГБД пре- дусмотрела также определение следующих четырех замков на уровне самой схемы: PRIVACY LOCK FOR LOCKS DISPLAY COPY ALTER OR Здесь варианты видов замков в фигурных скобках такие же, как и на уровне защиты данных. Замки ALTER (ИЗМЕНИТЬ), СОРУ (КОПИРОВАТЬ), DISPLAY (ПОКАЗАТЬ) и LOCKS (ЗАМКИ) называют функциями поддержки. (Это новый и, по всей видимости, более правильный термин для «служебных программ» или «утилит».) ALTER есть функция модифика- ции схемы, за исключением замков защиты, после ее первоначального определения, DISPLAY — функция выдачи на печать (или на видео- терминал) всего текста схемы, кроме замков защиты. Большое зна- чение имеет замок на COPY, так как с его помощью администратор данных может ограничить пользование данной схемой, точнее, кон- тролировать процесс трансляции с нее подсхем. Особо важная концепция связана с замком защиты LOCKS. Дело ; в том, что сами замки, в свою очередь, должны быть защищены зам- ками и поэтому РГБД определила функцию поддержки, которая, сог- ласно отчету «позволяет просматривать, создавать и изменять замки защиты». Лицо, обладающее ключом замка защиты замков, имеет максималь- ные возможности доступа в системе 18.3.2. Замки, определяемые в подсхеме В дополнение к замкам, определяемым в схеме, РГБД позволяет также специфицировать замки в подсхеме. Здесь важно отметить, что если указаны замки для некоторой совокупности данных .{области, 189
типа записи и т. п.) в схеме и для’той же совокупности данных в под- схеме, то замок подсхемы замещает замки схемы. Это не означает, что замок схемы вообще уничтожается, просто программы, пользующие- ся данной подсхемой, должны предоставлять ключ к замку подсхемы, а не к замку схемы. Тем самым выявляется важная роль «замка защи- ты для COPY»— единственного замка, для которого должен быть ука- зан ключ во всех случаях определения подсхем. Синтаксис РГЯБД для спецификации ключа: PRIVACY KEY IS литерал-1 имя-разработчика-1 имя-подпрограммы-1 j Виды ключей будут рассмотрены при обсуждении видов замков. Определяя подсхему, можно, кроме того, указывать замки защи- ты на уровне самой подсхемы. РГЯБД в этой части внесла значитель- ные изменения в спецификации РГБД, и поэтому мы приведем ниже оба варианта. Предложенный РГБД синтаксис ЯОД подсхемы для так называемого раздела идентификации (с. 155) имеет вид: SUB-SCHEMA NAME IS имя-подсхемы OF SCHEMA NAME имя-схемы PRIVACY LOCK FOR LOCKS DISPLAY COMPILE ALTER IS 'литерал-1 имя-замка-l PROCEDURE имя-процедурыД OR литерал-2 имя-замка-2 PROCEDURE имя-процедуры-2 PRIVACY KEY FOR COPY IS 1литеРал*3 --------- ---- ^имя-разработчика-1 Мы видим, что формат декларации замка защиты здесь совпадает с форматом в ЯОД схемы с той лишь разницей, что слово COPY за- менено словом COMPILE (КОМПИЛЯЦИЯ). Замок защиты для COMPILE в подсхеме должен быть открыт клю- чом, предоставляемым исходной прикладной программой, чтобы ста- ла возможной компиляция этой программы. В остальном функции ALTER, DISPLAY и LOCKS выполняют ту же роль на уровне подсхемы, что и на уровне схемы. В журнале развития (с. IV—4—4) в предложения РГБД внесено ряд изменений, и теперь мы имеем вместо раздела идентификации следующий раздел заголовка: 190
TITLE DIVISION SS имя-подсхемы WITHIN имя-схемы ; PRIVACY LOCK FOR INVOKING ALTERING LOCKS литерал-1 имя-разработчика-! им я -подпр огр а мм ы-1 ; PRIVACY KEY IS литерал-2 имя-разработчика-2 имя-подпрограммы-2 Функция DISPLAY здесь была опущена, но это действительно не- существенное изменение. Гораздо Важнее замена замка защиты для COMPILE на замок защиты для INVOKING (ВЫЗОВА). Правила РГЯБД четко определяют, что этот замок должен быть удовлетво- рен «для возможности исполнения процесса, содержащего данную подсхему». Замки для компиляции и вызова подсхемы в процесс имеют, как нам кажется, различные самостоятельные значения. Не совсем понят- но, почему РГБД не учла замки для вызова, а РГЯБД сознательно от- казалась от замков для компиляции. 18.3.3. Программно-определяемые ключи Выше отмечалось, что один из ключей защиты может определять- ся в ЯОД подсхемы. Замки защиты могут специфицироваться как в ЯОД схемы, так и в ЯОД подсхемы. По предложению РГБД все остальные ключи должны опреде- ляться в новом параграфе раздела идентификации Кобол-про- граммы, названном соответственно параграфом защиты. Этот па- раграф должен предшествовать всем «стандартным» операторам Ко- бола в данном разделе. Его назначение состоит в том, чтобы «уста- новить допустимость выполнения для некоторой программы и про- цесса стандартных императивных операторов ЯМД в соответствии с замками, объявленными в схеме или подсхеме». Синтаксический формат предложений определения ключей: {литерал-1 имя-разработчика-1 PRIVACY KEY FOR -EXCLUSIVE PROTECTED Exclusive PROTECTED )бласть-1 [, область-2].., REALM' \LL REALMS RETRIEVAL UPDATE -PROCEDURE IS литерал-3 идентификатор-2 OF имя-процедуры-1 литерал-2 идентификатор-1 191
Аналогичные предложения PRIVACY KEY далее определяются для типов записи, элементов данных и типов набора. Приведенный синтаксис требует объяснений. Часть из них можно получить из различных синтаксических и общих правил отчета. Прежде всего следует отметить, что если один и тот же замок опре- деляется для нескольких различных типов записи {или даже для всех типов записи) в схеме, то необходимо включать одинаковые предло- жения, специфицирующие замок защиты, в статью записи для каждо- го типа записи. В то же время, если один и тот же ключ применяется для нескольких типов записи, то это можно объявить одним предло- жением определения ключа защиты. Представляет интерес также сле- дующее синтаксическое правило: «Не допускается использование нескольких предложений, отличающихся лишь спецификацией клю- ча». Это правило, очевидно, предназначено для тех программистов, которые ставят в программе многочисленные спецификации ключей в надежде, что один из них подойдет к замку. Не менее любопытна и идея определения ключа в виде процеду- ры. Заметим, что такая процедура должна быть поименованной частью исходной программы пользователя. Замок защиты может быть про- цедурой базы данных. Существуют три способа задания «ключа-про- цедуры»: во-первых, можно указывать в предложении определения ключа литерал (т. е. литерал-2), при этом его буквенно-цифровое значение соответствует имени процедуры, во-вторых, — передавать имя процедуры через значение некоторого элемента данных про- граммы, и, наконец, в-третьих,— явно задавать имя процедуры в предложении определения ключа. В журнале развития определение всех предложений предъявле- ния ключей защиты было значительно изменено, за исключением предложения PRIVACY KEY FOR INVOKE. Последнее включается в так называемую статью подсхемы раздела данных Кобола Эта статья указывает подсхему, которую должна использовать данная Кобол-программа. Синтаксис статьи: DB имя-подсхемы WITHIN имя-схемы l;PRIVACY KEY IS литерал]. Предложение PRIVACY KEY должно использоваться в том слу- чае, если для имени-подсхемы определен замок защиты вызова, и предъявляемый ключ должен, естественно, подходить к этому зам- ку. Подход журнала развития ко всем остальным ключам защиты сос- тоит в расширении существующего механизма декларативных про- цедур, а именно предложения USE (с. III—7—159). Новый синтаксический формат весьма сложен и имеет следующий вид: 192
USE FOR PRIVACY "EXCLUSIVE I (RETRIEVAL PROTECTED (UPDATE ON FOR < имя-обл ыти-1 (REALMS [, имя-области-2] CONNECT DISCONNECT oTOR E ERASE ERASE PERMANENT ERASE SELECTIVE ERASE ALL GET MODIFY FIND ршя-запчси-1 [, имя-записи-2]...'J h0R (records I GET MODIFY STORE: j имя-пабора J [, имя-набора-2]... I | SETS J i FOR идентификатор-! [, идентификатор-2] Если используется предложение USE FOR PRIVACY, то в нем должна присутствовать хотя бы одна из необязательных фраз FOR. Кроме того, в случае, когда для доступа к данным необходимо ука- зывать ключи, это следует делать с помощью предложения USE FOR PRIVACY. В предложениях РГБД по контролю доступа не рассматривается вопрос о том, когда именно происходит сравнение ключей с замками. РГЯБД более определенно подходит к этой проблеме: «Любая конк- ретная процедура защиты вызывается выполнением оператора READY по отношению к каким-либо областям, типам записи, типам набора или элементам данных, с которыми связана данная процеду- ра». В журнале развития введен также специальный регистр (с. IH —12—3), называемый DB-PRIVACY-KEY (КЛЮЧ-ЗАЩЙ- ТЫ-БД). Следующая за USE декларативная процедура должна по- местить значение ключа в такой регистр, а исполнительный модуль СУБД затем автоматически выполнит соответствующее сравнение. Если ключ не подходит к замку, оператор READY не выполняется 7 Зах. 145 193
и возника ет исключительное состояние базы данных (см. параграф 13.5). Декларативная процедура может быть очень простой. Если в схе- ме для не которого типа записи определен замок ЗАПИСЬ-А PRIVACY LOCK IS «СЕЗАМ» т. е. замон простейшего вида, а именно литерал пли пароль, то про- граммист может написать в программе: USE FOR PRIVACY FOR ЗАПИСЬ-А MOVE «СЕЗАМ» TO DB-PRIVACY-KEY. При открытии области, содержащей записи типа ЗАПИСЬ-А, ав- томатически вызывается указанная USE процедура и с ее помощью устанавливается значение в специальный регистр защиты базы дан- ных. Следует4 отметить, что приведенный пример иллюстрирует про- стейший метод контроля доступа — достаточно ознакомиться с текс- том схемы или исходным текстом программы, чтобы узнать, что пред- ставляет собой замок защиты. Это общий недостаток замков-литера- лов. С другой стороны, преимущество литералов состоит в том, что они наглядны и легко воспринимаются пользователем. Ниже будут рассмотрены и другие виды замков. 18.4. ВИДЫ ЗАМКОВ И КЛЮЧЕЙ Как видно из синтаксиса стандартного формата замка зашиты в разд. 18.3.1, РГБД предусмотрела три возможных вида каждого замка: литерал; имя-замка; процедура базы данных 18.4.1. Замки-литералы Литерал эквивалентен знакомому всем понятию пароля. Напри- мер, для некоторого элемента данных администратор данных мо- жет написать: ЗАРПЛАТА PRIVACY LOCK FOR STORE MODIFY IS «БЕТСИ» PRIVACY LOCK FOR GET IS «КАМЕРА». Отсюда вытекает, что программист, который собирается модифи- цировать значение элемента данных ЗАРПЛАТА в некоторой за- писи, должен включить в программу две определенные РГЯБД процедуры USE, такие, как USE FOR PRIVACY ON STORE MODIFY ЗАРПЛАТА MOVE «БЕТСИ» TO DB-PRIVACY-KEY USE FOR PRIVACY ON GET ЗАРПЛАТА MOVE «КАМЕРА» TO DB-PRIVACY-KEY. 194
Здесь предполагается, что для модификации записи о элемен- том ЗАРПЛАТА мы должны прежде всего считать предыдущее зна- чение и, следовательно, предоставить ключ защиты GET. В журнале развития (g. IV—4—15) отсутствует концепция раз- личных видов ключей (а также и замков). То, что замок определен в виде литерала, не означает, что ключ должен предъявляться опи- санным выше способом. В системах прямого доступа в термина- лов процедура USE, скорее всего, будет содержать операторы за- проса о терминала значения ключа защиты, которое она затем по- местит в специальный регистр этого ключа. 18.4.2. Замки-переменные Если в ЯОД схемы определен замок защиты в виде PRIVACY LOCK IS имя-элемента то имя-элемента есть имя элемента данных, который должен со- держать значение замка защиты. Мы теперь переходим к обсужде- нию концепций, которые почти нигде не реализованы, и поэтому предлагаемая интерпретация рассматриваемых спецификаций будет носить несколько субъективный характер. Напомним, что РГБД и КЯОД предложили следующее определе- ние замка: PRIVACY LOCK [FOR [| || ] IS имя-замка-1 [OR имя-замка-2] Далее в синтаксическом правиле (с. 87) они объясняют, что «при- сутствующие в фразе PRIVACY имя-замка-1 и имя-замка-2 неявно объявляются элементами данных с характеристиками, заданными разработчиком». Комитет КЯОД лишь слегка изменил формулировку данного пра- вила (с. 3.15): «Имена-замков, указанные в фразе PRIVACY, рассмат- риваются как элементы данных с характеристиками, заданными раз- работчиком». Смысл обеих формулировок с точки зрения свойств защиты один и тот же. ЯОД схемы теперь используется не для указания константы, или литерала, явно определяемых в схеме, а для определения неко- торого элемента данных, размещаемого в базе данных или в оператив- ной памяти, из которого будет выбираться значение замка при выпол- нении какой-либо программы, обрабатывающей защищенные им дан- ные. Здесь возникают два вопроса: где размещается этот элемент дан- ных и как ему присваивается значение до выполнения процессов, об- ращающихся к защищенным данным? На первый вопрос ответ доста- точно очевиден: этот элемент данных должен быть частью объектной схемы и, следовательно, для него необходимо выделить постоянное место в памяти прямого доступа. Дальнейшее обращение зависит от того, применяется ли замок на уровне схемы или на уровне данных. Мы сначала обсудим второй случай, как более распространенный, 7* 195
т. е. рассмотрим замки, которые должны быть удовлетворены при- кладной программой во время ее исполнения, Значение такого замка должно, очевидно, определяться админи- стратором данных с помощью служебной «программы установки зам- ков» каждый раз, когда необходимо задать или сменить значение неко- торого замка этого типа. Для изменения значения замка-литерала следовало, по-видимому, изменить соответствующее предложение в схеме и повторить процесс ее трансляции. Таким образом, значения замков-переменных должны храниться в объектной схеме, а их установку и изменение нужно осуществлять с помощью специальной служебной программы. Если подсхема содер- жит данные, защищенные подобным замком, то при выполнении любой программы, использующей данную подсхему, его значение должно находиться в оперативной памяти и быть доступным подсистеме конт- роля доступа, выполняющей функцию сравнения ключей и замков. Замки защиты, определенные на уровне схемы, в основном требу- ют такого же обращения с той лишь разницей, что сравнение с клю- чом должно производиться до начала выполнения соответствующей функции. Интересно отметить, что здесь отсутствует определение средств, выполняющих функции LOCKS. Выше упоминалось о «служебной про- грамме установки замков», но не совсем ясно, идентична ли она этим средствам. Во всяком случае, следует четко различать спецификацию защиты некоторой части базы данных, которую РГБД предлагает осуществлять в схеме с помощью фраз декларации замков защиты, и установку значений замков для замков-переменных. 18.4.30 Затмки-процедуры Наконец, последний вид замка защиты — это процедура базы дан- ных. Как уже указывалось в гл. 10, сами процедуры базы данных пред- ставляют собой еще недостаточно четко определенное средство. Если же применять их в подсистеме контроля доступа, то неопределенность еще более возрастает. В то время как значения замков-переменных должны устанавли- ваться с помощью специальной служебной процедуры, значение зам- ка-процедуры задается, естественно, выполнением некоторой проце- дуры базы данных. Выходным значением процедуры является, по-ви- димому, значение замка, но знает ли пишущий ее программист, куда поместить это значение? Имеет ли процедура базы данных входные параметры и если да, то каким образом устанавливаются их значения? Если значение замка генерируется процедурно по неявно определен- ному алгоритму, то как программист или терминальный пользователь узнают, какой следует предоставить ключ? Возможно, более практичным является подход, при котором про- цедура базы данных замка-процедуры сама проверяет допустимость предъявленного ключа, а не генерирует значение замка, которое долж- но затем сравниваться с ключом в некоторой системной программе. В этом случае ключ является входным параметрОхМ процедуры зам- 196
ка защиты. Последняя может hmpi ь и другие входные параметры, та- кие, как данные идентификации лица, обращающегося к базе данных. Подобный подход вполне соответствует идеям журнала развития по поводу предложения USE FOR PRIVACY, изложенным в разд. 18.3.3. Исполнительный модуль СУБД может выяснить, является ли замок литералом, переменной или процедурой, и выполнить соответ- ствующие действия. Однако если применяется замок-процедура, то сле- дует помнить, что как процедура замка, так и процедура-ключ могут потребовать ввода дополнительных данных с терминала. В частности, нужно проследить за тем, чтобы обе процедуры не запрашивали у пользователя одни и те же данные, например, значение ключа. Еще одно замечание о замках-процедурах: им соответствует в СУБД особый класс процедур базы данных. Во-первых, исходный текст этих процедур также должен быть защищен, поскольку в противном случае опытный программист сможет легко выяснить, как следует ге- нерировать ключи к секретным данным. Во-вторых, необходимо иметь в виду, что процесс спецификации некоторого замка как замка-про- цедуры отделен от процесса определения самой процедуры. Так или иначе рекомендуется разделять работу с процедурами-замками и ра- боту со всеми остальными процедурами базы данных. 18.5. КРИТИЧЕСКИЙ ОБЗОР ПОДХОДА КОДАСИЛ К КОНТРОЛЮ ДОСТУПА Завершив изложение идей КОДАСИЛ по контролю доступа и об- судив их возможную реализацию, мы теперь можем попытаться дать общий обзор предложенного подхода и указать его недостатки. Сам факт, что предложения РГБД по контролю доступа практичес- ки нигде не реализованы, свидетельствует об отношении к ним раз- работчиков. Очевидно, это связано с тем, что контроль доступа не является определяющим для коммерческой жизнеспособности СУБД; не ясны методы реализации предложений КОДАСИЛ; можно отложить реализацию средств контроля доступа и добавить их в более поздней версии системы; операционная система уже имеет некоторые средства контроля до- ступа; разработчики понимают подход КОДАСИЛ, но считают его непри- емлемым. Каковы бы ни были причины, конкретные СУБД, базирующиеся на предложениях КОДАСИЛ, имеют лишь крайне ограниченные сред- ства контроля доступа. В последующих разделах настоящей главы мы рассмотрим четыре проблемы, связанные с изложенным выше подходом, и предложим аль- тернативное и, как нам кажется, более эффективное решение. Эти че- тыре проблемы можно сформулировать следующим образом: 1. Смешение понятий защиты данных и. определения привилегий. 2. Отсутствие четкого определения, кого следует контролировать. 197
3. Совмещение в тексте схемы предложений ЯОД и определений замков. 4. Критическая позиция замка защиты для COPY, t 18 .5.1. Защита данных и определение привилегий программиста В подходе РГБД к системе контроля доступа смешиваются два различных понятия, которые мы будем идентифицировать как защиту данных и определение привилегий. Если данные являются в той или иной степени секретными или частными, то требуется контролировать «разрешенность» их считывания или внесения в них изменений. Здесь не имеет значения, как выдаются эти данные или каким обра- зом вносятся изменения, важен лишь сам факт доступа к данным для их выборки или изменения. Следовательно, необходимо различать факт доступа и способ его осуществления. В частности, если некоторому лицу разрешается изменять данные какого-либо типа записи, то это определяется, скорее, его служебным положением, а не профессиональными навыками. Изменения может вносить и «параметрический» пользователь, вводящий значения элемен- тов данных с терминала и понятия не имеющий о строении приклад- ной программы (или даже вообще не умеющий программировать). Разделение программистов, занимающихся только выборкой дан- ных, и программистов, занимающихся их обновлением, вполне соот- ветствует двум типам защиты доступа к данным — разрешению на вы- борку данных и разрешению на их изменение. С другой стороны, нексторые программисты, независимо от того, занимаются они выборкой или обновлением данных, профессиональ- но опытнее других и им можно разрешить пользоваться более слож- ными средствами ЯМД. Видимо, именно поэтому РГБД предусмотрела различные варианты замков защиты на каждом уровне, особенно на уровне записи, и предоставила администратору данных средства за- прещения использования отдельных операторов ЯМД с помощью этих замков. Такой аспект РГБД в отношении замков защиты, очевидно, практически не связан с тем, разрешается ли программисту выбирать или обновлять данные. Далее под «защитой данных» (privacy) мы бу- дем подразумевать контроль разрешения на считывание или модифи- кацию данных, а под «определением привилегий» (privilege) — конт- роль разрешения на использование программистом тех или иных ва- риантов операторов ЯМД. Заметим, что полное определение привилегий часто требует фор- мулировки одного и того же предложения для каждой области, типа набора и типа записи, в зависимости от уровня, на котором будет про- изводиться контроль этих привилегий. Например, если администра- тор данных собирается запретить использование оператора ERASE ALL, а в схеме имеется 13 типов записи, то он должен написать 13 раз предложение RPIVACY LOCK FOR ERASE ALL IS имя-замка-7 даже если все замки одинаковы. 198
В настоящем разделе подход РГБД подвергся критике не за суть самих предложений, а скорее, за способ их представления. В частности, средства определения защиты данных с трудом распознаются среди средств контроля использования различных вариантов ЯМД. Оче- видно, и те и другие средства имеют важное значение, поэтому пред- ложенное разделение, как нам кажется, позволит более эффективно их определять и поддерживать. 18 .5.2. От кого защищаются данные? Предложение РГБД, по которому ключи защиты должны сообщать- ся в некотором параграфе программы и проверяться в момент ее ком- пиляции, свидетельствует о том, что единственным потенциальным нарушителем защиты данных в базе данных считается программист. Модификации, внесенные журналом развития, показали, что таким на- рушителем может быть и параметрический терминальный пользователь. Практически хорошая система контроля доступа должна проверять как программистов, так и терминальных пользователей. Следует от- метить, что контроль программиста с некоторой точки зрения значи- тельно труднее, так как он может написать любую программу досту- па к данным в базе данных. Тем не менее общая концепция СУБД предполагает, что прикладные программы пишутся для последующего использования различными лицами, которые просто вызывают их (в объектном коде, уже отлаженные) и предоставляют значения вход- ных параметров. Поскольку выдача программы может содержать за- щищенную информацию, рекомендуется контролировать процесс вызова такой программы. Рассмотренный в предыдущем разделе вопрос об определении при- вилегий относится, очевидно, лишь к программистам, а не к парамет- рическим пользователям, тогда как защита распространяется и на тех, и на других. Эта проблема имеет еще один аспект. Кроме программистов и пара- метрических пользователей, в эксплуатации участвует группа админи- стрирования данными, куда входят лица, отвечающие за использова- ние транслятора ЯОД подсхемы и различных служебных программ, включенных в состав современной полной СУБД. В системе должны быть предусмотрены функции контроля использования таких средств. Для подобных случаев РГБД предложила специфицировать замки за- щиты на уровне схемы. Вряд ли, однако, ЯОД схемы является под- ходящим средством их определения. 18 .5.3. Вынесение описаний замков защиты из ЯОД схемы Как было указано выше, РГБД предложила описывать замки за- щиты в статьях ЯОД схемы. Это, конечно, полезно для общего пред- ставления всех свойств некоторой области, типа записи, элемента дан- ных или типа набора. Но возникает вопрос: соответствует ли такое описание интересам управления процессами обработки и защиты дан- ных? 199
Скорее всего, замки защиты будут изменяться чаще других декла- раций схемы. В разд. 18.4.2 отмечалось, что значения замков-пере- менных изменяются еще чаще. Тот факт, что замки защиты изменяют- ся интенсивнее структурирующих объявлений ЯОД схемы, является серьезным доводом в пользу вынесения деклараций замков из ЯОД схемы. С другой стороны, это может служить аргументом и для при- менения замков-переменных, а не литералов, хотя этот довод частич- но снимается при вынесении определений замков из ЯОД схемы. Что касается вопроса защиты самих деклараций замков защиты, то здесь исходный текст схемы должен быть доступен прикладным про- граммистам, поскольку это самый простой способ сообщить им имена типов записи, типов набора, областей и другие необходимые для со- ставления программ характеристики, например способ размещения типа записи, области, к которым приписан тип записи, и т.д. Можно, конечно, построить транслятор ЯОД схемы так, чтобы он выдавал на печать описания замков лишь при специальном указании, но ведь нужно еще контролировать и ввод текста в транслятор ЯОД схемы. В последнее время КЯОД склоняется к вынесению предложений определения замков защиты в специальную «категорию» ЯОД схемы. Проблемы гибкого управления и надежного обеспечения защиты мож- но решить, лишь выделив декларации замков защиты в самостоятель- ный язык, отделенный от ЯОД схемы и имеющий стой транслятор. Мы назовем этот язык «языком определения защиты данных» и впоследст- вии рассмотрим его некоторые аспекты. 18 .5.4. Замок защиты для COPY Если при определении схемы в ней объявлен «замок защиты для COPY», то этот замок должен быть удовлетворен при составлении лю- бой ее подсхемы. В том случае, когда пишущий подсхему может удов- летворить этот замок, он получает возможность специфицировать нужные ему данные в базе данных и указать свои собственные замки защиты, ключи которых ему, естественно, будут известны. По предло- жениям РГБД, если для определенной части данных объявлен какой- либо замок в схеме и какой-либо другой замок в подсхеме, то в програм- мах, использующих эту подсхему, ее замок замещает соответствую- щий замок схемы. В результате замок защиты для COPY становится «ахиллесовой пя- той» системы защиты данных. Нарушителю защиты достаточно «взло- мать» этот замок и затем определить свои собственные замки для всех структурных элементов, чтобы база данных оказалась полно- стью доступной. Некоторые специалисты считают, что замки схемы должны быть действительны в любом случае, а в подсхеме следует разрешить опре- деление лишь более сильных замков. При этом администратор дан- ных в какой-то степени берет на себя ответственность за специфика- цию подсхем. Такой подход, однако, излишне усложняет систему защи- ты, не улучшая существенно защиту базы данных 20. 200
18.6. ПРЕДЛАГАЕМЫЙ ПОДХОД К КОНТРОЛЮ ДОСТУПА Для решения изложенных выше проблем в подход к контролю до- ступа предлагается внести следующие изменения: 1. Разделить три роли функции замков защиты: привилегии группы администрирования данными; привилегии программиста; защита данных. 2. Вынести все декларации замков защиты из ЯОД схемы и ЯОД подсхемы. 3. Уточнить возможности использования замков-переменных и замков-процедур. - 18 .6.1. Служебная программа определения полномочий Самой первой компонентой СУБД, применяемой при ее поставке и установке, скорее всего, должна быть «служебная программа оп- ределения полномочий», с помощью которой администратор данных определяет замки защиты на использование различных других компо- нент, таких, как: транслятор ЯОД схемы; транслятор языка описания хранения данных; транслятор языка защиты данных; служебная программа установки значений замков; транслятор ЯОД подсхемы; транслятор языка привилегий программиста; язык реструктуризации (по РГБД функция ALTER). Этот список содержит уже рассмотренные ранее компоненты, а также две компоненты (язык описания хранения данных и язык рест- руктуризации), которые будут обсуждаться в последующих главах. Важной концепцией здесь является служебная программа определе- ния полномочий, позволяющая контролировать использование ком- понент СУБД. Имеет смысл держать под контролем не сами языки, такие, как ЯОД схемы, а трансляторы с этих языков. Установленные с помощью служебной программы определения пол- номочий замки защиты использования трансляторов языка защиты данных и языка привилегий программиста в совокупности эквивалент- ны предложенным РГБД замкам для LOCKS, которые предполагалось определять в ЯОД схемы. Следует заметить, что замки полномочий, специфицируемые в этой первой служебной программе, поневоле должны быть литералами. Литералами же должны быть и ключи к этим замкам, предоставляе- мые непосредственно после ввода текстов обращения к защищенным компонентам СУБД из приведенного выше списка. 18 .6.2. Язык защиты данных Если мы исключим все определения, связанные со способом выбор- ки или модификации данных, то у нас останется относительно простой набор предложений, которые можно представить с помощью следую- щих форматов: 201
Формат 1 SCHEMA Н АМЕ 13 имя-схемы PRIVACY LOCK [ON имя-подсхемы] ТО ' UPDATE RETRIEVE IS литерал-1 1 имя-замка-1 I PROCEDURE имя-процедуры-1I Если фраза ON не используется, то замок относится ко всем дан- ным базы данных, определяемой указанной схемой. Формат 2 SCHEMA NAME IS имя-схемы PRIVACY LOCK ON имя-области-1 [, имя-области-2] ... имя-набора-l [, имя-набора-2] ... имя-записи-1 [, имя-записи-2] ... имя-элемента-1 [,имя-элемента-2]... ( UPDATE) ТО -------- } IS [RETRIEVE! <литерал-1 имя-замка-1 PROCEDURE имя-процедуры-1 Приведенные форматы требуют некоторого пояснения. Прежде все- го, возникает вопрос: содержит ли тип набора какую-либо информа- цию сверх той, которая заключена в записи-владельце и записях-чле- нах? К сожалению (из-за соображений, не относящихся к данной про- блеме), сам факт связи некоторого экземпляра записи-члена с некото- рым экземпляром владельца может представлять информацию, не со- держащуюся ни в той, ни в другой записи. Что, собственно, будет оз- начать. ситуация, когда пользователь имеет ключ к замку защиты члена и владельца, но не имеет ключа к замку защиты типа набора? Общий подход к подобным проблемам должен состоять в обеспече- нии возможностей любого контроля без применения слишком сложных конструкций, затрудняющих восприятие и использование системы. Решением поставленного выше конкретного вопроса может быть авто- матическое распространение замка защиты типа набора на все типы записи. Указанное правило легко запоминается, и имя набора в от- ношении защиты приобретает роль сокращенного обозначения сово- купности имен участвующих типов записи. Тем не менее если пользо- вателю разрешен доступ ко всем типам записи в типе набора, он не по- лучает автоматически доступа к последнему. Это соответствует интер- претации, используемой в ЯОД подсхемы. Всякий другой подход при- водит, как правило, к слишком сложной и противоречивой семантике. Еще одна проблема с типами набора возникает при модификации записей-членов. Если некоторый тип записи является членом данного типа набора, то нужно иметь разрешение на обновление не только этого типа записи, но и всего типа набора. 202
Чтобы быть последовательными, мы должны считать имя-областп сокращенным обозначением для всех типов записи в области, а имя- записи — сокращенным обозначением для всех элементов данных в типе записи (последнее уже является общепризнанным). В предлагаемом языке защиты данных допускается применение либо формата 1, либо формата 2, но не обоих одновременно. В фор- мате 1 все подсхемы должны принадлежать определенной схеме и все указанные процедуры базы данных должны быть специфицированы для соответствующей базы данных. В формате 2 каждый элемент, тип записи или тип набора может быть «защищен» только через одну какую-нибудь фразу независимо от ее области действия (т. е. указа- нием имени области, типа набора или типа записи). Если допустить двойное определение различных замков для неко- торой части базы данных, то как узнать, который из этих замков дол- жен быть удовлетворен для обеспечения обработки данных? В пред- ложениях РГБД замки связаны между собой дизъюнктивно, т. е. до- статочно предъявить ключ к одному из них Таким образом, двойное определение замков не усиливает защиту соответствующей части базы данных, а ослабляет ее. С другой стороны, было бы ошибочно требо вать удовлетворения всех множественно определенных замков, так как это привело бы к новым проблемам. 18 .6.3. Язык привилегий программиста Установление привилегий в использовании вариантов ЯМД может потребоваться по следующим причинам: 1. Применение указанного варианта не рационально. 2. Этот вариант не соответствует определениям схемы. 3. Программист недостаточно опытен для его использования. 4. Необходим контроль независимости данных. Последний пункт касается важной концепции управления незави- симостью данных, к рассмотрению которой мы еще вернемся. Заметим, что каждая из перечисленных причин вряд ли может быть связана, например, с одним из типов записи и не иметь отношения к другим. Таким образом, привилегии программиста являются свойством целого уровня структуры данных, а не отдельных типов на каком- либо уровне. Как указывалось выше, в предложениях РГБД этот мо- мент был недостаточно проработан. Для языка привилегий програм- миста предлагается следующий синтаксис: Формат 1 I RIVILEGE LOCK FOR " EXCLUSIVE RETR1EVAL EXCLUSIVE PROTECTED UPDATE литер ал-I IS J имя-замка-1 PROCEDURE имя-процедуры-i 203
Формагл 2 CONNECT DISCONNECT PRIVILEGE LOCK FOR ERASE ERASE SELECTIVE erase Permanent ERASE ALL FIND GET MODIFY STORE IS литерал-2 имя-замка-2 PROCEDURE имя-процедуры-2 Формат 3 PRIVILEGE LOCK FOR Формат 4 PRIVILEGE ГОСК FOR GET MODIFY STORE CONNECT DISCONNECT FIND 'литерал-3 имя-замка-3 PROCEDURE имя-проиедуры-З 'литерал-4 имя-замка-4 PROCEDURE имя-ироцедуры~4 Легко заметить, что формат 1 используется для операторов уровня области, формат 2 — для операторов уровня типа записи и т. д. В со- ответствии с решением РГБД здесь отдельно указываются различные варианты EKASE и, кстати, было бы желательно аналогичным обра- зом указывать все варианты FIND. Для этого каждому из них следует присвоить краткое обозначение и включить его в синтаксис предло- жения PRIVILEGE LOCK. Однократное использование языка привилегий программиста мо- жет включать определения нескольких замков в каждом формате, однако необходимо еще раз отметить, что каждый вариант ЯМД мо- жет упоминаться только единожды. Ключи к этим замкам должны сообщаться в программе так же, как это предлагалось в спецификациях РГБД Но в данном случае очевид- но, что сравнение ключа и замка производится во время компиляции программы. 204
ГЛАВА 19 ЯЗЫК УПРАВЛЕНИЯ РАЗМЕЩЕНИЕМ НА ВНЕШНИХ НОСИТЕЛЯХ 19.1. ВВЕДЕНИЕ Закончив рассмотрение свойств, достаточно подробно определен- ных предложениями КОДАСИЛ, перейдем к обсуждению тех средств, которые были «оставлены на усмотрение разработчика». Термин язык управления размещением на внешних носителях (ЯУВН) (device media control language) довольно часто встречается в от- четах РГБД и КЯОД. При этом иод внешними носителями подразу- меваются диски, хотя первоначально ЯУВН предназначался, по-ви- димому, для управления размещением базы данных на внешних носи- телях в различных типах устройств. Отчет РГБД (с. 21—22) специфицирует данный язык как средство «приписки областей к устройствам и пространствам внешних носите- лей, а также спецификации особенностей и управления буферизацией, страничной организацией и переполнением». Комитет ЯОД повторил это определение, но включил дополнитель- но в свой отчет раздел «Средства администрирования данными» (с. 2.13—2.14), указав в нем место ЯУВН в общем комплексе средств администратора данных. В настоящей и следующей главах мы будем обсуждать средства администрирования данными, следуя при этом идеям Рабочей группы по администрированию базами данных (РГАБД), которая подчиняется КОДАСИЛ и одновременно Британскому обществу по вычислитель- ной технике. Отчет этой группы за 1975 г. КЯОД КОДАСИЛ имеет почти такое же значение, как первый отчет РГБД 1968 г. вышестоящей организации. Он включает в основном определения концепций, а не спецификации языка. По мнению РГАБД, термин язык управления размещением на внеш- них устройствах является слишком узким для рассматриваемой обла- сти, и действительно он не нашел поддержки у разработчиков. В свя- зи с этим был предложен новый термин — язык описания хр нения данных — ЯОХД (Data Storage (ранее — Strategy) Description Lan- guage — DSDL), включающий прежний ЯУВН и отражающий многие новые аспекты распределения базы данных в целом, а также ее отдель- ных частей на физических носителях. 19.2. ВЗАИМОСВЯЗЬ ЯОХД И ЯОД СХЕМЫ С некоторой точки зрения ЯОХД представляет собой расширение ЯОД схемы. Такое расширение можно выполнять двумя способами: дополнить существующие статьи области, типа записи и типа набора синтаксисом ЯОХД или же выделить его в самостоятельный язык со своим собственным транслятором, с тем чтобы операторы ЯОХД не перемежались с операторами ЯОД схемы. 205
Достоинство первого способа заключается в том, что он позволяет ознакомиться со всеми спецификациями, относящимися к некоторой области, типу записи или типу набора, непосредственно при чте- нии исходного текста, не обращаясь к его отдельным распечаткам. С другой стороны, в случае раздельного подхода прикладному про- граммисту, как правило, не требуется знать декларации ЯОХД. Кро- ме того, он может использовать информацию этих деклараций (т. е. составлять с их помощью более эффективную программу) лишь изред- ка в особых ситуациях. Не менее важной при раздельном подходе яв- ляется и возможность модификации деклараций ЯОХД без изменения текста ЯОД схемы. Последнее связано с реструктуризацией, которая будет рассматриваться в следующей главе. Таким образом, идея двух раздельных языков, каждый из которых снабжен своим транслятором, имеет значительные преимущества, хотя на практике реализуются оба подхода. В связи с этим большое значение приобретает четкое разграничение ЯОД схемы и ЯОХД. Отнести первый язык к логическому уровню, а второй — к физичес- кому не совсем правильно, так как сами термины «логический» и «фи- зический» определены недостаточно четко. Тем не менее можно ут- верждать, что ЯОХД соответствует «более физическому» уровню,чем ЯОД схемы. По нашему глубокому убеждению, линия раздела между этими двумя языками определяется степенью зависимости программиста от тех или иных деклараций схемы. Хорошей иллюстрацией второго под- хода является решение КЯОД удалить предложенное РГБД опреде- ление «вида представления набора» из ЯОД схемы, которое уже об- суждалось в параграфе 5.9. (У КЯОД не было возможности куда-либо переместить это определение, поэтому от него просто отказались.) Такое радикальное решение обосновывалось тем, что для программис- та не имеет значения, представлен ли тип набора цепочкой или масси- вом указателей. Более того, даже если вид представления известен, то ЯМД не обеспечивает возможности использования его с целью по- вышения эффективности программ. С другой стороны, программист вовсе не обязан знать, специфицирован ли для обрабатываемого набо- ра указатель предыдущей записи, но иногда подобная информация ему может пригодиться, например, чтобы избежать применения ва- рианта FIND PRIOR, если данный указатель отсутствует (см. разд. 15.5.1). Поэтому КЯОД сохранил это определение в ЯОД схемы. В соответствии с рассмотренным подходом все операторы ЯОД схемы и ЯОХД можно разделить на три группы в зависимости от сле- дующих ситуаций: программист должен знать; программист должен знать, но может использовать; программист не должен знать и не может использовать. Каждый оператор или вариант первой группы должен принадле- жать ЯОД схемы, а каждый оператор или вариант третьей группы — ЯОХД. Остается решить вопрос со второй группой. Приведем приме- ры принадлежащих к ней операторов и их вариантов: 206
1. Тип набораопределения указателя предыдущей записи и указателя владельца. 2. Тип набора — упорядоченность набора (если она отлична от NEXT и PRIOR). 3. Тип набора — поисковый ключ. 4. Элемент данных — виртуальный или реальный, 5. Тип записи — расположение в каждой области. 6. Тип записи — способ размещения, если он не CALC, т. е. DIRECT или VIA SET. Чтобы пояснить какой-либо из этих примеров, рассмотрим пятый пункт приведенного списка, связанный с одной из возможностей ЯОХД, которая будет рассматриваться ниже. Здесь речь идет об ис- пользовании следующего оператора ЯМД, представленного в разд. 15.5.6: (NEXT) (RECORD ) FIND < I { > IN *—> имя-области ---- (PRIOR J [имя-записи] — Если программисту неизвестно специфицируемое ЯОХД распреде- ление записей в области, то данный оператор находит полезное приме- нение лишь в случае обработки всех записей (возможно, определен- ного типа) в области. Если же программист знает распределение запи- сей в области, то он может этим воспользоваться с помощью данного оператора. Таким образом, мы сформулировали (и далее уточним) некоторый критерий включения того или иного определения в ЯОД схемы или в ЯОХД. Решение этого вопроса особенно важно при наличии двух отдельных трансляторов, обрабатывающих соответствующие тексты- определения в разное время. Транслятор ЯОД схемы должен пред- шествовать транслятору ЯОХД, хотя при повторных применениях по- следнего может аннулироваться эффект его предыдущего использова- ния для данной схемы. Мы будем рассматривать ЯОД схемы как эталонную функциональ- ную границу, не делая больше попыток перенести из него в ЯОХД какие-либо спецификации. 19.3. возможности ЯОХД Обсудим возможности ЯОХД в той последовательности, в которой они использовались бы при совмещении с ЯОД схемы, т. е. сначала на уровне областей, а затем типа записи и типа набора. Подчеркнем, что эти возможности представлены здесь лишь для полноты изложения. В конкретных же СУБД могут быть реализованы далеко не все из них (см. параграф 19.4). 19.3.1. Уровень областей ЯОХД ЭТ°М УРовне предусматриваются следующие возможности 1. Разделение области на некоторое число страниц одинакового размера, причем размер страницы может быть фиксирован в СУБД; 207
выбран для всей базы данных из фиксированного в СУБД набора размеров страниц; выбран для каждой области из фиксированного в СУБД набора размеров страниц. 2. Разделение области на определенное число диапазонов страниц (не обязательно одинаковых размеров). 3. Размещение области или диапазона страниц на некотором месте или типе внешнего носителя в одном из следующих вариантов: всей области или диапазона страниц на определенном месте опре- деленного тома внешнего носителя; всей области или диапазона страниц на любом месте (т. е. на усмот- рение системы) определенного тома внешнего носителя; всей области или диапазона страниц на определенном типе внеш- него носителя или устройства (конкретные детали размещения остав- ляются на усмотрение системы); всей области вблизи некоторых других областей; всей области изолированно от других областей. Проблема управления расходом памяти, возникающая из-за несо- ответствия выбранного размера страницы блоку внешнего устройства, должна решаться с помощью средств определения размеров страниц и характеристик устройств. Переполнение областей рассматривается на уровней записи. Кроме того, определение функций журнализации и периодического копирования относят, как правило, к свойствам областей. Это озна- чает, что в спецификации каждой области включаются указания о том, должны ли изменения записей данной области заноситься в жур- нал, и если да, то в каком файле он располагается. Если этот журнал будет затем использоваться для восстановления некоторого правиль- ного состояния области, то служебная программа восстановления счи- тается отдельной от ЯОХД компонентой системы. 19.3.2. Уровень записей Здесь ivioryT быть предусмотрены следующие возможности: 1. Размещение записей одного или нескольких типов на одной стра- нице. 2. Управление физической смежностью выделяемых страниц в том случае, когда размер записи превышает размер страницы. 3. Выделение в некотором диапазоне страниц определенного числа последних для размещения различных комбинаций типов записи (из и. 1). 4. Указание или задание (с помощью процедуры базы данных) CALC-алгоритма для типов записи со способом размещения CALC (см. разд. 4.5.3). 5. Выделение диапазона страниц для CALC-записей (если это не сделано в п.1) и указание конкретных страниц (или их числа в про- центном отношении), предназначенных для использования при пере- полнении или возникновении коллизий. 6. Задание упакованного представления для всех или некоторых элементов данных в типе записи (алгоритм упаковки может быть про- 208
цедурсй базы данных, как в случае фразы ENCODING, рассмотренной в разд. 10.6.3). 7. Указание для типа записи ожидаемого минимального, среднего и максимального числа записей. 8. Определение процедуры, осуществляющей распределение запи- сей некоторого типа по двум или более областям (см. разд. 4.8.1), 19.3.3. Уровень типа набора Перечислим возможности ЯОХД на уровне типа набора: 1. Определение вида представления типа набора с помощью це- почек или массивов указателей (см. параграф 5.3). 2. Указание ожидаемого минимального, среднего и максимально- го числа записей-членов в данном типе набора. Для многочленных типов набора это относится к каждому типу записи-члена. 3. Задание области или диапазона страниц для размещения ин- декса сортируемого тепа набора (см. разд. 6.3.2). 4. Спецификация области или диапазона страниц для размещения представления поискового ключа в типе набора (см. • параграф 6.10). 19.4. СПОСОБЫ ПРЕДОСТАВЛЕНИЯ СРЕДСТВ ЯОХД Выше были перечислены некоторые возможности, предоставляемые администратору данных в соответствии с современными концепция- ми и методами реализации СУБД. Каждую из этих возможностей сле- дует еще рассмотреть с точки зрения способов ее обеспечения: 1. Несущественна для разработчика или администратора данных (не дает значительных преимуществ в управлении). 2. Определяется разработчиком; администратору данных реше- ние не предоставляется (разработчик либо считает, что его решение наилучшее, либо просто экономит усилия по реализации). 3. Разработчиком предусматривается стандартное решение, ко- торое администратор данных может заменить с помощью процедуры базы данных (в подобном случае разработчик должен предоставить ад- министратору данных средства определения процедур базы данных). 4, Разработчиком предоставляется стандартное решение, которое администратор данных может переопределить через ЯОХД. 5. Определяется администратором данных, выбирающим один из вариантов деклараций ЯОХД или определяющим свою собственную процедуру базы данных. 6. Специфицируется администратором данных с помощью декла- раций ЯОХД. 7. Специфицируется администратором данных с помощью про- цедуры базы данных. 8 Оставляется на усмотрение программиста. Ниже приводится таблица, демонстрирующая различные способы предоставления средств ЯОХД в конкретных СУБД. Для идентифи- кации этих средств в первой графе таблицы указываются уровень и номер пункта из приведенных выше списков. Символ X означает, что соответствующая возможность может быть в общем случае предостав- лена способом, соответствующим номеру графы, Звездочкой (*) отме- 209
<ены варианты, рекомендуемые спецификациями КЯОД (лишь для тех возможностей, которые предусматриваются спецификациями РГБД или КЯОД). i. Data Base Administration Working Group. June 1975 report. Available from British Computer Society. ГЛАВА 20 РЕСТРУКТУРИЗАЦИЯ 20.1. ЗАМЕЧАНИЯ РГБД ПО РЕСТРУКТУРИЗАЦИИ Отчеты РГБД и КЯОД лишь слегка касаются проблемы реструк- туризации. В отчете РГБД 1971 г. о ней упоминается всего в трех местах. Так, на с. 21 в разделе «Функции поддержки системы» отмеча- ется: «... спецификации полной СУБД должны включать описание и 210
языковые спецификации для ... языка, позволяющего модифициро- вать схему или подсхему с отражением вносимых изменений в самой базе данных. При отсутствии такого языка изменение схемы возможно только путем составления новой схемы и реструктуризации базы дан- ных в соответствии с этой новой схемой». Некоторые моменты здесь нуждаются в комментарии. Прежде все- го модификация подсхемы не имеет, по-видимому, отношения к про- блеме реструктуризации. Кроме того, идея «реструктуризации базы данных в соответствии с новой схемой» требует уточнения. Если СУБД не предоставляет средств реструктуризации, администратор данных должен осуществлять реструктуризацию сложным обходным путем. Скорее всего ему придется разгрузить имеющуюся базу данных на по- следовательный носитель, оттранслировать новую схему и, наконец, загрузить выведенные данные, чтобы они составили базу данных, со ответствующую новой схеме. Для этого последнего действия ему, воз- можно, понадобится прикладная программа, отличная от той, которая использовалась для загрузки базы данных по старой схеме. Далее на с. 23 под заголовком «Реорганизация» (ниже будет выяс- нена разница между «реструктуризацией» и «реорганизацией») мы читаем: «По информации, полученной в процессе своей деятельности, или в связи с необходимостью структурного расширения базы данных администратору данных может потребоваться реорганизовать базу дан ных. Он может: перераспределить области на другие устройства (носители), что является функцией языка управления распределением на внешних носителях; изменить схему и (или) характеристики элементов схемы; изменить базу данных, с тем чтобы она соответствовала изменени- ям в схеме (реструктуризация); удалить «мертвые» записи и уплотнить пространство («сборка му- сора»)». Реструктуризация, упоминаемая здесь РГБД в скобках в третьем пункте, согласуется с использованием этого термина в приведенном ранее тексте со с. 21. Другими словами, «изменение схемы» и «рест- руктуризация базы данных» считаются двумя различными и взаимо- исключающими действиями. Однако каждое из них бессмысленно без другого и поэтому термином реструктуризация мы здесь будем обозначать их комбинацию. Если же потребуется обсудить указанные действия по отдельности, то мы воспользуемся терминами изменение схемы и повторная загрузка данных или добавление новых данных. Этот вопрос далее рассматривается более подробно. Последнее замечание РГБД по реструктуризации можно найти на с. 75 в представлении операции ALTER: «Данная операция позво ляет изменять любые определения схемы, кроме предложений опреде- ления замков секретности». Как уже указывалось в разд. 18.3.1, РГБД и КЯОД предусмотре- ли возможность определения в ЯОД схемы замка защиты для этой операции* 211
20.2. УТОЧНЯЮЩИЕ ФОРМУЛИРОВКИ КЯОД Комитет КЯОД почти ничего не добавил к замечаниям РГБД, лишь уточнив приведенную выше выдержку (со с. 23) из отчета РГБД (с. 2.14): «Для этого администратор данных должен иметь возможность изменять схему и транслировать эти изменения в ее объектное пред- ставление; изменять базу данных в соответствии с изменениями схемы; удалять недоступные записи и уплотнять свободную память («сбор- ка мусора»); перераспределять данные на другие устройства и носители (с по- мощью Я^ВН) в зависимости от требований соотношения времени и памяти; редактировать отдельные части базы данных». Очевидно, что этот текст, действительно, уточняет формулировки РГБД, но не претендует на какой-либо новый более глубокий подход к пробле я 20.3. РЕСТРУКТУРИЗАЦИЯ И РЕОРГАНИЗАЦИЯ Прежде всего следует исключить из представления о реструктури- зации все, что фактически относится к обновлению данных. Послед- нее означает любые изменения значений элементов данных, записей или наборов в базе данных, которые выполняются через прикладные программы с помощью таких операторов, как STORE, MODIFY, ERASE, CONNECT и DISCONNECT (см. гл. 16). С другой стороны, при внесении изменений в схему скорее всего потребуется написать обновляющую программу или программу за- грузки, приводящую базу данных в соответствующее состояние. (Программа загрузки является просто частным случаем обновляющих программ.) Здесь все зависит от типа вносимых в схему изменений. Изменения могут вноситься не только в схему ЯОД, но и в декла- рации ЯОХД для некоторой базы данных, которые рассматривались в предыдущей главе. Наконец, имеется еще один вид реструктуризации, не связанный с изменением каких-либо деклараций администратора данных. Он сводится к улучшению физического расположения данных в базе дан- ных. Классическим, а возможно, и единственным примером подобной реструктуризации является широко известная «сборка мусора», упо- минаемая в приведенном выше тексте из отчета РГБД. В связи с изложенным все виды реструктуризации естественно раз- делить на следующие три категории: реструктуризация на уровне схемы; реструктуризация на уровне ЯОХД; реорганизация. Таким образом, если изменение вносится в декларации ЯОД схе- мы, то оно относится к первой категории, а если в управляющие дек- ларации, сделанные через ЯОХД, — то ко второй. Все остальные из- 212
менения физического расположения данных представляют собой ре- организацию и включаются в третью категорию. Это означает, что некоторое изменение, относящееся в одной кон- кретной СУБД и ЯОХД-реструктуризации, в другой может оказать- ся в категории реорганизации, если в ней не предусмотрен для адми- нистратора данных уровень управления через ЯОХД (см. параграф 19.4). 20.4. СПЕЦИФИКАЦИЯ РЕСТРУКТУРИЗАЦИИ НА УРОВНЕ СХЕМЫ И ЯОХД Имеются два основных метода спецификации реструктуризации на уровне схемы в ЯОХД: замена описания и внесение модификаций. В первом случае администратор данных полностью переопределя- ет всю схему. Модуль СУБД, обрабатывающий эту новую схему, дол- жен сравнить ее с предыдущей, выявить различия, проверить их до- пустимость и выполнить соответствующую реструктуризацию. Во втором случае администратор данных может указать изменения в прежней схеме с помощью языка, который можно назвать языком реструктуризации схемы (функция ALTER предложений РГБД). Транслятор данного языка должен проверить допустимость указан- ных изменений и реализовать их. Те же два метода применимы и при реструктуризации на уровне ЯОХД. 20.4.1. Спецификация реорганизации Для физической реорганизации также предлагаются два метода, отличных от описанных выше. Администратору данных может быть предоставлена служебная программа с декларативными языковыми средствами типа COLLECT GARBAGE IN область-7 (СБОРКА МУСОРА В область-7) COAGULATE имя-записи-5 IN область-3 (ОБЪЕДИНИТЬ имя-записи-5 В область-3) Альтернативой является использование специального языка ма- нипулирования на физическом уровне, с помощью которого програм- мисты административной группы могут составить специальные про- граммы-процедуры, выполняющие физическую реорганизацию. 20.5. ПРОЦЕСС РЕСТРУКТУРИЗАЦИИ Реструктуризацию и реорганизацию лучше всего осуществлять в тот момент, когда вся ЭВМ или по крайней мере вся база данных могут быть полностью предоставлены в распоряжение преобразую- щего процесса (монопольное использование для обновления). Если такой момент никогда не может быть выделен, то приходится приме- нять другой подход. При относительно небольшом пространстве' па- мяти, занимаемом базой данных, можно провести реструктуризацию на специально заведенной копии, после чего внести в эту копию все обновления, произведенные с начала копирования, и переключить на 213
нее обрабатывающие процессы. Если же и этот подход невозможен, то придется вести реструктуризацию «на месте», скорее всего с блокиров- кой на уровне областей. В этом случае удобно определять небольшие области. 20.5.1. Следствия реструктуризации 21 При реструктуризации возможны следующие изменения: 1. Только объектной схемы. 2. Внутренних таблиц, составляемых в результате трансляции ЯОХД. 3. Содержимого (значений) базы данных. 4. Физического расположения записей в базе данных. 20.6. РЕСТРУКТУРИЗАЦИЯ НА УРОВНЕ СХЕМЫ Имеет смысл различать дополнения, сокращения и модификации схемы. В соответствии с этим разделим все изменения на три груп- пы и рассмотрим каждую из них, представив эти изменения в после- довательности, соответствующей включению в ЯОД схемы. 20.6.1. Дополнения схемы Для каждого из перечисленных ниже дополнений указываются параграф или раздел данной книги, где обсуждалось соответствующее определение ЯОД схемы, и комбинация возможных следствий, пред- ставленных в разд. 20.5.1. № Дополнения Параграф или раздел Возможные следстния 1 2 3 4 1 Область 11.4 XX 2 Тип записи 11.8 X Элемент в существующем типе записи 9.9 X X 4 Реальный элемент-копия в существую- 9.7 щем типе записи X X Виртуальный элемент-копия в существу- ющем типе записи 9.7 X 6 Реальный элемент-результат в существу- 10.6.2 ющем типе записи X X 7 Виртуальный элемент-результат в суще- ствующем типе записи 10.6.2 X 8 Тип набора, включающий существующие 11.6 типы записи X X 9 Индекс для сортируемого типа набора 6.3.2 X 10 Поисковый ключ в любом типе набора 6.10 X Следует заметить, что в некоторых случаях дополнение может из- менить физическое расположение данных в базе данных при расшире- нии записей для вставления новых элементов или для физического представления присутствия в новых наборах. Только введение но- вой области может повлиять на внутренние таблицы ЯОХД, и ни одно из перечисленных изменений не должно отразиться на значениях, хра- нимых в базе данных. 214
20.6.2. Сокращения схемы Здесь мы применяем ту же структуру и последовательность пред- ставления изменений, что и в предыдущем разделе. № Сокращения Параграф или раздел Возможные следствия 1 2 3 4 1 Области 11.4 XX X 2 Типа записи 11.5 X X 3 Элемента в существующем типе записи 9.9 X X 4 Реального элемента-копии в существую- щем типе записи 9.7 X X 5 Виртуального элемента-копии в сущест- вующего типе записи 10.6.2 X 6 Реального элемента-результата в суще- ствующем типе записи 10.6.2 X X 7 Виртуального элемента-результата в су- ществующем типе записи 10.6.2 X 8 Типа набора с сохранением составляю- щих типов записи 11.6 X X 9 Индекса сортируемого типа набора 6.3.2 X 10 Поискового ключа в любом типе набора 6.10 X Таким образом, мы видим, что сокращение иногда влияет на со- держимое базы данных, а иногда нет. При отмене области изменения вносятся как в объектную схему, так и во внутренние таблицы ЯОХД. Содержимое базы данных затрагивается лишь в том случае, когда в об- ласти имеются еще какие-то записи. При этом возникает один из тех общих вопросов, которые характер- ны для всей проблемы реструктуризации: следует ли допускать трак- товку отмены области как удобного сокращенного указания отмены всех содержащихся в ней записей или такая практика является опас- ной? Большинство разработчиков СУБД наверняка выберет здесь наиболее надежное решение и потребует, чтобы отменяемая область была совершенно пустой. Не менее интересен случай отмены типа набора с сохранением со- ставляющих его типов записи. Изменяется ли при этом содержимое базы данных — зависит от применяемого варианта выбора набора. Если используется вариант выбора по некоторому элементу записи (см. параграф 8.8), то значения данных базы данных не меняются. Для более старых и классических вариантов КОДАСИЛ, таких, как выбор «по индикатору текущего набора», сам факт принадлежности экземпляра записи-члена к некоторому экземпляру набора несет в се- бе определенную информацию и представляет собой информационное содержание базы данных. При отмене подобного типа набора удаляет- ся и информация о принадлежности к нему записей, а это, бесспорно, является модификацией содержимого базы данных. Отмена типа набора может привести и к четвертому следствию — изменению физического размещения записей в базе данных, незави- симо от того, используются ли для представления набора цепочки или массивы указателей. В принципе имеются только два основания для отмены типа набора без удаления составляющих его записей — в це- 215
.лях экономии пространства памяти и сокращения времени обновле- ния. В первом случае было бы бессмысленно отказываться от типа на- бора, если бы это не влекло за собой перераспределение памяти. В заключение отметим, что сокращающая реструктуризация при- меняется гораздо реже расширяющей или модифицирующей. Струк- тура базы данных имеет скорее тенденцию к расширению, чем к сок- ращению, а процесс ее «настройки» чаще всего требует внесения изме- нений в некоторые аспекты определения данных. 20.6.3. Модификации схемы Модифицирующая реструктуризация может включать следующие изменение: . . Ng Модификации Параграф или раздел Возможные следствия 12 3 4 1 Имени области 11.4 X X 2 Имени типа записи 11.5 XX 3 Имени элемента данных 9.9 X 4 Имени типа набора 11.6 X 5 Имени индекса 6.10.1 X X 6 Приписки записи области 11.6 4.5.1 XX X 7 CALC-ключа с сохранением способа раз- мещения 4,4.1 X X 8 С пособа размещения некоторого типа за- п пси 4.3 X X 9 Элемента из реального в виртуальный 9.7, X X 10 Элемента из виртуального в реальный " 10.6.2 9.7, V 11 Упорядочения набора для некоторого ти- па набора 10.6.2 6.7 X X 12 Вида представления некоторого типа на- бора 5.6 XX X 13 Критерия выбора набора для некоторой 8.6 X X 14 записи-члена Типа включения записи-члена набора 7.4 X X 15 Типа исключения записи-члена набора 7.4 х ^Модификации 1—5 представляют собой изменения имен. Мало ве- роятно, чего бы они часто производились после загрузки базы данных. Если ЯОД подсхемы имеет средства переименования (см. разд. 12.8.3), то изменение имени в схеме не повлечет за собой модификации про- грамм. С другой стороны, при этом необходимо внести изменения в подсхемы, использующие старые имена, и перетранслировать их. Интересные проблемы возникают при изменении способа разме- щения, в частности CALC, при котором большей частью приходится вносить изменения в программы. Замена некоторого способа разме- щения на CALC также, возможно, приведет к изменениям в програм- мах, реализующим преимущества этого нового способа размещения (иначе зачем нужно такое изменение?). Изменение CALC-ключа (п. 7 в приведенном выше списке) — довольно редкое событие, почти навер- няка связанное с изменениями в программах. 216
Изменение упорядоченности набора не обязательно потребует мо- дификации физического размещения записей в базе данных, но тем не менее такая возможность имеется. Здесь более важным является вопрос об изменении программ, обрабатывающих базу данных по ста- рой схеме. Ведь для того чтобы использовать в программе известный порядок набора, недостаточно просто выполнить оператор FIND с указанием типа набора (см. разд. 15.5.1 и 15.5.4), необходимо знать и метод применения этого оператора. Существуют методы «нечувстви- тельные к упорядоченности», при которых изменение последней не влияет на процесс выполнения программы. Изменению критерия выбора набора следовало бы посвятить отдельную главу. Следствия такого изменения связаны со способом включения записи-члена, который, кстати, также может быть модифи- цирован. Если этот способ включения был или после реструктуриза- ции стал автоматическим, то каждый экземпляр записи-члена необхо- димо включать в какой-либо экземпляр набора. В том случае, когда при новом способе выбора набора экземпляр последнего определяется семантикой обновляющей программы, реструктуризацию не удастся провести средствами одних только непроцедурных деклараций. По всей видимости, это одна из самых сложных проблем реструктуриза- ции. Возвращаясь к обсуждению критерия выбора набора (см. пара- граф 8.9), порекомендуем лишь по возможности выбирать подход, ос- нованный на применении элемента в записи, и избегать его переопре- деления. 20.7. ЗАКЛЮЧЕНИЕ Мы надеемся, что изложенный выше материал дает некоторое пред- ставление о проблеме реструктуризации, которая довольно часто упо- минается, но нигде детально не исследуется. До публикации отчета РГАБД 1975 г. деятельность КОДАСИЛ была настолько ограничен- ной, что он не мог охватить эту проблему. К сожалению, многие аргументы и гипотезы по обеспечению неза- висимости данных основаны на тех видах реструктуризации, которые вряд ли найдут применение на практике. ГЛАВА 21 СИСТЕМА TOTAL 21.1. ОСНОВНЫЕ КОМПОНЕНТЫ Перейдем к рассмотрению двух других широко используемых мето- дов управления базами данных. Первый из них представлен системой TOTAL фирмы Cincom, которая предлагается для значительного ряда вычислительных машин. TOTAL — это собственное имя системы, а не акроним. Как и при обсуждении предложений КОДАСИЛ, мы не будем вдаваться в детали конкретных реализаций. Цель данной ра- 217
боты — по казать суть управления базой дан пых, обеспечиваемого каждым методом. Тем не менее сообщим для сведения читателей, что в настоящее время существуют реализации этой системы для вычисли- тельных машин фирм Burroughs, Control Data, DEC, Harris, Honey- well, IBM, ICL, Interdata, NCR, Siemens, Univac, Varian. Представляя систему TOTAL, мы постараемся придерживаться по- рядка, принятого в книге, и будем давать ссылки на соответствующие положения, рассмотренные ранее в предложениях КОДАСИЛ. В нас- тоящей гл-аве описываются определенные возможности у пр ав ления, но это не означает, что они имеются в каждой из реализаций. Ниже перечислены компоненты TOTAL, соответствующие указан- ным в гл. 2: ЯОД схемы Язык определения базы данных (ЯОБД) Язык манипулирования Язык манипулирования данными (ЯМД) данными Резидентный модуль СУБД DATBAS (только для пользователей IBM OS) Здесь DATBAS — имя небольшого модуля интерфейса. Основной исполнительный модуль обычно называется TOTAL. ЯОД подсхемы в этой системе отсутствует, хотя некоторые его средства можно осу- ществить. 51зык управления внешним носителем (см. гл. 19) также от- сутствует, ио некоторые из его возможностей обеспечиваются статьями физической среды. 21.2. РЕАЛИЗАЦИЯ ЯМД Язык манипулирования данными в TOTAL также является расши- рением существующих языков программирования. Он состоит из ряда операторов CALL, каждый со своим собственным списком парамет- ров. Большинство операторов CALL имеет вид: CALL «DATBAS» USING операция, состояние, файл, ссылка, цепь-связи, поле управления, список элементов записи, область-записи, конец-списка- параметров, где первый параметр в списке, а именно «операция», является именем типа оператора, который будет выполняться. Некоторые параметры, например «ссылка» и «цепь-связи», используются только в определен- ных ситуациях. Пользуясь оператором CALL, можно поддерживать более одного включающего языка (см. разд. 2.5.2), и действительно, для этой роли равно применимы языки Кобол, ПЛ/1, Фортран и Ассемблер. 21.3. КОНЦЕПЦИИ СТРУКТУРИРОВАНИЯ Структура базы данных TOTAL основана на связях между запися- ми (см. параграф 3.3), причем тип набора (см. параграф 3.4) называет- ся «связью» или иногда «цепью-связи». Важно отметить, что все типы наборов в TOTAL — одночленные. Отсутствие многочленных типов набора (см. параграф 3.4) снимает многие проблемы как для разработ- чика, так и для пользователя. Однако в TOTAL имеется одна особен- 218
ность, фактически позволяющая пользователю определять многочлен- ные типы набора с помощью внутренней структуры записи, которая описывается нижз. Как будет показано далее, здесь отсутствуют и типы набора, вла- дельцем которых является сама система. 21.3.1. Структуры связи между записями Способ использования связи типа набора для построения структу- ры базы данных в TOTAL в основном аналогичен подходу КОДАСИЛ, но имеется существенное ограничение. В TOTAL тип записи не мо- жет быть владельцем в одном типе набора и членом в другом. К счастью, тип записи мо- жет быть членом нескольких типов набора, и, следовательно, проектировщик базы данных TOTAL в состоянии устранить это затрудне- ние. На рис. 21.1, повторяющем рис. З.Н, представлена простая трехуровневая иерар- хическая структура, которая, как мы увидим позднее, не вызовет никаких осложнений ни в системе КОДАСИЛ, ни в IMS. Однако в TOTAL нужно ввести четвертый тип запи- си, который даст структуру, приведенную на рис. 21.2. Всякий раз, когда к базе данных добав- ляется новый экземпляр ЗАКАЗ-ПРОДА- ЖА, программист должен проверить, чтобы был также создан и записан экземпляр ОТ- НОШЕНИЕ-ЗАКАЗ-ПРОДАЖА. Обычно этот Рис. 21.1. Иерархическая структура четвертый тип записи бывает небольшим. Более того, дополнитель- ная связь типа набора ОЗ представляет собой в действительности с г- ношение один к одному. Другими словами, существует точно од: г я экземпляр ЗАКАЗ-ПРОДАЖА для каждого экземпляра ОТНОШЕ- НИЕ-ЗАКАЗ-ПРОДАЖА. Сравним ОЗ с двумя другими связями на рис. 21.2, которые соответствуют связям, имеющим те же имена, на рис. 21.1. Для этих двух связей ПЗ и ОЛЗП может существовать нуль, зсзп Рис. 21,2. Типичная двухуровневая структура TOTAL
один или более экземпляров записей-членов на каждый экземг ник владельца - Следуем' заметить, что TOTAL не накладывает никаких ограничений на число связей типа набора, которые могут быть определены между любыми двумя типами записи. На рис. 21.3 показана типичная струк- тура базы данных TOTAL, заимствованная из примера, приведенного в справочнике этой системы, но с переименованными типами записи, и несколько видоизмененная в соответствии с соглашениями, приняты- ми в данной книге. Здесь ясно виден двухуровневый характер допусти- мой структуры базы данных TOTAL. Рис. 21.3. База данных TOTAL В TOTAL требуется, чтобы каждому типу записи давалось имя из четырех литер, а каждому элементу данных — из восьми литер, при- чем первые четыре литеры имени элемента должны быть эквивалентны имени типа записи, содержащей этот элемент. Типу набора присваи- вается имя из восьми литер формата mmmm LKxx. Для представления типа записи-члена при графическом изображе- нии структуры базы данных в TOTAL используется иной символ — шестиугольник. Сама идея TOTAL предполагает, что тип записи в ба- зе данных может играть роль либо владельца набора, либо его членае но никогда обе роли одновременно. По отношению к владельцу исполь- зуется терглин основная, или главная, статья, а по отношению к запи- си-члену — переменная статья. Набор всех записей конкретного типа называется либо набором данных главной статьи, либо набором дан- ных переменной статьи. Термин набор данных широко применяется в операционной систе- ме IBM. В литературе по TOTAL вместо набора данных иногда употреб- ляется слово файл. 21.3.2. Внутренняя структура записи В TOTAL имеется специальное средство внутренней структуриза- ции, которое отличается от средств, предлагаемых КОДАСИЛ. Оно называется концепцией кода записи и представляет собой фактически формализацию приема с использованием последовательных файлов, которым иногда пользуются программисты, работающие с Коболом. 220
При определении базы данных любой тип записи-члена может быть разделен на две части, содержащие базовые и переопределяемые данные. Базовые данные составляют первую часть типа записи, и су- ществуют четкие правила, указывающие, какие элементы должны в нее включаться. Переопределяемая часть может иметь два или более различных определений, каждое из которых имеет свой двухлитерный «код записи». Более того, каждая кодированная запись (по существу, «подтип записи») может участвовать в отношениях типа набора, отлич- ных от других кодированных записей в том же файле. Длины всех записей типа записи-члена одинаковы, независимо сг того, какому определению записи соответствует переопределяемая часть. Очевидно, что всем экземплярам записи требуется такой же объ ем памяти, как и самому длинному определению в данном типе записи, и что все записи, которые соответствуют более коротким определени- ям, содержат пустое неиспользованное пространство. Если эти длины существенно отличаются, рекомендуется специфицировать различные типы записи (т. е. различные файлы переменных статей TOTAL), 21.4. ПРЕДСТАВЛЕНИЕ ТИПА ЗАПИСИ В ПАМЯТИ Единственный вид контроля над представлением типа записи в па- мяти проектировщик может осуществить, когда он решает, должен ли тип записи быть владельцем или членом набора. В TOTAL нет яв ной концепции способа размещения (см. параграф 4.3). Тем не менее принято считать, что все типы записей-владельцев имеют способ раз- мещения CALC (см. параграф 4.5), но с запрещением значений-дуб ликатов (см. разд. 4.5.1). Другими словами, каждый тип записи-вла дельца должен иметь элемент уникального первичного ключа, значе ние которого используется для встроенного метода рандомизации, при меняемого при размещении экземпляров записи. Все типы записей- владельцев в любой базе данных TOTAL ставятся в соответствии с од- ним и тем же алгоритмом рандомизации, и коллизии (см. разд. 4.5.2) обрабатываются автоматически. Так как предполагается, что типы записей-владельцев имеют спо- соб размещения CALC, наиболее подходящим способом размещения для типов записей-членов является SYSTEM (см. разд. 4.6.2). Послед- ним подразумевается, что система сама решает, как должны размещать- ся записи такого типа, и проектировщик базы данных не в состоянии влиять на этот процесс. Тип записи-члена не может иметь первичный ключ без определения дополнительного типа записи специально для указанной цели. То, что тип записи-члена может быть связан с неограниченным чис- лом владельцев (как в КОДАСИЛ, но не в IMS), фактически разрешает несколько проблем. Проектировщик базы данных может, действи- тельно, разрешить типу записи-члена иметь несколько ключей с по- мощью простого средства — определения типа записи-владельца, со- держащего элемент, взятый у типа записи-члена, который должен слу- жить ключом. В такой ситуации окажется столько экземпляров этого типа записи-владельца, сколько существует различных значений для 221
ключевого элемента. Последний служит уникальным первичным клкн чом для типа записи-владельца и уникальным ключом обращения 4 типу записи-члена. Программист, который будет писать программы для; обработки этой части базы данных, должен полностью осознать, что; ключи к типу записи-члена обеспечиваются именно таким образом, и : пройти через процесс поиска записи-владельца, а затем записи-члена. Концепция области в подходе КОДАСИЛ (см. разд. 4.8.1) позво- ляет размещать записи различных типов близко друг к другу, т. е. в данном случае на одном пакете дисков. Способ размещения VIA SET (см. параграф 4.7) допускает размеще- ние записей-членов по возможности вблизи других записей в том же наборе, а также владельца набора. Такой контроль над физическим размещением записей не обеспечивается в TOTAL, где имеется лишь средство контроля числа логических записей на блок и, следова- тельно, на дорожку. Однако концепция «кодированной записи» (см. разд. 21.3.2) предполагает некоторый контроль над сплошным физи- ческим размещением двух или более типов набора. 21.5. ПРЕДСТАВЛЕНИЕ ТИПА НАБОРА В ПАМЯТИ Все типы набора в TOTAL представлены в памяти как цепочки, со- единенные со следующей и предыдущей записями (см. параграф 5.6). У проектировщика базы данных нет другого выбора. Как и в системе КОДАСИЛ, это означает, что в каждой записи-владельце и записи-чле- не содержатся два указателя (см. рис. 5.4). Однако в TOTAL лицо, подготавливающее описание базы данных, должно выделять восемь байтов в типе записи для каждого отношения, в котором этот тип запи- си участвует, независимо от того, является ли он владельцем или чле- ном набора. (В системах КОДАСИЛ такое выделение объема памяти неявно подразумевается в определении типа набора и вида представле- ния последнего (см. параграф 5.3).) С точки зрения проектировщика базы данных, подобное ограниче- ние одним видом представления набора является неплохим решением. Различные варианты КОДАСИЛ требуют выбора соотношения между временем обработки и объемом памяти, что не всегда легко выполнимо. 21.6. УПОРЯДОЧЕНИЕ НАБОРА Проектировщик базы данных TOTAL не может специфицировать упорядочение записей в типе набора (см. параграф 6.2). Чтобы выяс- нить, что происходит, когда к набору присоединяется новая запись, не- обходимо изучить семантику эквивалента оператора STORE (см. па- раграф 16.4), который в TOTAL называется оператором ADD (см. разд. 21.12.3). Конечно, пока еще несколько преждевременно деталь- но рассматривать ЯМД, однако следует заметить, что для постановки записи-члена должен использоваться иной оператор, чем для записи- владельца. Кроме того, имеются три различных варианта помещения записи-члена в базу данных.
Таким образом, определение порядка в любом типе набора находит- ся в ведении программиста, который пишет программы обновления. Если этим занимаются несколько программистов, они должны прийти к соглашению относительно упорядочения набора. Напомним, что в системах КОДАСИЛ (см. разд. 6.2.2) администратор данных может пе- редать программисту полномочия по решению об упорядочении набора (см. разд. 6.4.2). Метод, используемый в TOTAL, близок, но не экви- валентен такому варианту КОДАСИЛ. 21.7. ПОИСКОВ ЫЕ КЛЮЧИ Система TOTAL не поддерживает предложенный КОДАСИЛ тип поискового ключа внутри типа набора (см. параграф 6.10). Правда, это и не является значительной потерей. Гораздо больший интерес пред- ставляет так называемый глобальный поисковый ключ (см. разд. 6.10.3). Как и способ размещения, он принадлежит типу записи и дает возмож- ность определять вторичные ключи. В случае типа записи-члена в TOTAL при определении других по- исковых ключей в равной мере успешно может применяться метод ис- пользования дополнительного типа записи-владельца, выполняющего роль первичного ключа. Привлечение дополнительного типа набора для моделирования вторичного индекса давно получило признание в КОДАСИЛ. Возможно, РГБД считает, что это возмещает отсутст- вие глобальные поисковых ключей. 21.8. СПОСОБ ВКЛЮЧЕНИЯ И ДОПУСТИМОСТЬ ИСКЛЮЧЕНИЯ Эти две концепции не имеют эквивалентов в TOTAL. Тип записи- 1 лена обязательно является автоматическим членом любого типа набо- ра. Последнее лучше всего показать на примерах. Так, в приведен- 1 ом ранее примере (см. параграф 7.1) в тип записи ПРЕДМЕТ вклю- чается дополнительный элемент (см. рис. 21.4), указывающий, что этот предмет представляет собой невыполненный заказ. Другой пример показан на рис. 21.5. В том случае когда служащий может быть не приписан к отделу, необходимо в базе данных иметь запись ОТДЕЛ, представляющую фик- тивный отдел. Этому фиктивному отделу нужно дать номер и присое- ПРЕДМЕТ ЗАГОЛОВОК- ЗАКАЗ- ПРОДАЖА Рис. 21.4. Только автоматический способ вклю- чения чения 22 3
динить служащих, не относящихся к какому-лиоо реальному отделу, к даниль записи. 6 такой ситуации программисту, конечно, придется выполнить некоторую дополнительную работу, но вряд ли она окажет- ся намного больше тон., которую он выполняет при неавтоматическом способ; включения. Допустимость исключения (см. параграф 7.2) связана с семанти- кой оператора ERASE (см. параграф 16.3). В TOTAL он называется DELETE, и, как и в случае STORE, для владельцев и членов набора в нем предусмотрю различные форматы. Не имеет смысла опреде- лять в TOTAL каю шибо из двух возможных видов допустимости исключжыя КОДА С 01. 21.9. ГЮкоР НАБОРА В ковочной литературе по TOTAL термин выбор набора (или даже о аленно похожий на него) отсутствует. Тем не менее эта про- блема шествует в любой СУБД (см. параграф 8.2), поддерживающей отношышя типа структур связи между записями, и ее решение в TO- TAL предельно простое. В типе записи-владельца для каждого типа набора должен присут- ствовать элемент (или группа элементов), играющий роль управляю- щего тая. Тип записи-члена содержит элемент, который соответст- вует по длине управляющему полю в типе записи-владельца. Значе- ние этого элемента в записи-члене должно быть равно значению управ- ляющего поля в одной из записей-владельцев, уже хранимой в базе данных. Этен подход можно проиллюстрировать с похмощыо рис. 21.5. Ес- ли считать, что элемент №-ОТДЕЛА являете;; первичным ключом в типе записи ОТДЕЛ, то в типе записи СЛУЖАЩИЙ должен присут- ствовать элемент, который принимает то же значение, что и №-ОТДЕЛА. Ему не обязательно присваивается имя ЖОТДЕЛА. Следует заметить, что такой подход довольно близок к предложе- ниям КЯОД, введенным дополнительно к спецификациям КОДАСИЛ (см. параграф 8.9). Дублирование элемента в двух типах записи позво- ляет устранить неоднозначность в выборе набора, присущую методу КОДАСИЛ. Очевидно, что в подходе КОДАСИЛ специфицирован- ный программистом выбор набора (см. параграф 8.3) сопряжен с не- автоматическим включением. В TOTAL, где имеет место лишь автома- тический способ включения и применяется простой вариант выбора набора, осуществляется более слабый контроль соотношения между объемом памяти и временем исполнения, но зато этот подход гораздо проще is концептуальном отношении. 21.10. ПОДСХЕМА Как уже упоминалось ранее, в TOTAL нет ЯОД подсхемы. Подсхе- ма позволяет программисту ограничить свое представление о базе дан- ных и сосредоточить внимание только на типах данных, которые он собирается обрабатывать в программе. В системах КОДАСИЛ такое «ограниченное представление» должно определяться администратором 224
данных с помощью ЯОД подсхемы (см. параграф 12.2). Каждой под- схеме присваивается имя, и программисту остается лишь использо- вать его в своей программе (см. параграф 13.3). Отсюда вытекает важ- ное следствие, которое заключается в том, что область записи (см па- раграф 12,4) будет резервироваться в любом выполняющемся экземп- ляре этой программы. В TOTAL программист специфицирует области записи в своей про- грамме для каждого типа записи, который он желает обрабатывать. Типы записи, не представляющие интереса, могут быть опущены. Такой подход соответствует аспекту «ограниченного представления» в концепции ЯОД подсхемы, но не предоставляет администратору дан- ных контроля над тем, кому и в какой части базы данных разрешается обрабатывать данные. Подобный контроль можно обеспечить с помо- щью библиотечных средств Кобола. 21.11. КОНЦЕПЦИИ ЯМД В параграфе 21.2 отмечалось, то все обращения к базе данных на включающем языке должны производиться с помощью оператора CALL, Первый параметр в списке всегда обозначает выполняемую операцию, а второй, называемый «состоянием», — ячейку в рабочем пространстве вызывающей программы, где устанавливается условие состояния. Это условие показывает, что происходит всякий раз, когда вызывает- ся оператор CALL. Мы можем считать переменную состояния некото- рым видом регистра базы данных (см. параграф 13.5). В литературе по TOTAL не упоминается концепция индикаторов текущего состояния (см. параграф 13.6), но в ней не упоминаются и ключи базы данных (см. параграф 4.2). Изучение же семантики некоторых операторов ЯМД наталкивает на мысль о том, что вполне можно было бы ввести концепцию нескольких индикаторов текущего состояния. Позднее, при рассмотрении конкретных операторов ЯМД, это станет очевидным. 21.12. ОПЕРАТОРЫ ЯМД Нам уже известно (см. параграф 21.6), что для типов записей-вла- дельцев и записей-членов имеются различные операторы ЯА1Д. Су- ществуют три категории этих операторов: независимые от типа записи; применяемые для типа записи-владельца; применяемые для типа записи-члена, которые мы рассмотрим ниже. При этом не предполагается подробное описание работы каждого оператора, но будут приведены сведения, позволяющие дать им сравнительную оценку с эквивалентными опера- торами КОДАСИЛ. Возможные типы операторов TOTAL и соответствующие им опе- раторы КОДАСИЛ представлены в следующей таблице: В последнее время наметилась тенденция использовать операторы, применяемые и для записей-владельцев, и для записей-членов. Не- смотря на то что такие операторы, как OPENM и OPENV, все еще дей- 8 Зак. 145 225
Эквивалент КОДАСИЛ Типы записей- владельцев Оба типа записей Типы записей- членов READY FIMISN OPENM CLOSM SINON OPENX SINOF CLOSX OPENV CLOSV F1NTD/GET READM RDNXT RINDX READV READD READR STORE ADD-M ADDVA ADDVB ADDVR ERASE DEL-M DELVD MODIFY WRITM WRITV ствительны (в целях обеспечения совместимости с более ранними вер- сиями), в современном справочнике приводится лишь оператор OPENX, а описания остальных четырех операторов OPEN отсутствуют. 21.13. ОПЕРАТОРЫ ЯМД, ПРИМЕНЯЕМЫЕ ДЛЯ ЗАПИСЕЙ-ВЛАДЕЛЬЦЕВ И ЗАПИСЕЙ-ЧЛЕНОВ 21.13.1. Операторы SINON, READY и FINISH Первым оператором в прикладной программе, написанной для об- работки базы данных TOTAL, должен быть SINON. В некотором смыс- ле он аналогичен оператору READY КОДАСИЛ, но, поскольку в TOTAL имеется и OPEN, необходимо рассмотреть их различия. Конкретная вычислительная установка может содержать несколь- ко баз данных TOTAL. Это означает, что в каталоге или библиотеке находится более одного «модуля описания базы данных». Параметры оператора SINON отличаются от параметров других операторов. Один из них, называемый «доступом», подобен способу использования (см. разд. 14.2.1). Программисту предоставляется на выбор четыре ва- рианта, включающие поиск, обновление и восстановление. Последний вариант позволяет воспользоваться специальным оператором ЯМД (WRITD), который здесь не описывается. В операторе SINON, помимо указания способа использования, имеется также параметр, с помощью которого программист определя- ет, требуется ли журнализация, и если требуется, то какая и где. Далее следует упомянуть об операциях открытия и закрытия не- скольких файлов одним оператором. Соответствующие операторы, также не зависящие от используемых типов записи, имеют коды опера- 226
ций OPENX и CLOSX соответственно. Параметр «состояние» в этом случае должен иметь возможность включать код состояния для любого открываемого файла. Программист обязан проверять каждый из таких кодов. В TOTAL отсутствует концепция монопольной или защищенной обработки (см. разд. 14.2.1), поэтому считается, что вся обработка проходит в незащищенном режиме (см. разд. 14.2.4). Вид доступа вне зависимости от того, поиск это или обновление, называется «способом доступа» и специфицируется в SINON. Если предположить, что каж- дый тип записи в TOTAL относится к одной области и что, следователь- но, между областью и типом записи существует отношение один к од- ному, то OPENX окажется эквивалентным (см. параграф 14.2): READY [имя-области-1]...; USAGE MODE IS RETRIEVAL и CLOSX есть то же, что и FINISH [имя-области-1]... Оператор SINOF используется для завершения обработки. 21.13.2. Многоцелевой оператор READ Сравнительно недавно к списку операторов был добавлен RDNXT, или READ NEXT (ЧИТАТЬ СЛЕДУЮЩИЙ). Он заменяет прежний оператор SEQRM, или SERIAL READ MASTER (ПОСЛЕДОВАТЕЛЬ- НО ЧИТАТЬ ГЛАВНЫЙ), и может использоваться как с записями- владельцами, так и с записями-членами. Однако это различие устра- нено лишь частично, поскольку применение тех или других парамет- ров в операторе CALL зависит от «роли» типа записи. Устанавливая соответствующие значения параметров, программист может добиться тех же результатов, что и при использовании некото- рых вариантов оператора FIND КОДАСИЛ. Основной параметр этого оператора называется «квалификатором». Для типа записи-владель- ца (т. е. основного файла) существуют три варианта: 1. BEGN; 2. KEY = kkk...kk; 3. гггг, а для типа записи-члена (т. е. переменного файла) — еще пять: 4. BEGN WW SERIAL; 5. гггг bbbb SERIAL; 6. BEGN bbbb mmmmLKxx; 7. пт bbbb mmmmLKxx; 8. mmmmLKxx KEY = kk,,.kk. 8* 227
Хотя эти варианты могут показаться несколько необычными, каж- дый из них вполне обоснован: 1. Вариант BEGN предназначен для инициализации поиска. В любом случае он аналогичен FIND FIRST имя-записи-l IN имя-области (см. раздел 15.4.3). Если этот оператор выполняется успешно, запись помещается в область-записи, указанную в списке параметров опера- тора CALL, т. е. оператор RDNXT в TOTAL выполняется так же, как комбинация FIND и GET. Кроме того, изменяется содержимое поля параметров, имя которого задается в их списке как квалификатор. Сю- да помещается «внутренняя точка ссылки» (по существу, значение клю- ча базы данных) найденной записи. Ее смысл объясняется в п. 3. 2. Вариант KEY = kkk...kkk является «непосредственным» ва- риантом FIND, использующим значение уникального первичного ключа, которым должен располагать каждый тип записи-владельца. Поэтому он эквивалентен FIND ANV имя-записи (см. разд. 15.4.1). Ключ базы данных найденной записи помещается в первые -четыре байта квалификатора (вместо текста KEY =). 3. Вариант гггг эквивалентен FIND NEXT имя-записи-l IN имя-области (см. разд. 15.5.6). Предполагается, что значение ключа базы данных хранится в первых четырех байтах квалификатора, куда оно могло быть помещено в любом из первых двух вариантов. Это значение уве- личивается на единицу и находится запись, следующая за той, у ко- торой значение ключа базы данных записано в квалификаторе, а со- держимое последнего также увеличивается. 4. Вариант BEGN SERIAL для записи-члена эквивалентен ва- рианту 1 для записи-владельца. 5. Вариант rrrr SERIAL для записи-члена эквивалентен варианту 3 для записи-владельца. 6. Вариант BEGN mmmmLKxx не имеет эквивалента в КОДА- СИЛ, хотя наиболее близким является, вероятно, следующий: FIND FIRST имя-записи-l IN имя-набора-1 (см. разд. 15.5.1). Основное различие между ними заключается в спо- собе выбора экземпляра набора. Поскольку тип записи-члена может участвовать в нескольких типах набора, можно считать, что назначе- ние второй части квалификатора, а именно mmmni LKxx, состоит в спецификации того типа набора (или цепи связи), к которому относит- ся оператор. TOTAL в этом случае выполняет последовательный поиск с начала области записи, являющейся первой записью в каком-либо наборе данного типа. (В TOTAL она называется «головной записью цепи».) Как и в вариантах для записей-владельцев, значение ключа базы данных найденной записи помещается в первые четыре байта квалификатора. 228
7. Вариант rrrrmmmmLKxx аналогичен предыдущему варианту, с той лишь разницей, что поиск начинается с записи, значение ключа* базы данных которой задается в гггг. 8. Вариант mmmmLKxx KEY = kkk...kk представляет собой иной вариант FIND FIRST имя-записи-1 IN имя-набора-l причем набор выбирается с помощью владельца, значением первич- ного ключа которого является kkk...kk. Анализ рассмотренных вариантов RDNXT показывает, что для каждого из них можно определить следующие элементы: начальную точку; путь следования; условие, которому удовлетворяет искомая запись. Существуют три способа задания начальной точки: А. Первая (FIRST IN) в области. Б. Значение ключа базы данных (DB-KEY) в квалификаторе. В. Запись, выбираемая путем «непосредственного» доступа к вла- дельцу. Имеются два варианта пути следования: Г. Последовательный через область. Д. Не определен. Искомая запись должна удовлетворять трем возможным усло- виям: Е. Следующая (NEXT IN) в области. Ж. Первая (FIRST IN) в наборе. 3. Не определено. Все эти элементы в совокупности дают 18 возможных вариантов, , из которых разрешаются следующие восемь: 1. АДЗ 3. БГЕ 5. БГЕ 7. БГЖ 2. ВДЗ 4. АДЗ 6. АГЖ 8. ВДЖ 21.13. 3. Условный оператор FIND Оператор FINDX, который в некотором смысле можно считать мо- дификацией RDNXT, представляет собой расширение средств поиска. Его описание аналогично описанию оператора RDNXT. Оператор FINDX имеет такой же квалификатор, как и RDNXT, с восемью подобными вариантами. Кроме него FINDX обладает еще одним параметром, называемым «аргументом», который указывает список, содержащий критерий поиска. Последний состоит из ряда ло- гических условий по элементам в искомой записи. Эти условия со- единяются между собой посредством AND, т. е. для удовлетворения критерия поиска они все должны быть выполнены. В каждое условие необходимо включить один из шести известных операторов отношений: EQ, NE, GT, GE, LT, LE. Перечисленные выше три элемента оператора RDNXT — началь- ную точку, путь следования и условие, которому удовлетворяет иско- нная запись. — удобно использовать также и для FINDX, однако здесь 229
следует обметить некоторые расхождения в последних двух элементах. Варианты начальной точки остаются неизменными и мы обозначим их опять А, Б и В. Варна нты пути следования являются более сложными, и их можно определить как: Г. Последовательный через область. Д. Последовательный через область и затем последовательный по цепи. Условия, которым должна удовлетворять искомая запись, задают- ся с помощью аргумента. Таким образом, FINDX имеет следующие восемь вариантов: 1. BEGN. Начать с первой записи и производить поиск записи, удовлетворяющей критерию поиска, последовательно в области. 2. KEY = kkk...kk. Начать с записи, уникальный первичный ключ которой определен в параметре, и производить поиск записи, удовлет- воряющей критерию поиска, последовательно в области. 3. шт. Начать с записи, значение ключа базы данных которой сов- падает с заданным, и производить поиск записи, удовлетворяющей критерию поиска, последовательно в области. 4. BE GN... SERIAL. Выполнить действия, указанные в п. 1, но для типа записи-члена. 5. rrrr-..SERIAL. Выполнить действия, указанные в п. 3, но для типа записи-члена. 6. BEGN...mmmmLKxx. Начать с первой в области и вести в ней последовательный поиск. Записи, которые являются первыми в опре- деленном типе набора, сверяются с критерием поиска. 7. rrrr...mmmmLKxx. Выполняются действия, указанные в п. 6, но начать нужно с записи, значение ключа базы данных которой со- ответствует заданному. 8. mmmmLKxx KEY = kkk...kk. Начать с записи-владельца, зна- чение уникального первичного ключа которой соответствует заданно- му. Выбрать первую запись в наборе и сверить ее с критерием поис- ка. Если критерий не удовлетворяется, поиск в наборе продолжается (т. е. происходит по цепи), причем критерий поиска проверяется для каждой записи-члена. Этот вариант почти эквивалентен следующему варианту КОДАСИЛ (см. разд. 15.4.2). FIND имя-записи-1 WITHIN имя-набора-1 USIMG ид-данных-1 [, ид-данных-2]... в том случае, когда элементы фразы USING не являются поисковыми ключами или ключами сортировки. 21.14. ОПЕРАТОРЫ ЯМД, ПРИМЕНЯЕМЫЕ ДЛЯ ТИПА ЗАПИСИ-ВЛАДЕЛЬЦА Здесь прежде всего мы должны упомянуть операторы OPENM и CLOSM, которые означают OPEN MASTER и CLOSE MASTER. Слово MASTER, очевидно, перешло сюда из прежней терминологии TOTAL. 230
Впоследствии оно было заменено на «основную статью» (single entry), но еще сохранилось в кодах операций. Операторы OPENM и CLOSM относятся только к типу записи-владельца. По существу, они замене- ны на OPENX hCLOSX (см. разд. 21.13.1). 21.14.1. Операторы поиска В прежнем руководстве по системе TOTAL описывалось несколько операторов поиска, которые позднее были включены в RDNXT. Хотя последний и предоставил некоторые дополнительные возможности, но при его использовании читатель и программист-пользователь долж- ны детальнее разбираться в параметрах оператора CALL, чтобы оп- ределить, каковы же функции данного оператора. В качестве примера можно привести «непосредственный» FIND для записи-владельца — READM, READ MASTER (ЧИТАТЬ ОСНОВ- НУЮ СТАТЬЮ). Это эквивалент второго варианта RDNXT. Он дей- ствует так же, как вариант КОДАСИЛ для нахождения CALC-записи (см. разд. 15.4.1), с той лишь разницей, что в TOTAL первичный ключ является уникальным, и вопрос о возможности поиска дубликатов не возникает (см. разд. 15.5.2). В КОДАСИЛ ему соответствует следую- щее синтаксическое выражение: FIND ANY имя-записи Фактически READM включает применение GET (см. параграф 15.8), т. е. пересылает выбранные элементы в обозначенную область записи. Прежним вариантом FIND для типов записей-владельцев была «функция последовательного поиска» SEQRM, SERIAL READ MASTER (ЧИТАТЬ ПОСЛЕДОВАТЕЛЬНО ОСНОВНУЮ СТАТЬЮ). Это эквивалент вариантов 1 и 3 оператора RDNXT, который рекомен- дуется применять в новых программах. Этот оператор весьма близок к варианту КОДАСИЛ (см. разд. 15.4.3 и 15.5.6): (FIRST) FIND < I RECORD IN имя-области EEL- NEXT! --------- поскольку в каждой области имеется только один тип записи. Для выполнения FIND FIRST необходимо было в TOTAL исполь- зовать специальную операцию RESTM, RESTORE MASTER (ВОС- СТАНОВИТЬ ОСНОВНУЮ СТАТЬЮ), которая, как отмечается в справочном руководстве, «устанавливает счетчик последовательных обращений ЯМД к записи основного файла на нуль, чтобы последую- щее выполнение функции SEQRM выбрало первую запись из файла». Очевидно, что этот счетчик последовательных обращений к записи выполнял функцию индикатора текущей в области (см. параграф 13.6). Теперь эта функция выполняется одним из параметров FINDX и RDNXT, а именно гггг в квалификаторе. 231
21.14.2. Операторы обновления Новые записи-владельцы могут быть дополнительно введены в ба- зу данных с помощью операции ADDM, ADD MASTER (ДОБАВИТЬ К ОСНОВНОЙ СТАТЬЕ), которая соответствует оператору КОДА- СИЛ (см. параграф 16.4) STORE имя-записи в случае CALC-записи, не являющейся членом какого-либо типа набора. Существующие записи-владельцы можно модифицировать, пользу- ясь оператором WRITM, WRITE MASTER (ЗАПИСАТЬ ОСНОВУЮ СТАТЬЮ), несколько отличающимся от оператора КОДАСИЛ MODIFY имя-записи [имя-элемента] ... который воздействует на текущую запись процесса (см. параграф 16.2). Фактически оператор WRITM в TOTAL включает в себя вышеупомя- нутую операцию READM. Видоизменяемые элементы должны пере- числяться в массиве, указанном в одном из параметров CALL. Операция DEL-M, DELETE MASTER (УДАЛИТЬ ОСНОВНУЮ СТАТЬЮ) в TOTAL семантически аналогична «простому» ERASE в КОДАСИЛ (см. разд. 16.3.1) в том смысле, что могут исключаться толь- ко те записи-владельцы, которые не имеют подсоединенных к ним за- писей-членов. 21.15. ОПЕРАТОРЫ ЯМД, ПРИМЕНЯЕМЫЕ ДЛЯ ЗАПИСЕЙ-ЧЛЕНОВ Для типов записей-членов, известных в TOTAL как «переменные статьи», существуют особые операции OPENV и CLOSV, которые со- ответствуют операциям OPENM и CLOSM, применяемым для типов записей-владельцев. 21.15.1. Операторы поиска Рассматривая варианты поиска записей-членов, важно отметить один из параметров — так называемую «ссылку». Чтобы выполнить об- работку экземпляра набора способом, очевидным в системах КОДАСИЛ (см. разд. 15.5.1), необходимо инициализировать обработку с помощью специальной установки ссылки. При этом операция REDV, READ VARIABLE FORWARD (ЧИТАТЬ ПЕРЕМЕННУЮ ВПЕРЕД) будет выполняться почти таким же образом, как и FIND FIRST имя-записи IN имя-набора Однако в системах КОДАСИЛ и TOTAL имеется некоторое разли- чие, связанное со способом выбора набора. Определенный параметр в операторе CALL (управляющее поле) должен содержать соответствую- щее значение первичного ключа записи-владельца в обрабатываемом типе набора. Если нужно выполнить эквивалент FIND NEX Т имя-записи IN имя-набора 232
, параметр «ссылка» будет иметь другое значение. Однако при выполне- нии самого оператора READV этот параметр видоизменится и укажет выбранную запись. Очевидно, что ссылка здесь играет роль индика- тора текущей записи набора в КОДАСИЛ. Возможности, предоставляемые оператором READV, практически аналогичны тем, которые обеспечиваются вариантом 6 оператора RDNXT и вариантом 8 оператора FINDX (в последнем случае с Фиктив- ным критерием поиска, которому должна удовлетворять каждая про- веряемая запись). Существует еще один оператор, называемый READR, READ VARIABLE REVERSE (ЧИТАТЬ ПЕРЕМЕННУЮ НАЗАД), который не имеет эквивалента в RDNXT и FINDX, но действует подоб- но оператору READV. Третьим оператооом поиска записи-члена является READD, READ VARIABLE DIRECT (ЧИТАТЬ ПЕРЕМЕННУЮ НЕПОСРЕДСТ- ВЕННО), семантика которого также зависит от значения параметра «ссылка». Если последний содержит номер записи, находящейся в базе данных, то выбирается именно эта запись. В TOTAL такой номер называется «относительной позицией размещения записи». Этот вариант можно сравнить с «FIND по ключу базы данных» (см. разд. 15.6.2) в КОДАСИЛ. Оператор READD находит и другое применение, не имеющее прямо- го аналога в КОДАСИЛ. Первоначально его роль состояла в том, что- бы «... изменить направление цепи связи для последующих функций переменной статьи». Другими словами, этот вариант предназначался для инициализации поиска в точке, которая была идентифицирована в программе ранее. После его выполнения в последующем операторе можно продолжить обработку по любой цепи, к которой принадлежит запись. 21.15.2. Операторы обновления Операторы STORE для типов записей-членов в TOTAL также име- ют ряд интересных вариантов. Это объясняется тем, что здесь упорядо- чение в заданном типе набора определяет не администратор данных, а программист. При введении записи в базу данных используемый ва- риант специфицирует позицию в экземпляре набора, куда должна по- мещаться эта запись. Существуют три варианта, определяющие ука- занную позицию: В терминах КОДАСИЛ: ADD VC ADD VARIABLE CONTINUE ' (конец набора) ADD VB ADD VARIABLE BEFORE (перед текущей записью набора) ADD VA ADD VARIABLE AFTER (после текущей записи набора) ' При использовании вариантов ADDVA и ADDVB, если рассматри- ваемый тип записи является членом двух или более типов набора, воз- никает семантическая проблема. Параметр «ссылка» для этого опера- тора содержит или значение ключа базы данных (точку внутренней 233
ссылки), или имя набора. Если указан тип набора, то позиция записи определяется для его экземпляра (до или после текущей записи). К другим типам наборов она подсоединяется автоматически в конец цепи. Следует отметить не всегда удачное применение термина «первич- ная цепь связи» для ссылки на набор, к которому запись должна при- соединяться с помощью ADDVB или ADDVA. Этот термин исполь- зовался т*акже на этапе определения «кодированных записей» (см. разд. 21.3.2) для ссылки на тип набора, в котором все типы записи на- бора являются его членами, хотя и имел иной смысл. Назначение варианта ADDVC — разрешить включение записи в конец набора в любом случае. В последних руководствах по TOTAL этот вариант отсутствует, поэтому при трансляции он считается экви- валентным ADDVA. Для модификации записей-членов, уже находящихся в базе дан- ных, предусмотрены два оператора. Один из них — ADDVR, ADD VARIABLE REPLACE — некоторым образом ассоциируется с други- ми тремя операторами ADD. Ассоциация, правда, состоит лишь в том, что программисту в этом случае опять приходится использовать цепи связи, но это никоим образом не оправдывает имени операции. Вариант ADDVR должен использоваться при изменении значения управляю- щего поля. В результате запись будет отсоединена от одного набора и присоединена к другому, что аналогично действию следующего опера- тора КОДАСИЛ (см. параграф 16.2): MODIFY имя-записи ONLY имя-набора MEMBERSHIP Если нужно изменить значение не управляющего поля, а какого- либо другого элемента, то следует применить оператор WRITV, WRI- TE VARIABLE (ЗАПИСАТЬ ПЕРЕМЕННУЮ СТАТЬЮ). Заметим, что WRITV нельзя использовать для изменения содержимого управ- ляющих полей. Он воздействует на последнюю считанную запись (т. е. текущую запись процесса) и, следовательно, отличается от WRITM, который сам находит запись, которую должен изменить. Поэтому WRITV гораздо ближе к оператору MODIFY КОДАСИЛ (см. параграф 16.2), однако он не может переместить запись из одного набора в другой набор того же типа. Наконец, оператор DELVD, DELETE VARIABLE (УДАЛИТЬ ПЕРЕМЕННУЮ СТАТЬЮ) практически эквивалентен «простому» ERASE (см. разд. 16.3.1), действующему по отношению к последней считанной записи. 21.16. ЗАКЛЮЧЕНИЕ Подход к управлению базами данных TOTAL во многом аналогичен предложениям КОДАСИЛ. Их основное структурное различие заклю- чается в том, что TOTAL ограничивается плоскими сетями. Поэтому естественно выдвинуть требование, чтобы для всех записей-владель- цев применялся стандартный способ размещения CALC, которое, впро- чем, полезно было бы распространить и на записи-члены. 234
Язык манипулирования данными в TOTAL не так изящен, как со- ответствующий язык в КОДАСИЛ. Программы с различными операто- рами CALL, содержащими сложные списки параметров, будет труднее? читать и поддерживать, чем программы с «описательными» оператора- ми ЯМД. Семантика операторов STORE и MODIFY может создавать затруднения для программистов. С другой стороны, для проектировщика базы данных система TOTAL представляется более простой, чем системы КОДАСИЛ. Если он является новичком в области управления базами данных, то емv потребуется принимать меньше решений и разбираться в меньшем ко- личестве концепций. В этом, несомненно, заключается одна из причин коммерческого успеха системы TOTAL. ГЛАВА 22 СИСТЕМА IMS 22.1. ОСНОВНЫЕ КОМПОНЕНТЫ IMS—акроним Information Management System (система управ- ления информацией). Рассматриваемый здесь метод управления база- ми данных разработан фирмой North American Rockwell в середине шестидесятых годов. В 1967 г. он был принят в IBM и к настоящему времени претерпел существенные изменения. Тем не менее основные аспекты управления данными, несомненно, принадлежат первоначаль- ной системе. Важно отметить, что IMS является не только системой управления базами данных. В терминологии IBM она определяется как «Система баз данных/ передачи данных». Другими словами, почти половина то- го, что подразумевается под акронимом IMS, представляет собой сред- ства управления передачей данных, которые в настоящей книге не об- суждаются. Часть, относящаяся к базе данных IMS, иногда называет- ся DL/1, Data Language 1, (Язык данных 1). Этот термин был введен фирмой North American Rockwell. Здесь мы воспользуемся сокраще- нием IMS, которое имеет более широкое распространение. Следует от- метить, что IMS использует обозначение DL/1 для идентификации той части системы, которая в КОДАСИЛ называется резидентным моду- лем СУБД (см. параграф 2.6). Термин «схема» в IMS не употребляется, но близкая к этому поня- тию функция обеспечивается одним или более управляющими блоками, известными под названием «Определение базы данных» (ОВД). Средства подсхемы (см. параграф 2.4) также обеспечиваются в IMS, но не на уровне внутренних структур, а на уровне структур связи между записями. Подсхема специфицируется посредством определения ряда Блоков связи с программой (РСВ), которые в совокупности назы- ваются Блоком спецификации программы (PSB). Как и ОБД, исход- ный язык РСВ является фактически набором макрооператоров ассемб- лера системы IBM/360.j 235
22.2, РЕАЛИЗАЦИЯ ЯМД Язык манипулирования данными в IMS аналогичен ЯМД в TOTAL. Другими словами, он реализован с помощью оператора CALL. Одна- ко вызываемые модули у разных включающих языков имеют разные названия. Например, для Кобол-программы следует писать: CALL 'CBLTDLI’ USING счетчик-параметров, функция, имя-РСВ, область ввода- вывода, SSA-L ...» SSA-n. Значение параметров этого оператора объясняется ниже. 22.3. КОНЦЕПЦИИ СТРУКТУРИРОВАНИЯ Так же как в КОДАСИЛ и в TOTAL, структура базы данных IMS основана на типах связей между записями (см. параграф 3.3), а тип набора, как и в TOTAL (см. параграф 3.4), называется связью. Значе- ние термина база данных в IMS отличается от его значения в указанных системах, посколь- ку в IMS имеются два различных типа базы данных. Тип записи здесь не вполне четко оп- ределен. Однако мы попытаемся объяснить эти два понятия, прежде чем продолжить об- суждение. Для обозначения структурной концепции, которая в КОДАСИЛ и TOTAL известна как тип записи, в IMS используется термин тип сегмента. Однако в литературе встре- чается ссылка на запись IMS и, чтобы по- нять их смысл, необходимо уяснить значение базы данnix /MS. Известно, что IMS полностью построена на иерархических структурах. Фактически сама база данных IMS представляет собой та- кую структуру. Структуры, допустимые для базы данных IMS, приведены на рис. 22.1—22.4. На вершине каждой из показанных четырех иерархических структур находится один тип записи. По терминологии IMS он называется типом корневого сегмента. Запись IMS есть экземпляр этого типа корневого сегмента со всеми экземплярами записей низшего уровня, которые прямо или косвенно связаны с ним. На рис. 22.5 приведена запись IMS для /-образной структуры, изображенной на рис. 22.2. Поскольку представление типа набора будет описано ниже, значение линий, соединяющих экземпляры записей, и отсутствие на них стре- лок мы объясним позднее. Пока же можно считать, что все восемь эк- земпляров записей на рис. 22.5 составляют одну запись IMS базы дан- ных, показанной на рис. 22.2. Для этих восьми записей существует показатель «близости», который отсутствует в КОДАСИЛ и в TOTAL и с которым мы скоро познакомим читателя. 236
КОМПАНИЯ ОТДЕЛ 237
22.3.1. Внутренняя структура записи В ранних версиях IMS все экземпляры каждого типа записи долж- ны были иметь одинаковую длину. В последней же версии IMS/VS любому типу записи разрешается иметь фиксированную или перемен- ную длину. За исключением этого, IMS не связана с внутренней струк- турой записи. При подготовке описания базы данных (т. е. схемы) нет необходимости называть все элементы в типе записи. Однако длина по- следнего должна задаваться, что позволит заранее резервировать мес- то для каждого экземпляра записи. В IMS/VS типы записи могут иметь переменную длину на любом уровне в иерархической базе данных. 22.3.2. Типы набора Уяснив значение иерархии в IMS, вернемся к концепции типа на- бора и посмотрим, какую роль играет эта структурная концепция в базе данных. Прежде всего отметим, что она принципиально иная, чем в КОДАСИЛ или TOTAL. Очевидно, в иерархической структуре любой тип записи-члена мо- жет иметь не более одного владельца. Поэтому проектировщики IMS не сочли нужным вводить названия для типов набора. Тип набора в ба- зе данных определяется в декларации типа записи путем простого ука- зания имени другого типа записи. В IMS вместо термина запись-вла- делец, принятого КОДАСИЛ, применяется термин исходная запись, а вместо термина запись-член — порожденная запись. Каждый тип записи в иерархической структуре имеет одну и толь- ко одну исходную запись, за исключением, конечно, типа корневого сегмента. Последний должен всегда определяться первым для каж- дой иерархической структуры. Ранние версии IMS ограничивались только этими иерархическими структурами, каждая из которых, как уже отмечалось, составляет базу данных. Допускается одновременное определение нескольких таких баз данных. Более того, прикладная программа может обрабатывать несколько из них. (В КОДАСИЛ и TOTAL говорят об одной опреде- ленной базе данных, и именно в ней программа обрабатывает данные. То, что IMS позволяет программе обрабатывать несколько объектов, которые здесь называются базами данных, связано скорее с необхо- димостью, а не с ее достоинствами.) В 1970 г. IBM, выявив слабые стороны иерархического подхода, постаралась их устранить в IMS/2. В этой системе каждому типу запи- си-члена разрешено соотноситься с двумя типами записей-владель- цев. Метод определения последовательности иерархических баз дан- ных был по необходимости принят. Однако стало возможным нахожде- ние второго отношения между типом записи в одной иерархии и дру- гим типом записи, который может размещаться в другой базе данных. Теперь речь может идти о двух владельцах: один из них, находящий- ся в той же базе данных, что и рассматриваемый тип записи, называет- ся физически исходной записью, а другой—логически исходной записью. База данных по определению называется физической базой данных. 238
Далее, когда мы введем концепции подсхемы IMS, будет ясна и кон- цепция логической базы данных. На рис. 22.6 показаны две физические базы данных, связанные логически. Каждый тип записи может иметь одну физически исходную запись и не более одной логически исходной записи. Физическая связь здесь показана сплошной линией, а логическая — пунктирной (ср. со способом включения в КОДАСИЛ — параграф 7.1, — где пунктир- ная линия используется для изображения неавтоматического включе- ния, а сплошная — для автоматического). С помощью иерархических структур и логических отношений можно представлять сетевые струк- туры. Рис. 22.6. Логическое отношение Завершая обсуждение логических отношений, приведем выдержку из IMS/VS DB Primer (Руководство для начинающих) [1]. «Правила определения логических отношений в физических базах данных. Логически порожденный сегмент 1. Логически порожденный сегмент должен иметь один и только один физически исходный сегмент и один и только один логически ис- ходный сегмент. 2. Логически порожденный сегмент определяется как физически порожденный сегмент в физической базе данных его физически исход- ного сегмента. 3. В своей физической базе данных логически порожденный сег- мент не может иметь другого логически порожденного сегмента, непо- средственно зависящего от него. Логически исходный сегмент 1. Логически исходный сегмент может быть определен на любом уровне физической базы данных, включая уровень корня. 2. Логически исходный сегмент может иметь один или несколько типов логически порожденного сегмента. 3. Сегмент в физической базе данных не может определяться как логически исходный и как логически порожденный одновременно. 239
4. Логически исходный сегмент может определяться в той же или другой физической базе данных как логически порожденный сегмент; Физически. исходный сегмент 1. Физически исходный сегмент логически порожденного сегмента не может быть также логически порожденным сегментом (см. правило 3 для логически порожденного сегмента)». Кроме того, следует отметить, что существует взаимосвязь между определением логических отпадений и представлением типов записи в памяти, 22.4. ПРЕДСТАВЛЕНИЕ ТИПА ЗАПИСИ В ПАМЯТИ Установив, что любая база данных IMS является иерархической структурой, рассмотрим вопрос о том, как такие структуры отобража- ются в памяти. В отличие от системы TOTAL, не имеющей никаких вариантов, в IAAS их предлагается несколько, но все они весьма отли- чаются от тех, которыми располагают системы КОДАСИЛ. Во-первых, в системах КОДАСИЛ можно (и нужно) выбирать спо- соб размещения (см. параграф 4.4) для каждого типа записи в базе данных. В IMS достаточно выбрать один метод доступа для физической базы данных в целом. Существуют четыре иерархических метода до- ступа: HSAM — последовательный; HISAM — индексно-последовательный; HDAM — прямой; HIDAM —индексно-прямой. Сравнивая эти методы, можно заметить в них некоторые общие ас- пекты с подходом КОДАСИЛ. Тип корневого сегмента нетрудно пред- ставить как тип записи со способом размещения CALC, где CALC не обязательно означает рандомизацию (см. параграф 4.5.). Другие типы записей более низкого уровня в базе данных можно представить как имеющие способ размещения VIA SET (см. параграф 4.7), поскольку считается, что записи одинакового типа располагаются по возможно- сти ближе друг к другу и к своим владельцам (т. е, к исходному сегмен- ту), хотя степень их близости зависит от используемого метода доступа. Метод HSAM предназначен в основном для базы данных, записан- ной на магнитной ленте, и в этом смысле он отличается от трех других методов доступа. Обновление физической базы данных HSAM не сов- падает с обновлением любой из трех остальных. Более того, не имеет смысла разрешать типам записи в этой базе данных иметь логически исходный сегмент или быть им. Следует отметить здесь также отсутст- вие журнализации. Этот метод применяется очень редко. Метод HISAM основан на хорошо известном методе индексно-по- следовательного доступа. В качестве первичного ключа здесь исполь- зуется какой-либо элемент в типе корневого сегмента. С HISAM можно также вовлекать типы записей второго уровня (т. е. порожденные сег- менты типа корневого сегмента). В результате ключ второго уровня 240
сочленяется с ключом корневого сегмента, образуя ключ ISAM, что позволяет искать записи непосредственно на втором уровне. При методе HDAM корневые сегменты хранятся в месте, которое определяется задаваемым пользователем алгоритмом рандомизации. Последни й может иметь вид, как и для систем КОДАСИЛ (см. пара- граф 4.5). При методе HIDAM корневые сегменты записываются при- близительно в порядке возрастания их ключей и выбираются с по- мощью отдельного индекса. В HDAM и в HID AM каждый сегмент ниж- него уровня записывается и выбирается посредством цепочек указа- телей, идущих от своего владельца (исходного сегмента). Записи ниж- него уровня помещаются в память с помощью довольно сложного ал- горитма сцепления. Такой же метод размещения записей нижнего уровня используется и при HIDAM, но тип корневого сегмента запи- сывается посредством метода ISAM, а не рандомизации. Одна из целей IMS — предоставить пользователю возможность контролировать выбор компромиссных решений, позволяя ему в то же время менять методы доступа. Вполне вероятно, что пользователь по^ желает перейти от метода HSAM к какому-либо другому, но вряд ли ему захочется перейти от другого метода к HSAM. Поэтому програм- мистам, которые пишут программы для обработки базы данных IMS, не обязательно знать, HISAM это, HDAM или HIDAM Если програм- мист составляет программу поиска, ему вовсе не должно быть извест- но, является ли база данных HSAM или нет. Тем не менее опыт пока- зывает, что метод доступа может иметь решающее значение. В конкрет- ной ситуации от его правильного выбора зависит время выполнения программ. 22.5. ПРЕДСТАВЛЕНИЕ ТИПА НАБОРА В ПАМЯТИ Способ представления типа набора в памяти в IMS может быть свой- ством всей физической базы данных или же единственного типа набо- ра, как в КОДАСИЛ. В отличие'от TOTAL, где используются исключи- тельно двунаправленные цепочки (см. параграф 21.5), в IMS существу- ет несколько вариантов, не совпадающих с вариантами КОДАСИЛ (см. параграфы 5.4 и 5.8). Однако следует напомнить, что в последнее время в КОДАСИЛ наметилась тенденция оставлять решение данного вопроса за разработчиком, так как программисту не нужно это знать при составлении его программы. Поскольку варианты IMS не имеот эквивалентов в КОДАСИЛ, мы для их описания воспользуемся тер- минологией IMS. Различные варианты идентифицируются видом используемых в них указателей, которые хранятся в записях базы данных. Не ко всем вариантам могут применяться указанные выше три метода доступа при использовании памяти прямого доступа. Выбор конкретного метода зависит от того, как размещаются в структуре записи низшего уровня. Эта тема не обсуждалась в предыдущем параграфе, однако очевидно, что выбор комбинации метода доступа и варианта указателей может иметь иногда решающее значение, так как при некоторых комбинаци- ях программа может функционировать правильно, но неэффективно. 241
В IMS существуют два основных класса указателей. К первому классу относятся указатели, направленные от каждого владельца к первому члену в наборе (в терминологии IMS — к первому порожден- ному сегменту) и от каждой записи к следующей (к прямому подобно- му сегменту). Последний применяется также для указания от одного экземпляра корневого сегмента к следующему. Рис. 22.7. Первый порожденный сегмент — прямой по- добный сегмент На рис. 22.7 такой указатель представлен для логической структу- ры, показанной на рис. 22.2. Рис. 22.8. Первый порожденный сег- мент— прямой и обратный подобные сегменты Рис. 22.9. Первый и последний поро- жденные сегменты — прямой и обрат- ный подобные сегменты В данном варианте к двум основным указателям можно добавить следующие три указателя: последний порожденный сегмент; обратный подобный сегмент; исходный сегмент, а также любую их комбинацию. В этом случае можно выбирать указа- тели для каждого отношения, но обычно принято выбирать их для всей физической базы данных. На рис. 22.8, 22.9 и 22.10 приведены приме- 242
ры двух основных указа- телей с некоторыми наибо- лее распространенными до- полнител ьными варианта- ми для одной физической базы данных. Важно отметить, что указатели в такой ситуа- ции могут определяться как для физических, так и для логических отноше- ний. Употребление терми- нов «физический» и «логи- ческий» для определения класса указателя вполне Рис. 22.10. Первый порожденный сегмент, прямой подобный сегмент и исходный сег- мент оправданно, например: первый физически порожденный сегмент; прямой физически подобный сегмент; обратный физически подобный сегмент; физически исходный сегмент, или первый логически порожденный сегмент; прямой логически подобный сегмент; обратный логически подобный сегмент; логически исходный сегмент. Рис. 22,11. Односторонние иерархические ука- затели Второй класс указателей носит название иерархического. В него входят указатели, которые могут определяться для полной физической базы данных. Среди них различают так называемые односторонние и двусторонние иерархические указатели. Заметим, что смешение клас- сов указателей в одной и той же физической базе данных связано с не- которыми ограничениями. 243
Односторонние иерархические указатели показаны на рис. 22.11, а двусторонние — на рис. 22.12. Рассмотренные выше классы указателей требуют пояснения. По умолчанию обычно принимается первый порожденный сегмент — прямой подобный сегмент (рис. 22.7). Следовательно, по мнению раз- Рис. 22.12. Двусторонние иерархические указатели ' работника, это наилучший вариант. Иерархические указатели могут показаться несколько необычными, если не учитывать действия одного из операторов FIND (GET NEXT). 22.6. УПОРЯДОЧЕНИЕ НАБОРА При определении базы данных администратор данных может в каждом типе записи нижнего уровня выбрать какой-либо элемент в качестве атрибута упорядочения. Поскольку любой тип записи ниж- него уровня является членом (в терминах IMS порожденным сегмен- том) одного и только одного типа набора, этому атрибуту упорядоче- ния в системах КОДАСИЛ соответствует ключ сортировки (см. пара- граф 6.3). Как и в КОДАСИЛ, администратор данных IMS может сделать ключ сортировки уникальным или не уникальным, причем первый определяется по умолчанию. Атрибут упорядочения играет важную роль в семантике нескольких операторов ЯМД, которая будет показана далее. Пока же интересно отметить, что методы систем КОДАСИЛ, TOTAL и IMS дают крайне различные решения вопроса об упорядочении набора. Как уже указы- валось в разд. 6.3.1, в системах КОДАСИЛ нужно иметь серьезную причину, чтобы выбрать сортируемый тип набора. 22.7. ПОИСКОВЫЕ КЛЮЧИ Первые версии IMS не поддерживали никакой вторичной индекса- ции, но в IMS/VS она была введена. Это относительно сложное средст- во, пожалуй, ближе к глобальному ключу поиска КОДАСИЛ, чем к более раннему «поисковому ключу внутри набора» (см. параграф 6.10), 244
В IMS вторичный индекс могут иметь и тип корневого сегмента, и зависимые от него сегменты. В последнем случае предлагается инте- ресное расширение. Для индексации типа записи-владельца можно пользоваться элементом типа записи-члена. Эгот владелец должен быть физически исходным сегментом, а не логически исходным. Сама таблица вторичных индексов является физической базой дан- ных IMS. Следует отметить, что это вполне согласуется с тем, что в IMS/VS типы записей нижнего уровня могут иметь переменную длину. 22.8. СПОСОБ ВКЛЮЧЕНИЯ И ДОПУСТИМОСТЬ ИСКЛЮЧЕНИЯ Отсутствие в IMS концепции способа включения (см. параграф 7.1) означает, что каждый тип записи-члена является автоматическим чле- ном одного или двух типов набора. Здесь избегают проблем точно так же, как и в TOTAL (см. параграф 21.8). Допустимость исключения (см. параграф 7.2) связана с семантикой оператора ERASE (см. параграф 16.3). В IMS он называется DELETE и действует так же, как ERASE ALL (см. разд. 16.3.2). Другими сло- вами, при удалении записи удаляются также все зависимые от нее нижестоящие записи в физической базе данных. Если удаленная за- пись является исходной в логическом отношении, то это дает допол- нительную гибкость — и сложность. 22.9 ВЫБОР НАБОРА В IMS отсутвуют варианты выбора набора, и сам выбор осуществ- ляется совсем не так, как в TOTAL. По существу, решение IMS пред- ставляет собой один из наиболее распространенных вариантов КОДА- СИЛ — так называемый иерархический выбор набора (см. параграф 8.6). Однако в IMS путь вниз по иерархии всегда начинается с корне- вого сегмента и определяется в терминах атрибута упорядочения, рас- смотренного в параграфе 22.6. В принципе здесь, как и в большинстве вариантов КОДАСИЛ, оп- ределение пути выбора предоставляется программисту. В TOTAL же (см. параграф 21.9), метод выбора набора основан на дублировании элементов данных в типах записей-членов. 22.10. ПОДСХЕМА В IMS данные на уровне схемы представляются сетью, определен- ной одной или более физическими иерархическими структурами, ко- торые, возможно, связаны логическими отношениями. Спецификация представления данных на уровне подсхемы выполняется в два этапа. Первый этап заключается в преобразовании сети, определенной в схеме, в одну или более иерархических структур, которые называют- ся логическими базами данных в отличие от физических баз данных, первоначально определенных в схеме. Корневым сегментом каждой логической базы данных должен быть корневой сегмент физической базы или сегмент, который можно выбирать непосредственно при ис- 245
пользовании вторичного индекса. Зависимые сегменты в указанной логической базе данных должны располагаться на путях, специфици- рованных в схеме (другими словами, они должны быть связаны по- средством физических или логических отношений). Логическая база данных может включать типы сегментов из двух или более физических баз данных. Обычно для каждого типа физиче- ского корневого сегмента определяется одна логическая база данных. Второй этап — определение представлений на уровне подсхемы для конкретной программы. Для этой цели применяются блоки специфика- ции программы (PSB), каждый из которых содержит один или более блоков связи с программой (РСВ). Блок спецификации программы оп- ределяет часть иерархической структуры, являющуюся логической базой данных. Ниже объясняются некоторые термины IMS, относящиеся к кон- цепции подсхемы. Говорят, что тип сегмента чувствителен к програм- ме, если он включен в РСВ, который используется в программе. Отсюда происходит и термин чувствительность сегмента. В том случае, когда программа чувствительна к типу сегмента, но не к зависимым от него сегментам, возникает затруднение. При удалении сегмента того типа, к которому чувствительна программа, удаляются и все зависимые от него сегменты, несмотря на то, что она может быть к ним нечувстви- тельна. Определение РСВ имеет важную особенность: для каждого чувст- вительного типа сегмента необходимо указывать один или более ва- риантов обработки. Например, если программе разрешается искать сегменты данного типа, то специфицируется вариант обработки G (GET). Любая попытка исключить или заменить сегмент этого типа окажется безуспешной. Эта концепция варианта обработки дополня- ется вариантом К (Key), который означает, что программа чувстви- тельна только к ключевому элементу в типе записи. 22.11. КОНЦЕПЦИИ ЯМД Как уже отмечалось, все обращения к базе данных со стороны вклю- чающего языка (см. параграф 13.2) обычно осуществляются с помощью оператора CALL. Однако недавно было объявлено о создании двух предтрансляторов: COBIMS и PLIMS, которые позволяют программи- сту писать операторы IMS в повествовательной форме в программах, составленных на языках Кобол и ПЛ/1. Формат оператора CALL для Кобола имеет вид: CALL ’CBLTDLI’ USING счетчик-параметров, функция, имя-РСВ, область ввода-вывода, SSA-1, ..., SSA-n В этом списке «функция» указывает имя выполняемого оператора. Допустимы, например, следующие коды функций: GU, GN, GNP, ISRT, DLET и REPL. Первые три из них представляют различные ва- рианты GET, а три последние являются основными вариантами об- новления •— поставить, удалить, заменить. Имя-РСВ относится к области памяти, которая должна включаться в секцию связи в разделе данных программы и специфицироваться в 246
фазе определения подсхемы (в IMS называется PSBQEN). Область па- мяти в программе содержит ряд важных параметров, в том числе: 1. Имя базы данных. 2. Код состояния (для связи с вызывающей программой). 3. Им я сегмента (для обратной связи с вызывающей программой). 4. Длина ключа обратной связи. 5. Область ключа обратной связи. Большая часть так называемой «маски РСВ» предназначается фак- тически для обратной связи системы с программой. Параметр «область ввода-вывода» указывает, в каком месте про- граммы помещается экземпляр записи после ее успешного поиска или где ее нужно искать для постановки или замены. Область ввода-вывода играет ту же роль, что и область записи в КОДАСИЛ (см. параграф 12.4). Однако в IMS она определяется пользователем. Параметры SSA-1, ..., SSA-n обозначают области в основной памяти, в которых программист хранит свои так называемые аргументы поис- ка сегмента (SSA). Концепция аргумента поиска сегмента представля- ет существенную часть семантики ЯМД IMS и поэтому требует некото- рого пояснения. 22.11.1. Аргументы поиска сегмента Оператор CALL, имеющий один или более параметров SSA, назы- вается уточненным, а оператор, не имеющий этих параметров, — неуточнентым. Различают три варианта формата SSA: 1. Имя сегмента. 2. Имя сегмента, имя элемента, оператор отношения, значение сравнения. 3. Имя сегмента, имя элемента, оператор отношения, значение сравнения. [Логический оператор, имя элемента, оператор отноше- ния, значение сравнения]. Здесь оператором отношения может быть любой из шести стандарт- ных операторов, а логическим — любой из двух обычных. Мы ограни- чимся рассмотрением первых двух вариантов. Важно отметить, что данные аргументы поиска сегмента являются областями в прикладной программе, и, следовательно, программист может модифицировать их содержимое, вводя в них необходимые ему значения. Это открывает перед ним широкие возможности. Значение аргумента поиска сегмента, как будет показано ниже, не- сколько варьируется в зависимости от той функции, в которой он ис- пользуется. 22.11.2. Операторы поиска Оператор GET в IMS представляет собой комбинацию операторов FIND (см. параграф 15.2) и GET (см. параграф 15.8) КОДАСИЛ. После выполнения GET в IMS запись помещается в область, обозначен- ную в параметре «область ввода-вывода». Какая это запись — зави- 247
сит от используемого варианта GET, а также от наличия и значения аргументов поиска сегмента. Оператор GET UNIQUE (GU) играет в IMS роль «непосредствен- ного» FIND (см. параграф 15.4). Аргументы поиска сегмента можно использовать для определения пути в иерархии от самого верхнего уровня до нижнего. Фактически выбранная запись обязательно будет находиться на самом нижнем специфицируемом уровне. Оператор GET NEKT (GN) является более простым из двух вариантов «отно- сительного» FIND в IMS (см. параграф 15.5). Он часто используется без аргументов поиска сегмента, чтобы получить доступ к той записи в иерархии, которая окажется «следующей» за самой последней выб- ранной (текущей) записью процесса. Интересно сравнить оператор GET NEXT с оператором FIND NEXT IN имя-набора в КОДАСИЛ (см. разд. 15.5.1). Последний оста- навливается в конце экземпляра набора. Оператор IMS может дейст- вовать до последней записи в базе данных. Его путь показан на рис. 22.11. Оператор GET NEXT следует правилу обработки иерар- хии сверху вниз и слева направо. Если аргумент поиска сегмента отсут- ствует, то оператор (неуточненный) спустится на один уровень вниз и выберет там первую запись. В том случае, когда запись является вла- дельцем двух членов набора, соблюдается последовательность, в кото- рой эти члены были определены в РСВ. При отсутствии записей, зави- симых от текущей, осуществляется поиск следующей записи того же типа, и если ее нет— ищется следующая исходная запись. Другой вариант относительного FIND—GET NEXT WITHIN PARENT (ВЗЯТЬ СЛЕДУЮЩУЮ В ИСХОДНОМ СЕГМЕНТЕ, GNP) используется для последовательной обработки подструктуры, связанной с данным экземпляром записи. В документации IMS осве- щается интересная проблема «установления отцовства» исходного сег- мента. Эта проблема решается обычно во время выполнения оператора GET UNIQUE или GET NEXT. Следует отметить, что установленное «отцовство» не видоизменяется каким-либо последующим оператором GNP. Такой же эффект будет наблюдаться только при выполнении другого оператора GU или GN. Прежде чем перейти к обсуждению операторов обновления, объяс- ним назначение варианта HOLD. Чтобы заменить или удалить запись из базы данных, программе сначала требуется ее найти. Для обнов- ления записи программист должен включить в GET вариант HOLD. Тем самым юн сообщаёт системе, что будет выполнено обновление дан- ной записи. Вместо кодов функций, GU, GN и GNP, он пишет GHU, GHN или GHNP. Семантика этих вариантов в режиме параллельной обработки довольно сложная, но программисту ее знать необяза- тельно. 22.11.3. Операторы обновления Существуют три оператора обновления: DLET (Pelete — удалить); REPL (Replace — заменить); ISRT (Insert поставить в базу данных). 248*
Оператор DLET воздействует в основном на запись, которая была найдена одним из операторов GET или HOLD. В отличие от TOTAL (см. разд. 21.12.2), результатом выполнения указанного оператора в IMS является удаление порожденных записей всех поколений, как и при использовании ERASE ALL в КОДАСИЛ (см. разд. 16.3.2). Это происходит в любом случае, независимо от того, чувствительна ли выполняемая программа к записям данного типа или нет. Подобная ситуация может отразиться и на логических отношениях. Устранить такое явление можно двумя способами. Один из них заключается в обя- зательном определении соответствующего варианта обработки в РСВ для удаления верхнего типа записи, а другой — в запрещении спе- цифицировать оператор DLET с аргументами поиска сегмента. Оператор REPL также воздействует на запись, которая была най- дена с помощью GET и HOLD. Модификация этой записи должна осу- ществляться в области ввода-вывода до его выполнения. Нельзя моди- фицировать значение атрибута упорядочения (см. параграф 22.6). Последнее является довольно существенным ограничением, которое отсутствует в операторе MODIFY системы TOTAL (см. разд. 21.12.3), поскольку там нет такого атрибута упорядочения, и в сортированных наборах КОДАСИЛ. Чтобы снять эту проблему, в IMS необходимо удалить запись, а затем вновь поставить ее с новым значением атри- бута упорядочения. При этом программист должен выполнить некото- рые действия по отношению к подструктуре, которую он желает сохра- нить, что может создать сложную ситуацию, рассмотрение которой вы- ходит за рамки настоящей книги. Оператор ISRT не следует путать с другим известным оператором CONNECT КОДАСИЛ (см. параграфы 13.8 и 16.6). Его можно скорее сравнить с оператором STORE КОДАСИЛ (см. параграф 16.4). Пол- ная семантика ISRT очень сложна, поэтому здесь достаточно привести упрощенное описание некоторых из его возможностей. Данный оператор предназначен для начальной загрузки и после- дующего обновления. Его нельзя применять для обновления файла HSAM по вполне очевидным причинам. Если 1SRT выполняется с целью обновления, обычно используется аргумент поиска сегмента для спе- цификации всего пути, начиная с корневого сегмента и до того места в иерархии, в которое должен быть поставлен сегмент. Однако на уров- не, соответствующем этому сегменту, данная позиция определяется значением атрибута упорядочения в области записи. В тех случаях, когда разрешаюся дублирующие значения атрибута упорядочения или когда он отсутствует, вводятся специальные правила и варианты пара- метров. 22.11.4. Другие операторы ЯМД Необходимо отметить одно важное свойство системы IMS, заклю- чающееся в том, что в ней отсутствует оператор OPEN или READY (см. гл. 14). Действительно, база данных открывается для программы автоматически в начале ее выполнения. Различие между двумя режи- мами обработки — обновления и поиска (см. разд. 14.2.1) -— указы- 249
вается пугем спецификации варианта отработки в РСВ. Как и в TOTAL, режим параллельной обработки является фактически UNRESTRI- CTED, н о можно также специфицировать эквивалент «монопольной обработки:» для каждого типа сегмента. 22.12. ЗАКЛЮЧЕНИЕ Как мы видим, подход IMS к управлению базой данных существен- но отличается от подходов КОДАСИЛ и TOTAL. Систему TOTAL мож- но представить в виде упрощенного подмножества предложений КО- ДАСИЛ, шо по отношению к IMS это сделать невозможно. Акцент на определение и обработку только иерархических структур придает методу кажущуюся простоту, но это впечатление быстро ис- чезает при глубоком изучении семантики ЯМД с весьма сложным средством использования аргументов поиска сегмента. Что касается определения данных, то решение о сортировке неко- торых типов набора так же сказывается на работе с большими набора- ми, как и в системе, основанной на предложениях КОДАСИЛ. Язык манипулирования данными имеет много «подводных камней». Существует1 целый ряд факторов, которые программисту вовсе не обя- зательно знать, чтобы писать правильно работающие программы. Тем не менее он может извлечь пользу из знакомства с ними, если ему нужно составлять эффективные программы. ЛИТЕРАТУРА 1. IMS/VS-DB Primer. IBM document No. S320 — 5767. ГЛАВА 23 СИСТЕМА ADABAS 23.1. ОСНОВ НЫЕ КОМПОНЕНТЫ Система ADABAS не так широко распространена, как IMS и TOTAL, но тем не менее она привлекает внимание пользователей и потому заслуживает рассмотрения. В настоящее время существуют две реализации ADABAS: для вычислительных систем IBM 360/370 и Siemens 4004. Компонентами ADABAS, соответствующими определенным в гл. 2, являются: Схемы ЯОД Управляющие перфокарты для служебных программ LOADER Язык Манипулирования Данныьли Команды ADABAS 23.2. РЕАЛИЗАЦИЯ ЯМД Язык манипулирования данными в ADABAS представляет собой расширение существующих языков программирования, таких, как Кобол, ПЛ/1 и язык Ассемблера. Каждая команда ADABAS являeтcяJ 250
двухлитерным кодом, содержащимся в блоке управления, на который делается ссылка в операторе CALL. Последний имеет следующий формат: CALL ’ADABAS’ USING блок-управления, буфер-формата, буфер-запнси, буфер-поиска, буфер-значения, буфер-ISN Этот формат сохраняется неизменным, независимо от используемо- го типа оператора ЯМД. Для каждого из шести параметров в операто- ре CALL программист должен иметь одну или более областей, опреде- ленных в своей секции рабочей памяти. Существует фиксированный список содержимого для «блока-управ- ления». Один из его параметров часто называют ‘COMMAND-CODE’ (код команды). С помощью этого кода указывается, какой из операто- ров ЯМД выполняется. Он определяет также роль областей, заданных в других параметрах и других частях блока-управления. 23.3. КОНЦЕПЦИИ СТРУКТУРИРОВАНИЯ Система ADABAS интенсивнее, чем какая-либо другая из трех рас- смотренных выше, использует внутреннюю структуру записи. Она применяет также и внешние структуры, причем ее методы существен- но отличаются от методов КОДАСИЛ, IMS и TOTAL. Подход ADABAS аналогйчен подходу КОДАСИЛ в том отношении, что позволяет иметь полную сетевую структуру. Единственной пред- ставляющее интерес ограничение вводится лишь при использовании одного из двух возможных способов представления связей между записями. 23.3.1. Внутренняя структура записи В то время как средства построения внутренней структуры записи в других системах диктуются возможностями используемых включаю- щих языков, ADABAS имеет свое собственное, довольно уникальное средство, не совместимое со средствами Кобола и ПЛ/1. Причина этого кроется, возможно, в том, что система первоначально проектирова- лась автономной. После выявления недостатков систем этого класса она стала системой с включающим языком, но нестандартный тип внутренней структуры записи был в ней сохранен. В ADABAS разрешается иметь одну или более переменных повто- ряющихся групп на верхнем уровне, т. е. нуль, один или более экзем- пляров групп для каждого экземпляра записи. Более того, в ней мож- но определять фиксированные повторяющиеся группы, а также век- торы фиксированного или переменного размера на верхнем уровне или внутри повторяющейся группы. В терминологии ADABAS вектор есть многозначное поле, а повторяющаяся группа — периодическое группо- вое поле. 23.3.2. Связи между записями В системе предусмотрены два способа представления связей между записями. Однако оба они зависят от концепции так называемого дескриптора, который, по существу, является поисковым ключом 251
на уровне записи КОДАСИЛ (см. разд. 6.10.3), но не уникальным поисковым ключом. Фактически единственный путь достижения уни- кальности одного из этих ключей — ввести необходимые тесты в про- граммы, обновляющие записи того типа, для которого, требуется уникальный ключ. . Для тжша записи может специфицироваться один или более ключей поиска. (ЗВ терминах ADABAS для любого файла может существовать один или более дескрипторов, причем файлом являются все записи не- которого -типа в базе данных.) Чтобы между двумя типами записей име- ло место жюлнозначное отношение, у каждого из них должны быть по- исковые ключи. Более того, необходимо предусмотреть возможность сопоставления значения одного ключа со значением другого и провер- ки их равенства. Представление отношений осуществляется следующим образом. Существует средство, называемое связью, которое можно определять (с помощью управляющих перфокарт) как часть процесса загрузки ба- зы данные. При использовании такого средства говорят, что два фай- ла связана, и эта связь представляется в памяти посредством индек- сирования:. Кроме того, в этом случае выполняется специальный рабо- тающий с множеством записей оператор FIND, если применяется неко- торое условное выражение, которое включает условия на элементы по- искового ключа в обоих типах записи. Поскольку ссылка на это от- ношение неявная, т. е. связь явно не называется по имени в операторе FIND, в ЯОД схемы не требуется его именовать. Поэтому между лю- быми двумя файлами в базе данных средство связи может определять- ся только один раз. Как показывает опыт пользователей ADABAS, рассмотренное сред- ство связи нельзя считать вполне удовлетворительным, поскольку оно требует большого объема памяти и неблагоприятно отражается на эксплуатационных характеристиках. Тем не менее если для двух типов записей определены поисковые ключи и если, как и прежде, можно сравнивать их значения, то (так как действие поискового ключа осно- вано на методах индексирования) между двумя типами записей суще- ствует отношение. Поясним это на примерах. На рис. 23.1 показаны два типа записей: ОТДЕЛ и СЛУЖАЩИЙ- Допустим, что запись ОТДЕЛ имеет ключ поиска №-ОТДЕЛА; а за- пись СЛУОКАЩИЙ — №-ОТД-СЛУЖ« Эти имена намеренно выбра- ны различными, но допустимое множество значений для них одинако- во, т. е. их значения сопоставимы. Мы привели этот пример потому, что обычно желательно использовать №-ОТДЕЛА в качестве уникаль- ного ключ^. Как уже отмечалось, в ADABAS такая возможность от- сутствует. С другой стороны, №-ОТД-СЛУЖ не может быть уникаль- ным ключом, поскольку в любом конкретном отделе работают несколь- ко служащих. Можно выбрать всех служащих в данном отделе (а именно эк- земпляр набора, владельцем которого является запись этого отде- ла), если известно значение №-ОТДЕЛА, и установить, что имеется равное значение ЖОТД-ОПУЖ. 252
С другой стороны, здесь есть вероятность ошибки — в базе дан- ных могут оказаться два экземпляра записи ОТДЕЛ с одинаковыми значениями №-ОТДЕЛА. Это создает определенные проблемы. Второй пример на рис. 23.2 показывает отношение «многие ко мно- гим» между записями ЧЕЛОВЕК и МАШИНА. Тип записи ЧЕЛОВЕК содержит поисковый ключ с именем ТИП-МАШИНЫ-КОТОРЫМ-УП РАВЛЯЕТ.Это значит, что на каждого человека приходится одна или более машин, которыми он может управлять. Тип записи МАШИНА Рис, 23.1. Связь ADABAS — «многие со многими» (неудачная связь) Рис. 23.2. Связь ADABAS — «многие со многими» (удачная связь) МАШИНА содержит элемент ТИП-МАШИНЫ, определенный как поисковый ключ. Каждому значению ТИП-МАШИНЫ соответствует несколько экземпляров ЧЕЛОВЕК, имеющих одинаковые значения ТИП-МА- ШИНЫ- КОТОРЫМ-УПРАВЛ Я ЕТ. Рис. 23.3. Структура, необходимая КОДАСИЛ или TOTAL, для представления ADABAS Этот пример полезного отношения «многие ко многим» вполне ре- ален. Человек может работать с несколькими машинами, т. е. с маши- нами данного типа. Машина же может управляться несколькими людьми, т. е. тем, кто может управлять этим типом машин. В ADABAS предусмотрена возможность выполнения еще более сложных операций путем объединения средств внутренней структуры записи и средств связи между записями. Вернемся к приведенному выше примеру и допустим, что человек может управлять машинами нескольких типов. В результате ТИП-МА- ШИНЫ-КОТОРЫМ-УПРАВЛЯЕТ будет вектором, оставаясь при этом поисковым ключом. Если же предположить, что конкретной ма- шине присвоено несколько различных кодов, то значение ТИПЫ-МА- ШИН окажется в векторе внутри типа записи МАШИНА. 253
Для гжолноты представления на рис. 23.3 показано решение этой проблемы! с помощью систем TOTAL или КОДАСИЛ. Тем ice менее следует заметить, что семантика манипулирования данными не зависит от конкретного метода структурирования. / 23.4. ПРЕДСТАВЛЕНИЕ ТИПОВ ЗАПИСИ В ПАМЯТИ В AOABAS концепция способа размещения отсутствует, поэтому можно считать, что каждый тип записи имеет способ размещения SYSTEM- С этой точки зрения пользователь не осуществляет никакого контроля над представлением типа записи в памяти. Концепция области здесь также отсутствует, поэтому можно до- пустить, что все экземпляры одного типа записи хранятся в одной об- ласти. Это в свою очередь означает, что контроль над взаимным физи- ческим расположением записей различных типов не производится. Однако п ользователям часто требуется размещать записи-члены вбли- зи владельца. Последнее обеспечивается в ADABAS с помощью средств построения внутренних структур записи. Очевидно, что эти средства предопределяют иной подход к манипулированию отношениями, от- личный от используемого для отношений связи между записями. 23.5. ПРЕДСТАВЛЕНИЕ ТИПОВ НАБОРА В ПАМЯТИ В ADABAS метод представления отношений типов набора в памяти основан на использовании индексирования для поддержки неуникаль- ных поисковых ключей. При этом выдвигается требование дублировать элемент в связанном типе записи. Этот прием подтверждает аналогию между типом набора и поиско- вым ключом в терминах КОДАСИЛ. Кроме того, он свидетельствует о большей гибкости индексирования по сравнению с рандомизацией. Далее» в ADABAS существует некоторый аналог массива указа- телей КОДАСИЛ, а также концепция, близкая концепции ключа базы данных — так называемый внутренний номер памяти (ВНП). Разли- чие между этими двумя концепциями состоит в том, что для обеспече- ния уникальности в базе данных ВНП должен уточняться номером файла. Иначе он будет уникальным только в файле. 23.6. УПОРЯДОЧЕНИЕ НАБОРА В ADABAS нет концепции упорядочения набора. Поскольку систе- ма представляет типы набора в памяти с помощью индексов поисковых ключей, можно считать, что эквивалентом упорядочения набора в ADABAS является либо LAST, либо IMMATERIAL. 23.7. ПОИСКОВЫЕ КЛЮЧИ Как уже отмечалось, в основу подхода ADABAS положены поис- ковые ключи. Это понятие было введено еще при обсуждении построе- ния структур связи между записями. Заметим также, что поисковый ключ может быть не только простым элементом, но и вектором (как было 254
показано ранее) или элементом в повторяющейся группе. Вероятны также многокомпонентные поисковые ключи. Это означает, что поис- ковый ключ может включать до пяти компонент, в качестве которых используются элемент, часть элемента, групповой элемент, элемент в повторяющейся группе или вектор. Такие многокомпонентные поис- ковые ключи, называемые «супердескрипторами», находят примене- ние в программах специального поиска. 23.8. СПОСОБ В КЛЮЧЕНИЯ И ДОПУСТИМОСТЬ ИСКЛЮЧЕНИЯ Аналогично IMS и TOTAL, ADABAS не имеет эквивалентов ни для одной из этих концепций. Связанные с их отсутствием проблемы раз- решаются здесь так же, как и в TOTAL (см. параграф 21.8). 23.9. ВЫБОР НАБОРА Как и в TOTAL, в ADABAS отсутствует концепция выбора набора. Однако система TOTAL аналогична КОДАСИЛ в том отношении, что она работает исключительно в терминах связей «одна со многими». По- этому в последней приходится решать, какую запись-владельца сое- динять с записью-членом, когда эта запись-член помещается в базу данных. Этот вопрос даже не возникает в системе ADABAS, поскольку она полностью ориентирована на отношения «многие ко многим». Тот факт, что один тип записи имеет связь с каким-либо другим типом запи- си в базе данных, не имеет здесь никакого значения. Концепция от- ношения М к N одинаково допускает отношения «нуль к многим», многие к нулю», «один к нулю» и т. д. 23.10. ПОДСХЕМА Все замечания относительно подсхемы, которые были сделаны для TOTAL (см. параграф 21.10), полностью справедливы и для ADABAS. 23.11. КОНЦЕПЦИИ ЯМД Доступ к базе данных при использовании включающего языка (см. параграф 13.2) должен осуществляться с помощью оператора CALL. Его первый параметр (напомним, что всего их шесть) идентифи- цирует блок управления, один из элементов которого содержит код, указывающий выполняемую операцию. Другим элементом в блоке управления является так называемый код реагирования, эквивалент- ный регистру состояния базы данных КОДАСИЛ (см. параграф 13.5). В ADABAS нег какой-либо явной концепции индикаторов текуще- го состояния, г е. представляемых системой элементов данных, с по- мощью которых она может отслеживать запись (данного типа, в дан- ном типе набора или данной области), найденную процессом или за- писанную им последней. Здесь программист сам должен включать в блоки управления элементы, которые могут содержать значение клю- 255
ча базы данных (ВНП). Такие элементы играют роль индикаторов текущего состояния. Для отслеживания логически связанных команд можно использо- вать идентификатор команды, например в тех случаях, когда последо- вательность «относительных» FIND (см. параграф 15.3) прерывается одним или более «непосредственными» FIND. 23.12. ОПЕРАТОРЫ ЯМД Каждый тип оператора ЯМД определяется двухразрядным команд- ным кодом. Этот код является сокращенным немецким названием соот- ветствующей операции и поэтому может показаться несколько необыч- ным. В целях совместимости с ранними версиями ADABAS у нескольких командных кодов были сохранены две формы: одна — для программ, выполняющихся в условиях доступа к базе данных одной программы, а другая — для программ, которые выполняются в условиях одновре- менного доступа двух или более программ (фактически процессов). Мультипрограммная версия сейчас работает в равной степени хорошо и в однопрограммном режиме. Операторы ЯМД ADABAS можно представить следующим образом (рис. 23.4): РГЯБД ADABAS Уровень Имя Имя Код Область READY OPEN OP FINISH CLOSE CL Только FIND FIND несколько запись STORE ADD N1 ERASE DELETE E1/E4 Запись и GET READ несколько элемент MODIFY UPDATE A1/A4 Параллель- KEEP HOLD Hl ная работа FREE RELEASE R1 (El, Е4 и Al, А4 служат примерами двух видов одного и того же кода). Рис. 23.4, Операторы ЯМД ADABAS Эти операторы по аналогии с операторами ЯМД КОДАСИЛ можно разделить на три категории: 1. Операторы поиска. 2. Операторы обновления. 3. Другие операторы. В третью категорию входит наиболее важный оператор — READY, 28.12.1. Операторы поиска ЯМД — FIND Хотя в ADABAS существуют два оператора поиска — FIND и READ, — обязанности между ними делятся не так, как между FIND и GET в КОДАСИЛ. В ADABAS FIND работает с множеством запи- сей, поэтому результатом его выполнения будет список значений клю- 256
чей базы данных в буфере управления. Оператор же READ воздейст- вует только на одну запись и предоставляет ее программе. Оператор FIND имеет три формата; FIND NORMAL S1/S4 FIND AND SOR I S2 FIND COUPLED S5 Первые два из них можно рассматривать совместно. Единственное различие между ними состоит в том, что во втором операторе список значений ключей базы данных отсортирован в соответствии с каким- либо указанным критерием сортировки Вариант FIND NORMAL является основным вариантом оператора FIND в любой поограмме ADABAS. Программист должен поместить условное выражение в область блока управления, которая называется буфером пои ка Оно состоит из ряда условий, основанных на клю-ах поиска в искомом типе запи- си. Кроме того, эти условия могут распространяться и на ключи поиска в связанных типах записи (связанным называется тип записи, который непосредственно связан с искомым типом записи). Условия на значе- ния поисковых ключей могут быть соединены дизъюнктивно Как отмечалось выию, условному выражению могут удовлегворять несколько записей. Для его вычисления система пользуется индексами поисковых ключей, в связи с чем записи для этой цели из баз данных не выбираются. Из записей, значения ключей базы данных которых включены в список, выбирается первая и записывается в область бло- ка управления, называемую буфером записи (аналогичную области записи КОДАСИЛ, но специфицируемую явно) Способ занесения записи в эту область записи определяется еще одной частью блока управления — буфером фор мата. Последний позволяет программисту указывать, какие части записи требуются и какой формат они должны иметь. Счетчик числа записей, удовлетворяющих заданному условию, также хранится в блоке управления Вариант FIND COUPLED представляет собой сокращенное обо- значение одного из средств, которое можно было бы выразить и с по- мощью FIND NORMAL. В терминах КОДАСИЛ это способ поиска экземпляра набора. Экземпляр набора отыскивается с помощью зна- чения ключа базы данных записи-вледельца. Этим он отличается от FIND NORMAL, при котором требуется выразить условие по элемен- ту поискового ключа, используемого и в том, и в другом типах записи. Кроме того, FIND COUPLED не представляет вызывающей програм- ме никакой записи. Важно отметить, что оба эти варианта FIND выполняются только з том случае, если отношение между двумя типами записей определе- ю явно (см разд. 23.3.2) Последнее имеет место для FIND NORMAL, юли нужно сформулировать условие как на искомом типе записи, так 1 на связанном. Очевидно, что ни один из рассмотренных форматов не соответст- вую! существующему в КОДАСИЛ, Зак 145 257
3.12.2. Операторы поиска ЯМД — READ В ADABAS оператор READ имеет пять форматов: FIELD DEFINITIONS LF ISN L1/L4 PHYSICAL SEQUENCE L2/L5 LOGICAL SEQUENCE L3/L6 VALUES L9 READ READ READ READ READ Вариант READ FIELD DEFINITIONS не имеет эквивалента в КОДАСИЛ. Он обеспечивает чтение объектной схемы во время вы- полнения программы. Поскольку FIND NORMAL обладает некоторым свойством, позволяющим программисту определять формат записи при ее размещении в области записи программы, во время выполнения по- следней часто оказывается весьма полезным читать объектную схему. Вариант READ ISN аналогичен оператору GET в КОДАСИЛ. Он обычно выполняется вместе с FIND NORMAL и предоставляет всю запись обращающейся программе. Как и GET, его можно использо- вать для предоставления программе какой-либо части записи. Вариант READ PHYSICAL SEQUENCE аналогичен следующему формату КОДАСИЛ: (FIRST) FIND •! J имя записи IN имя-области ---- (NEXT — (см. разд. 15.4.3). Вариант FIND FIRST выполняется посредством ус- тановки на нуль того параметра в блоке управления, который содер- жит значения ключей базы данных. При однократном выполнении опе- ратора в этом параметре устанавливается значение ключа базы данных найденной записи. FIND NEXT выполняется в том случае, если в па- раметре уже содержится такое значение. Вариант READ LOGICAL SEQUENCE не имеет полного эквива- лента в КОДАСИЛ в основном из-за его тенденции использовать ме- тоды рандомизации (см. разд. 4.4.1 и параграф 15.4). Один из поиско- вых ключей, определенных для типа записи, должен специфициро- ваться в блоке управления. Можно указывать начальное значение этого поискового ключа в другой части блока управления или начи- нать с его самого первого значения. Наиболее близкий к этому варианту в КОДАСИЛ является сле- дующий вариант FIND: (ANY ] FIND <nTTD тгатр! имя-записи USING имя-элемента-I.... I U U г Ц 1 £1 j (см. разд. 15.4.1 и 15.5.2). В спецификациях КОДАСИЛ данное сред- ство ADABAS имело бы формат: (FIRST ANY NEXT FIND имя-записи USING имя-элемента-1 Здесь имя-элемента-1 является поисковым или CALC-ключом. 258
Наконец, вариант READ VALUES также не имеет эквивалента в предложениях КОДАСИЛ. Это средство более типично для автоном- ных СУБД. Оно должно применяться при генерировании списка всех значений, которые может принимать данный поисковый ключ для дан- ного типа записи, и счетчика числа вхождений каждого из них в ка- кую-либо запись файла. Генерированный список не должен обязатель- но начинаться с самого низкого значения поискового ключа — оно может специфицироваться. Список при этом будет начинаться именно с него или со следующего более высокого значения. При однократном выполнении оператора генерируется одно значение и счетчик числа его вхождений. Если оператор встроен в цикл, можно выдавать последо- вательные значения. 23.12.3. Обновляющие операторы ЯМД Операторами обновления в ADABAS являются обычные STORE, MODIFY и ERASE. Из-за иного характера представляемых отноше- ний семантика STORE и ERASE несколько отличается от семантики этих операторов в других СУБД. При первичном помещении записи в базу данных системе не нужно проверять, к какому владельцу она присоединяется. Запись помещается в соответствующий файл, как правило, с новым ВНП (главной частью значения ключа базы данных), а соответствующие индексы поисковых ключей обновляются. Отношения с другими типами записи участвуют только в том случае, когда определено явное отношение с другим ти- пом записи (связь). Аналоги чная ситуация имеет место и при удалении записи. Послед- нюю можно удалить из базы данных, независимо от того, является ли она владельцем непустого набора или нет. Это означает, что если концептуально между двумя типами записи существует отношение «один ко многим», то обновляющая базу данных программа должна сама осуществлять то, что в других системах обеспечивается автомати- чески. Оператор MODIFY весьма похож на соответствующий оператор КОДАСИЛ. Однако существуют специальные правила, которые про- граммист должен помнить, модифицируя данные в агрегатах данных. Как и в системах КОДАСИЛ, прежде чем модифицировать запись, ее необходимо найти. Но здесь, в отличие от КОДАСИЛ, не возникает вопрос о ее переносе из одного экземпляра набора в другой в резуль- тате модификации. 23.12.4. Другие операторы ЯМД Оператор READY в ADABAS называется OPEN. Применяя его, программист должен явно указать цель открытия файла — для обнов- ления или для выборки. Оператор READY играет в ADABAS важную роль, так как он яв- ляется частью средства обеспечения контроля доступа в системе. Блок управления, используемый оператором OPEN, может содержать вось- 9* 259
мибайтовый пароль. Обязанность программиста — проверить его ус- тановку, прежде чем будет открыта какая-либо часть базы данных. Программист может установить его сам или ввести с терминала. В этом случае пароль служит ключом контроля доступа. С каждым таким ключом «ассоциируется область применимости или предоставления полномочий для обработки части базы данных определенным образом. Оператор HOLD ADABAS обычно используется неявно в операто- рах FINO и READY. При наличии двухлитерных кодов больший код подразумевает, что HOLD также выполняется. Можно, однако, при- менять этот оператор и самостоятельно. Оператор RELEASE анало- гичен оператору FREE КОДАСИЛ (см. разд. 17.2.2). 23.13. ЗАКЛЮЧЕНИЕ Подход ADABAS к управлению базами данных представляет зна- чительный интерес, поскольку во многом он отличается от подхода КОДАСИЛ, хотя можно с уверенностью заявить, что ADABAS обес- печивает возможность полной сетевой структуры за счет неявных от- ношений, а не за счет явных. Как уже отмечалось, пользователь, ви- димо, предпочитает неявные отношения для приложений включающего языка. Заметим, что пользователь имеющихся автономных средств должен применять средство связи. Использование отношений «многие ко многим» вместо отношения «один к многим» не всегда является достоинством, но заслуживает вни- мания, так как показывает, как можно реализовать эти отношения. Данный метод мог бы быть более эффективным, если бы он поддержи- вал оба типа отношений. Несмотря на то что мы в настоящей главе не касались этого аспекта, очевидно, отношение «многие ко многим» име- ет больший смысл при наличии специально рассчитанных на него за- просов. Проектировщику базы данных ADABAS не приходится принимать много решений. Он может воспользоваться внутренней структурой записи для представления нескольких отношений «один ко многим» и должен предусмотреть необходимые поисковые ключи, хотя новые ключи, если они потребуются, разрешается добавлять позднее. Глав- ное преимущество рассмотренной системы состоит в том, что она осно- вывается на методах индексирования, а не рандомизации. Тем не ме- нее еще раз подчеркнем: хорошая система должна обеспечивать раз- личные средства для всех типов записи в базе данных. ГЛАВА 24 РЕЛЯЦИОННЫЙ ПОДХОД 24.1. ОБЩИЕ СВЕДЕНИЯ Системы, описанные в трех предыдущих главах, экономически вы- годны и широко применяются во всем мире. Здесь мы рассмотрим под- ход к управлению базами данных, который вызывает интерес в ака- 260
демической среде, а также в исследовательских правительственных и торговых организациях. Реляционный подход освещался во многих статьях, но развит он был в ряде статей Кодда [1, 2] в 1971 г. Полное представление об этом подходе дает книга Дейта [3]. Следует подчеркнуть, что реляционный подход является, по суще- ству, теорией, на которой базируется ряд экспериментальных систем. Не останавливаясь на подобных системах, мы опишем в данной главе элементы этой теории с тем, чтобы иметь возможность сравнить ее с подходом КОДАСИЛ. В реляционном подходе нет «компонентов», как в других рассмот- ренных методах. Здесь отсутствует язык определения данных как та- ковой, его заменяет способ их представления. Язык манипулирования данными, однако, имеется. Кодд называет его подъязыком данных. Этот термин представляется более удачным, чем язык манипулирования данными. Он гораздо эффективнее передает скрытый смысл расши- рения существующего языка программирования. Подъязык данных Кодда известен как ALPHA [2]. 24.2 РЕЛЯЦИОННАЯ ТЕРМИНОЛОГИЯ Прежде всего мы должны сопоставить терминологию, используе- мую в реляционном подходе, с терминологией, представленной в пред- ложениях КОДАСИЛ. Сам факт, что даже таблица терминологических эквивалентов может быть спор- ной, показывает, как обстоит дело со сравнительным анали- зом этих двух методов. Эквива- лентные термины, которые встре- чаются в настоящей главе, при- ведены на рис. 24.1. 24.2.1. Атрибут, домен и элемент данных Реляционный подход Атрибут Значение Домен Отношен не Кортеж Таблица Зависимость меж- ду отношениями Степень отношения Предложения КОДАСИЛ Элемент данных Значение Тип записи Запись (экземпляр) Файл Тил набора Число элементов в типе записи Происхождение термина «до- мен» связано с классической теорией множеств. Действитель- но, в математическом множест- ве может существовать какое-то конкретной ситуации может образовать домен. Полезно также пред- ставлять домен как множество значений, например М и Ф в домене ПОЛ. Смысл, заложенный в определенное заранее множество зна- чений, не совпадает со смыслом термина элемент данных (и тем бо- лее термина «простой элемент данных»), который широко применяет- ся в обработке экономических данных. Завершая обсуждение этого вопроса, приведем выдержку из ста- тьи Кодда 14] о доменах и полях (т. е. элементах): «Именно концепция атрибута, а не домена, наиболее полно соответствует полю. Концепция 261 Рис. 24.1. Терминологические эквивален- ты число элементов, часть которых в
домена отсутствует в традиционных системах обработки данных, вклю- чая СУБД в системах КОДАСИЛ. При определении реляционной базы данных одним из первых ша- гов являемся идентификация соответствующих доменов, т. е. семанти- чески различных множеств неразложимых значений данных, из ко- торых можно динамически создавать кортежи ... Если атрибуты А, В ... берут свои значения из общего домена, то семантически допус- тимо сравнивать значения А, В на равенство...». В качестве примера можно привести домен ФАМИЛИЯ-ЧЕЛОВЕКА и два атрибута ФАМИЛИЯ-ЗАКАЗЧИКА и ФАМИЛИЯ-СЛУЖАЩЕ- ГО. Возможно, что эти два атрибута не имеют ничего общего, но если это не так, то можно проверить, является ли данный клиент также и служащим. Столь точная трактовка не свойственна термину элемент данных, и концепция домена, как отличная от атрибута, должна получить рас- пространение. Решение этой проблемы заключается не в изменении са- мого термина элемент данных, а скорее в признании необходимости определять домен значений для элемента до спецификации типов запи- сей, к которым этот элемент принадлежит. 24.2.2. Отношения и типы записей Одна из основных проблем в терминологии обычной обработки дан- ных связана с неточным употреблением терминов тип записи и запись. Девять человек из десяти применяют термин запись, имея в виду тип записи. В обработке данных это не имеет большого значения, но в ус- ловиях ориентации на базы данных может возникнуть неоднознач- ность. Если отвлечься от обычной терминологии обработки данных, то отношение и тип записи можно считать эквивалентными. 24.2.3. Кортежи и записи Под термином запись в раннем Фортране подразумевалось значе- ние сплошной строки записанных данных, т. е. он имел полностью физический смысл. В Коболе ему придается более логическое значе- ние (см. параграф 3.2), и считается возможным приравнять запись к кортежу. Следует отметить, что кортеж представляет собой сокраще- ние от термина «кортеж отношения степени п» (n-tuple), 24.2.4. Таблицы и файлы Набор кортежей данного отношения называется таблицей. Слово файл в Коболе имеет более широкое значение, так как оно включает концепцию файлов с несколькими типами записей, а также подразу- мевает содержимое вспомогательной памяти, хотя в словаре «Журна- ла развития Кобола» файл определяется просто как совокупность записей. В спецификациях базы данных КОДАСИЛ (оправдано это или не оправдано) избегают употреблять слово «файл». Возможно, если бы 262
спецификации строились на основе терминологии файла, а не экзем- пляра набора, некоторые концепции проще воспринимались бы теми, кто имеет опыт работы с обычными методами. Под термином таблица, означающим тип внутренней структуры записи в Коболе, в реляционной теории понимают совокупность кор- тежей данного отношения. Существуют правила, которым должны удовлетворять эти кортежи, но этот вопрос уже представляет собой ас- пект теории. 24.2.5. Тип набора и зависимость между отношениями Обсуждение данного вопроса нам придется отложить до тех пор, пока не будут рассмотрены определенные теоретические аспекты, по- скольку сравнение реляционной теории и предложений КОДАСИЛ здесь представляется слишком сложным. 24.2.6. Степень отношения ! Степенью отношения называется число доменов или атрибутов в отношении. В литературе встречаются оба термина — и домен, и атри- бут. Однако практика повседневной обработки данных требует их разграничения. Степень отношения должна определяться как чис- ло атрибутов, независимо от того, что один или более из них (даже в одном и том же отношении) могут брать свои значения из одного и того же домена. 24.3. КРАТКОЕ ИЗЛОЖЕНИЕ РЕЛЯЦИОННОЙ ТЕОРИИ Хотя реляционная теория базируется на математической теории множеств, в литературе она еще не представлена достаточно полно и связно. Поэтому мы попытаемся изложить ее основные положения с помощью реляционной терминологии и (для сравнения) терминоло- гии повседневной обработки данных. Следует подчеркнуть, что все положения относятся именно к реляционной теории. Сравнение с под- ходом КОДАСИЛ здесь не проводится. Каждое положение мы будем классифицировать как лемму. Лем- ма есть допускаемое или доказываемое утверждение, используемое в качестве аргумента или доказательства. Поскольку доказывать нам ничего не нужно, данное представление служит только для пояснения. Для ясности леммы представлены в форме, облегчающей их сравнение. Все специальные термины выделены курсивом. Реляционная терминология Терминология обработки данных ОПРЕДЕЛЕНИЯ 1. Атрибут есть неразложи- Простой элемент данных (на- мый элемент именованных дан- зываемый также элементом) ных есть неразложимый элемент именованных данных 263
2. Домен есть совокупность значений, которые можно ассо- циировать с одним или более атрибутов 3. Отношение состоит из ря- да атрибутов 4. Степень отношения есть число атрибутов в отношении 5. Определение совокупности отношений составляет опреде- ление базы данных 6. Кортеж есть множество значений всех атрибутов в от- ношении 7. Совокупность всех корте- жей для отношения называется таблицей ОСНОВНЫЕ 1. Порядок кортежей в таб- лице не существен 2. Упорядочение значений ат- рибутов в кортеже должно со- ответствовать упорядочению атрибутов в отношении 3. Каждое отношение должно содержать один или более ат- рибутов, которые вместе со- ставляют уникальный первич- ный ключ 4. Если между какими-либо двумя отношениями существу- ет зависимость, то одно отно- шение является исходным, а другое — подчиненным 5. Чтобы между двумя отно- шениями существовала зависи- мость, атрибут или атрибуты, которые служат первичным ключом в исходном отношении, должны также присутствовать в подчиненном отношении 6. Если отношение является подчиненным в одной зависи- мости и исходным в другой, то первичный ключ исходного от- ношения первой зависимости должен передаваться через под- чиненное отношение второй за- висимости 'Домен есть совокупность зна- чений, которые можно ассоции- ровать с одним или более эле- ментом Тип записи состоит из ряда эле* ментов Степень типа записи есть чи- сло элементов в типе записи Определение совокупности ти- пов записи составляет схему базы данных Запись есть множество значе- ний всех элементов в типе за- писи Совокупность всех записей ти- па записи называется файлом ПОЛОЖЕНИЯ Порядок записей в файле не существен Упорядочение значений элемен- тов в записи должно соответ- ствовать упорядочению элемен- тов в типе записи Каждый тип записи должен со- держать один или более эле- ментов, которые вместе состав- ляют уникальный первичный ключ Если между двумя типами за- писи существует отношение ти- па набора, то один тип записи является владельцем, а дру- гой — членом Чтобы между двумя типами записей существовало отноше- ние типа набора, элемент или элементы, которые служат пер- вичным ключом в записи-вла- дельце, должны также присут- ствовать в записи-члене Если тип записи является чле- ном в одном типе набора и вла- дельцем в другом, то первич- ный ключ владельца первого типа набора должен переда- ваться через своего члена к члену второго типа набора 264
24.4.ОГРАН ИМЕНИЯ РЕЛЯЦИОННОЙ ТЕОРИИ В ТЕРМИНАХ КОДАСИЛ Тщательное изучение изложенных выше положений показывает, что реляционная теория предполагает довольно жесткий набор огра- ничений в реляционной базе данных. Просуммируем эти ограничения в терминах КОДАСИЛ: 1. Каждый тип записи содержит только простые элементы данных. 2. Каждый тип записи должен иметь уникальный первичный ключ. 3. Для обеспечения возможности определения типа набора первич- ный ключ записи-владельца должен также присутствовать в записи- члене. Далее, полезно перечислить несколько концепций ЯОД схемы КОДАСИЛ, которые явно запрещены в реляционной базе данных: 1. Повторяющиеся группы. 2. Управление физической близостью размещения записей одного или различных типов. 3. Предопределенный порядок в наборе. 4. Определение поисковых ключей. 5. Многочленные типы набора. 6. Способ включения и допустимость исключения. 7. Алгоритм выбора набора. Обращаясь к IMS и TOTAL, важно отметить, что реляционная тео- рия не вводит ни одного из основных ограничений, имеющихся в этих двух системах. Так, в ней отсутствует утверждение о том, что тип за- писи не может быть связан более чем с двумя типами записей-владель- цев, в то время как в IMS это составляет главную проблему (см. разд. 22.3.2). Здесь также ничего не сказано о том, что тип записи не может быть одновременно владельцем в одном типе набора и членом в другом. В TOTAL же от этого зависят средства структурирования (см. разд. 21.3.1) 24.5. РЕЛЯЦИОННЫЕ СЕТИ И СЕТИ КОДАСИЛ Сравнительный анализ реляционного метода и подхода КОДАСИЛ приведен в [51. Интересно, что подход КОДАСИЛ в литературе неиз- менно называется «сетевым». Объяснение этому дается в одной из ран- них статей Кодда 161: «Утверждают, что в некоторых приложениях за- дачи формулируются непосредственно в терминах сетей. Это справед-? ливо для таких приложений, как изучение транспортных сетей и се- тей энергетических линий, проектирование с применением ЭВМ и т. п. Мы будем называть их сетевыми приложениями ...Многочисленные базы данных, которые отражают повседневную работу и деловые опе- рации торговых и промышленных предприятий, по большей части свя- заны с несетевыми приложениями. Навязывать сетевую структуру по- добным базам данных и заставлять всех пользователей рассматривать данные в сетевых терминах — значит создавать для большинства поль- зователей ненужные трудности». При чтении этой выдержки складывается впечатление, что в сетях есть что-то принципиально нежелательное. Однако именно Дейт, . 265
сравнивая подход КОДАСИЛ в «реляционной моделью», назвал этот метод «сетевым» [3]. Возможно, многие, прочитав статьи Кодда и Дейта, придут к вы- воду не только о том, что сети являются нежелательными, но и о том, что реляционный метод не поддерживает их. Это, конечно, противоре- чит истине. К сожалению, те простые примеры, которые приведены для ил- люстрации принципов реляционной теории, основываются на двух- трех типа х записи, подобных описанным с помощью схем Бахмана на рис. 24.2. Рис. 24.2. Простые базы данных Статьи , посвященные реляционной теории, по той или иной причи- не не используют схемы Бахмана (или какие-либо другие графические формальные приемы) для описания структуры базы данных. Анализ обширного материала по реляционной теории позволяет сделать следующий вывод. Логическая структура данных, которая мо- жет быть представлена в реляционной базе данных, может иметь та- кую же степень сложности, какая разрешается в предложениях КО- ДАСИЛ для системы управления базами данных. Единственным ис- ключением является возможность представления циклических струк- тур в КОДАСИЛ. Этот вывод не распространяется на системы IMS и TOTAL. 24.6. ИСПОЛЬЗОВАНИЕ КЛЮЧЕЙ Реляционная теория требует, чтобы каждый тип записи в базе данных имел уникальный первичный ключ. В предложениях КОДА- СИЛ такая возможность просто допускается. Достигается это опре- делением для типа записи способа размещения CALC (см. разд. 4.4.1) с объявлением варианта ‘DUPLICATES NOT ALLOWED’. Напомним, что в последнее время КОДАСИЛ стремится устранить оттенок рандо- мизации, сопутствующий употреблению термина calc, Следуе'г отметить, что в базах данных TOTAL или IMS невозмож- но определить первичный ключ в каждом типе записи. Фактически этого можно добиться в обеих системах, лишь отказавшись от исполь- зования отношений типа набора. Однако редкий пользователь сочтет такое решение приемлемым. Подход КОДАСИЛ позволяет определять поисковые или вторич* ные ключи, В реляционной теории они явно не обеспечиваются. 266
24.7. ТИПЫ НАБОРА И СВОЙСТВА НАСЛЕДОВАНИЯ Концепция типа набора в реляционной теории явно не опреде- ляется. Термин зависимость между отношениями здесь используется, но Дейт употребляет термин зависимость внутри отношения > а также термин совместимость отношений [3]. 24.7.1. Определение связй . ' _ В трех экономически жизнеспособных системах — КОДАСИЛ, IMS и TOTAL — связь между записями определяется следующим об- разом. Специфицируются два типа записей — А и В, а затем в другом месте синтаксического описания устанавливается связь между ними. В КОДАСИЛ и TOTAL между А и В может существовать одна или бо- лее связей и поэтому их необходимо именовать. В IMS между А и В может быть не более одной связи и именовать ее не разрешается. В реляционной теории типы записи определяются, но любая связь между ними неявно выражается в атрибутах каждого типа записи. На- пример, в простейшем случае с отделами и служащими могут исполь- зоваться следующие типы записи: ОТДЕЛ №-ОТДЕЛА НАЗВАНИЕ-ОТДЕЛА РУКОВОДИТЕЛЬ МЕСТОНАХОЖДЕНИЕ СЛУЖАЩИЙ №-СЛУЖАЩЕГО Ф АМИЛИ Я-СЛУЖАЩЕГО ЖОТДЕЛА ЗАРПЛАТА Повторение элемента данных № ОТДЕЛА в обоих типах записи, а также использование №-ОТДЕЛА в качестве первичного ключа типа записи дает эффект определения связи типа набора между этими дву- мя типами записи. Другими словами, определение связи типа набора в реляционной базе данных неявно присутствует в элементах, специ- фицированных в типах записи. Важно отметить, что TOTAL пользуется точно таким же методом для определения связей типа набора с помощью элементов управле- ния (см. параграф 22.9), тогда как IMS не допускает этого даже в ка- честве одного из вариантов. Стоит также заметить, что ранние спецификации КОДАСИЛ не обеспечивали такого приема, и, следовательно, в доступных реализа- циях он не поддерживается. Однако самые последние спецификации КОДАСИЛ включают его в качестве возможного варианта (см. разд. 8.9). 24.7.2. Упорядочение набора Одним из наиболее спорных свойств типа набора является упоря- дочение последнего. В реляционной теории такой концепции нет. Дей- ствительно, в своей первой статье [1] Кодд утверждает: «Те приклад- 267
ные программы, которые пользуются преимуществом упорядочения файла, скорее всего, перестанут правильно работать, если по какой- либо причине потребуется изменить этот порядок на другой». Здесь, конечно, трудно что-либо возразить. Однако зло заключает- ся не в определении порядка, а в его применении. Оперируя аргу- ментом «доведение до абсурда», можно заявить, что прикладная про- грамма не должна пользоваться каким-либо компонентом определе- ния данных, так как теоретически он может измениться Куда это мо- жет нас завести? Тем не менее реляционная теория, прямо или косвенно, оказала влияние на предложения КОДАСИЛ по упорядочению набора. Кон- струкцию определения его порядка решили не исключать, но доба- вили вариант, позволяющий администратору данных объявить поря- док в наборе несущественным (см. параграф 6.5) Этот вариант дал возможность ввести в системы КОДАСИЛ средства, предложенные в реляционной теории. 24.7.3. Способ включения Наконец, следует рассмотреть концепцию способа включения в подходе КОДАСИЛ Реляционная теория не признает такой концеп- ции, т. е. считаетсящто способ включения здесь всегда автоматический. Реляционная система фактически ведет себя так же, как TOTAL. При запоминании записи-члена значение элемента набора для любого ти- па набора, в котором она участвует, должно соответствовать злому значению в одной из записей-владельцев в базе данных, 24.7.4. Вид представления набора Обсудим в заключение вид представления набора. Ссылки на цепи и массивы указателей в ранних работах КОДАСИЛ были критически восприняты читателями, поскольку КОДАСИЛ без необходимости занимался вопросами представления данных. Комитет по языку опи- сания данных, рассмотрев критические замечания, исключил из ЯОД схемы конструкцию с определением вида набора (см. параграф 5.3). Действительно, концепция цепи занимала важное место в раннем пред- ставлении предложений КОДАСИЛ. Сейчас признана основной воз- можность определения отношения 1 : М между типами записи, а не методы представления этих отношений в памяти прямого доступа. Реляционная теория еще более отступает от явного определения связи, предпочитая ему неявное с помощью элементов данных в ти- па,х записи. Последователи реляционного метода допускали, что неко- торый вид представления набора должен неявно обеспечиваться. Как и упорядочение набора, он не должен определяться явно, чтобы программист не мог воспользоваться его преимуществом. 268
24.8. ПРАКТИЧЕСКИЕ АСПЕКТЫ РЕЛЯЦИОННОЙ ТЕОРИИ Наибольшее значение для пользователя имеют следующие три аспекта реляционной теории: 1. Уникальный первичный ключ для каждого типа записи. 2. Средства представления связей типа набора. 3. Распространение первичных ключей по структуре. Прежде чем обсуждать эти аспекты, необходимо проанализировать их логическое обоснование. Оно заключается в обеспечении независи- мости данных и в проектировании языка манипулирования данными. Здесь, естественно, возникает вопрос: оправдывает ли достижение независимости данных эти жесткие правила? 24 .8.1. Уникальный первичный ключ Реляционная теория выдвигает требование, согласно которому каждый тип записи должен иметь уникальный первичный ключ. Как правило, это требование вполне оправдано и не вызывает возражений. Однако в некоторых случаях оно представ- ляется необязательным. Рассмотрим пример, приведенный на рис. 24.3. Служащие обычно имеют служебные но- мера, и первичный ключ в типе записи СЛУ- ЖАЩИЙ является приемлемым. Но в типе записи ОБРАЗОВАНИЕ применение уни- кального первичного ключа нам кажется из- лишним. Маловероятно, что в такой неболь- шой базе данных может когда-нибудь потре- боваться доступ к записи ОБРАЗОВАНИЕ, независимо от записи СЛУЖАЩИЙ, которой СЛУЖАЩИЙ ОБРАЗОВАНИЕ Рис. 24.3. К вопросу определения уникального первичного ключа она принадлежит. Требование определения уникального первичного ключа является почти всегда обоснованным. Конечно, важно иметь возможность спе- цифицировать такой ключ для любого типа записи в базе данных (что невозможно в TOTAL и IMS), но быть вынужденным делать это нет ни- ка кой необходимости. 24 .8.2. Представление связей типа набора Реляционный способ представления связей типа набора прост и эффективен. Он осуществляется путем дублирования некоторого эле- мента (и, следовательно, его значений) в двух типах записи. Этот ме- тод легко усваивается и удобен в использовании. Его достоинства бы- ли продемонстрированы системами TOTAL и ADABAS. Что же касается подхода КОДАСИЛ к этой проблеме, то из мно- жества предложенных им вариантов выбора набора лишь один соот- ветствует методу, поддерживаемому реляционной теорией. Реляционный метод в этом отношении предпочтителен почти в лю- бом случае. Возможно, что отсутствие такого средства в системе IMS является ее существенным недостатком. 269
24 .8.3. Распространение первичных ключей Этот прием (рис. 24.4) показан на примере, приведенном из первой статьи Кодда [1]. В последующих работах, посвященных реляционной теории, тзсе примеры двухуровневые. Рис. 24.4. Трехуровневая структура Если бы представленные на рисунке четыре типа записи были оп- ределены в соответствии с реляционной теорией, они имели бы сле- дующий вид: СЛУЖАЩИЙ (№-СЛУЖ; ФАМИЛИЯ, ДАТА-РОЖДЕНИЯ) ИСТОРИЯ-РАБОТЫ (№-СЛУЖ, ДАТА-РАБОТЫ, НАЗВАНИЕ) ИСТОРИЯ-ЗАРПЛАТЫ (ЖСЛУЖ, ДАТА-РАБОТЫ ДАТА-ЗАРПЛАТЫ, ЗАРПЛАТА) РЕБЕНОК (№-СЛУЖ, ИМЯ-РЕБЕНКА ДАТА-РОЖДЕНИЯ) Такой способ спецификации имен записей и элементов, принадле- жащих каждой из них, широко применяется в работах по реляцион- ной теории. Подчеркивая имя элемента, мы тем самым указываем, что данный элемент служит первичным ключом в типе записи или частью первичного ключа. Вид представления этих типов записи в совокупно- сти в реляционной теории называется третьей нормальной формой. В настоящей главе этот термин встречается впервые, хотя его значение использовалось во многих местах. Рассмотренный вид представления типичен для реляционной теории. По существу, ограничения на элементь! 3 типах записи в структуре базы данных вводятся с целью обеспечения возможности манипулиро- вания этой структурой, что уменьшает зависимость прикладных про- грамм от ее изменений. Отношения между типами записи подразуме- ваются в элементах данных этих типов записи. Одобряя практику распространения первичных ключей на один уровень вниз, мы считаем, что в распространении их на два или более уровня нет необходимости. Трудно поддержать требование, чтобы эле- мент №-СЛУЖ включался в тип записи ИСТОРИЯ-ЗАРПЛАТЫ про- сто ради удовлетворения семантических потребностей специфического языка манипулирования. 270
24.9. ПОДЪЯЗЫКИ ДАННЫХ (ЯМД) ДЛЯ РЕЛЯЦИОННОЙ БАЗЫ ДАННЫХ Для реляционных баз данных не существует единого ЯМД. Имеет- ся несколько подходов, основанных на реляционной алгебре и реля- ционном исчислении [3]. Различие между ними Дейт сформулировал следующим образом: «Существуют, по крайней мере, два способа, которыми мы могли бы позволить пользователю это сделать: 1) он может определить после- довательность операций реляционной алгебры, которые необходимо выполнить для получения желаемого результата; 2) он может просто дать определение желаемого результата в терминах реляционного ис* числения, оставляя за системой определение требуемых операций. Раз- личие между двумя указанными подходами такое же, как и между: 1) фактическим построением множества путем выполнения над ним последовательности операций (объединением, пересечением и т. д.) и 2) простым указанием «определяющего свойства» множества в виде предиката, т. е. как между процедурным путехМ и непроцедурным». 24,9.1. Реляционная алгебра Операция реляционной алгебры выполняется над одним или более типами записи и в результате появляется еще один тип записи. Раз- личают две основные операции — проекцию (projection) и объединение (join). Проекция воздействует только на один тип записи и выдает один тип записи с меньшим числом элементов. Точнее, операция воздействует не на тип записи, а на все записи названного типа. Результатом выпол- нения проекции является генерирование совокупности записей нового типа. Считается, что они хранятся в гак называемом рабочем прост- ранстве. Рабочее пространство отличается от рабочей области пользователя КОДАСИЛ прежде всего тем, что оно, по существу, не ограничено. Кроме того, здесь отсутствует требование, согласно которому оно долж- но вмещать только одну запись каждого типа. В Коболе записи, которые генерируются во время выполнения про- граммы, обычно соответствуют типу записи, определенному в секции рабочей памяти Прикладной программист должен объявлять объем памяти, необходимый для хранения файла, полученного в результате выполнения операции проекции. Если два типа записи имеют общий элемент и значения этого эле- мента в обоих случаях выбираются из одного и того же домена, то мож- но выполнить операцию объединения по общему элементу. В резуль- тате генерируется совокупность записей нового типа, который содер- жит все элементы из двух указанных типов записей, но лишь один общий элемент. Если некоторое значение общего элемента содержится в совокупности записей одного типа и ни в одной записи другого типа, то запись с этим значением не принимает участия в объединении. 271
Фактически объединение не является какой-либо новой операци- ей. Тем, кто имеет опыт обработки ленточных файлов, оно известно как операция слияния Тем не менее проекция и объединение вместе обес- печивают непроцедурный способ манипулирования файлами. Можно возразить, что это обязательно приведет к увеличению объе- ма памяти по сравнению с тем, который требуется в соответствии с ме- тодом «одна запись в одну операцию», присущим сегодняшним систе- мам. Однако сторонники реляционного метода указывают на сокра- щение числа операторов, необходимых для спецификации любого кон- кретного запроса. 24.9,2. Реляционное исчисление Как уже отмечалось, реляционное исчисление отличается от реляционной алгебры. Известным примером этого поджгда служит подъязык данных ALPHA [2]. Точно так же, как оператор FIND (см. гл. 15) является основным операторе : ЯМД КОДАСИЛ, оператор GET является главным оператором в ALPHA Общий формат оператора GET можно представить следующим об- разом' GET расочее-пространство списог:-объ°ктов WHERE условие Параметр «рабочее пространство» относится к пространству памя- ти, в котором размещается совокупность записей, генерируемая в ре- зультате выполнения этого оператора Важным аспектом языка ALPHA является то, что программисту не нужно знать, находится ли данное рабочее пространство в памяти прямого доступа или нет Спи- сок объектов состоит обычно из списка имен элементов (возможно, уточненных именами записей) и отдельных имен записей. Наконец, условие может быть полным логическим выражением, подобно слож- ным у* ловным выражениям в Коболе Кроме GET, имеется ряд других операторов, таких, как PUT (т е. STORE), UPDATE (MODIFY) и DELETE. 24 10. ЗАКЛЮЧЕНИЕ На основании анализа реляционного метода можно сделать следую- щие выводы 1. Реляционному методу соответствует процесс определения дан- ных, который содержит ряд ограничений. 2 Два из ограничений — уникальный первичный ключ и способ определения типов набора — вполне приемлемы Распространение же первичных ключей сверху вниз по глубокой структуре вызывает сом- нение. 3. Реляционный метод позволяет определять столь же сложные сетевые структуры, как и подход КОДАСИЛ (за исключением цикли- ческих структур). 4. Подход КОДАСИЛ гораздо более соответствует реляционной теории, чем I?4S и TOTAL. 272
5. Требование распространения первичных ключей по структуре необходимо для поддержки семантики подъязыков данных, предло- женных для реляционных баз данных 6. «Одношаговый» по отношению к записям ЯМД КОДАСИЛ мог бы манипулировать реляционной базой данных Наконец, следует отметить, что большая часть дискуссий на гему «реляционная против сетевой» имела целью отвлечь внимание от не- достатков таких систем, как LMS В действительности реляционный метод и метод КОДАСИЛ имеют довольно много общего. Решения, принятые КЯОД за период с 1972 по 1976 г., свидетельствуют о том, что реляционная теория оказала существенное влияние на системы КОДАСИЛ Но, к сожалению, она никак не отразилась на IMS. ЛИТЕРАТУРА 1. Cod d Е. F. A relational model of data for large shared data banks — CACM 1970, 13, № 6, p. 377—387 2. С о d d E. F. A data base sub-language founded on the relational calcu- lus.— Proceedings of ACM SIGFIDET Workshop on Data Description Access and Control, p. 35—68. 3. D a t e C. J. An Introduction to Data Base Systems, Addison — Wesley, 1975 4. CoddE. F. Understanding relations. — FDT, 1974 6, № 4, p. 18—22. 5. Workshop on Data Description Access and Control — Data Models: Data Structure Set Versus Relational (Debate Proceedings). Part of Proceedings of ACMS1GMOD Workshop, held May 1974. 6. Co d d E. F. Normalized Data Base Structure; A brief tutorial. Procee- dings of ACM SIGFIDET Workshop on Data Description Access an Control, held November 1971, p 1—1G. 7. D a t e C. J Relational Data Base Systems: A Tutorial.— in.: Iniorma- tion Systems COINS IV, 1974. Plenum Press, p. 37—54. ГЛАВА 25 РЕТРОСПЕКТИВНЫЙ ОБЗОР 25 1. ПОДВЕДЕНИЕ ИТОГОВ В первых 18 главах книги мы рассмотрели основные концепции, предложенные КОДАСИЛ по управлению базами данных, и объясни- ли каждую из них Мы не пытались представить спецификации как свод законов Эту задачу должны выполнять формальные специфика- ции, что, однако, делает их грудночитаемыми Здесь был применен механизм субъективной оценки, причем свойства, которые чаще встре- чаются в практических реализациях, бсуждались более подробно. Гл. 19 и 20 посвящены двум аспектам СУБД, о которых упоми- налось в сообщениях РГБД и КЯОД Представлен не языка определе- ния хранения данных и средств реструктуризации в этих главах до не- которой степени основывалось на работе РГАБД, находящейся в Ве- ликобритании. 273
Наконец, в гл. 21, 22 и 23 изучались три конкурирующих коммер- ческих метода, а в гл. 24 — широко пропагандируемый реляционный метод, каким он представляется в контексте предложений КОДАСИЛ. 25 2. КРИТИЧЕСКИЕ ЗАМЕЧАНИЯ ПО ПОВОДА ПРЕДЛОЖЕНИИ КОДАСИЛ Подход КОДАСИЛ к управлению базами данных, конечно, не сво- боден от недостатков. В соответствующих главах и разделах книги при рассмотрении некоторых средств мы пытались указать на некоторые его слабые стороны. Точка зрения автора по этому вопросу высказана в работе [1] представленной на конференции, которая была организо- вана Техническим комитетом 2IFIP. На этой конференции, посвящен- ной обзору ЯОД схемы, обсуждались многие проблемы [2]—17], за- тронутые в настоящей книге. Ниже перечислены несколько из рассмотренных выше средств, имеющие практическое значение, которые, по нашему мнению, долж- ны быть изменены в спецификациях (если они уже не изменены): 1. Рандомизация, подразумеваемая в CALC (см. параграф 4.5). 2. Возможность предоставления нулевого значения ключа базы данных при запоминании записи со способом размещения DIRECT (см. разд. 4.6.3). 3. Явное объявление вида представления набора в ЯОД схемы (см. параграф 5.3 и разд. 5.5.2). 4. Концепция индексированных сортируемых наборов (см. разд. 6.10.3). 5. Глобальные поисковые ключи (см. разд 6.10.3). 6. Иерархический выбор набора (см. параграф 8.6). 7. Сложные способы выбора набора с помощью значений элемента записи-члена (см. параграф 8.9) 8. Модификация выбора набора в подсхеме (см параграф 12.7). 9. Зависимость FIND ANY DUPLICATE от методов рандомиза- ции (см. разд. 15.5.2). 10. Семантика операторов управления текущим состоянием KEEP, FREE, REMONITOR (см. параграф 17.2) 11. Средства для проверки исключительных состояний базы дан- ных с помощью декларации USE (см параграф 17.6). 12. Средства обеспечения контроля доступа (см. параграф 18.5). Кроме того, рекомендуем читателю по возможности избегать мно- гочленных типов набора и сортируемых типов набора Первые услож- няют семантику, а вторые могут оказать серьезное влияние на время выполнения программы. 25 3. АСПЕКТЫ, ИМЕЮЩИЕ БОЛЕЕ ШИРОКОЕ ЗНАЧЕНИЕ Спецификации КОДАСИЛ подверглись критике и по таким вопро- сам, как независимость данных и основная архитектура. Некоторые положения в отношении независимости данных были рассмотрены при обсуждении связи между новым языком определения 274
хранения данных, предложенным РГАБД, и существующим ЯОД схе* мы (см. параграф 19.2). Вопрос о независимости данных сводится в основном к вопросу о тех средствах определения, которыми программист может воспользо- ваться в своих программах. Если какое-либо из этих средств изме- няется, программист должен соответственно изменить свою программу. Следовательно, чем больше существует таких средств, тем вероятнее, что программист воспользуется ими. Но еще вероятнее то, что его программа должна будет изменяться при внесении изменений в опре- деление данных. Чтобы объективно подойти к данному вопросу, необходимо рас- смотреть эти самые средства и выяснить их положительные аспекты. Действительно ли они предоставляют администратору данных или программисту какую-либо возможность улучшать рабочие характе- ристики всей системы? Здесь трудно дать однозначный ответ, однако администратор данных, а при некоторых обстоятельствах и програм- мист, несомненно, должен иметь возможность контролировать реше- ния по соотношению память—время. Другими словами, система должна быть достаточно гибкой, чтобы можно было добиться либо не- зависимости данных, обычно за счет ухудшения рабочих характерис- тик, либо хороших рабочих характеристик, не слишком поступаясь независимостью данных. Выше мы упоминали о средствах определения данных, которыми программист может воспользоваться в своих программах. В парагра- фе 19.2 была предложена классификация этих средств, согласно кото- рой программист не обязан их знать; не обязан их знать, но, если они ему известны, может этим восполь- зоваться; не обязан их знать и не сможет ими воспользоваться, даже если они ему известны. В этом отношении показательна концепция двухэтапного опреде- ления данных, обеспечиваемая ЯОД схемы с последующим ЯОХД. Например, было подвергнуто критике наличие в ЯОД схемы таких средств, как: вид представления набора; объявления областей и приписка им типов записи, способ размещения «через набор»; упорядочение набора. Некоторые из этих средств позволяют администратору данных при- нимать компромиссные решения. Он хочет иметь возможность влиять на физическую близость размещения записей различных типов — кон- цепция области и способ размещения «через набор» позволяют ему осу- ществить это. В некоторых ситуациях решения о порядке в наборах конкретного типа и о способе представления этих наборов являются также частью настройки базы данных. Тем не менее привлечение к воп- росам управления администратора данных вовсе не означает, что в это должен вовлекаться и программист. 275
Другими словами, вполне допустимо, чтобы контроль над опреде- ленными средствами Осуществлялся администратором данных, без предоставления аналогичных возможностей программисту. Такие средства (и вид представления набора служит тому хорошим приме- ром) должны включаться в ЯОХД, а не в ЯОД схемы. Если ЯОХД будет формально принят как часть предложений КОДАСИЛ, то реше- ние многих вопросов существенно упростится. 25.4. ПЕРСПЕКТИВНОСТЬ ПОДХОДА КОДАСИЛ Подход КОДАСИЛ к управлению базами данных не является со- вершеннытл. Необходимо пересмотреть значительную часть его специ- фикаций, многие из которых упоминались в настоящей книге. Подход КОДАСИЛ может служить основой для будущего между- народного стандарта, базирующегося на испытанной технологии. Его средства структуризации более полно соответствуют реляционной теории, чем средства других методов. Он предлагает гибкие средства управления для администратора данных, который компетентен при- нимать решения по вопросам выбора между независимостью данных и временем обработки. Мы надеемся, что данная книга окажется по- лезной широкому кругу читателей — она поможет им разобраться в этом подходе, оценить его преимущества и решить проблемы, связан- ные с его применением. ЛИТЕРАТУРА 1. О 1 1 е Т. W. An analysis of the flaws in the Schema DDL and proposed improvements.— In.: Data Base Description (Ed. В. С. M. Douque and G. M. Nijssen), North-Holland, 1975, p. 238—298. 2. N i j sse n G. M. Set and CODASYL set or coset. As above, p. 1—72. 3. Waghorn W. J. The DDL as an industry standart? As above, p. 121 — 168. 4. Kay M. H. An analysis of the CODASYL DDL for use with a relational sub-schema. As above, p. 199—214. 5. Earnest C. Selection of higher level structures in networks. As above, p. 215—238. 6. Gerassimenko T. The realm concept as incorporated in the family of database languages developed by CODASYL (for COBOL). As above, p. 329— 338. 7. S t e e 1 T. B. Jr. Data base standartization: a status report. As above, p. 183—198. ПРИМЕЧАНИЯ К РУССКОМУ ИЗДАНИЮ 1 С момента появления данной книги КОДАСИЛ опубликовал еще несколь- ко документов, основной из них — январский Отчет Комитета по языку описа- ния данных 1978 г. (Report of the CODASYL Data Description Language Commit- tee, January 1978, Information Systems, v. 3, № 4; русский перевод: Язык опи- сания данных КОДАСИЛ. М., Статистика, 1981), содержащий новую версию языка описания данных и проект языка описания хранения данных. Некоторые существенные расхождения предложений этого документа с излагаемыми в данной книге концепциями будут отмечены в примечаниях. 2 В некоторых конкретных СУБД допускается возможность попеременной или даже одновременной работы по нескольким подсхемам, 276
3 В настоящее время подавляющее большинство 'широко распространенных СУБД может работать с несколькими включающими языками. 4 Опубликован проект (см. примеч. 1) стандартных спецификаций языка описания хранения данных (ЯОХД), представляющего собой развитие концеп- ций ЯУВН. 5 Хотя пример кажется очевидным, формально он не совсем ясен. По-види- мому, автор здесь допускает широко распространенную ошибку, заключающуюся в нарушении правила, по которому экземпляр записи может принадлежат., толь- ко одному экземпляру набора данного гида и соответственно иметь только одно- го владельца поэтому типу набора. Если в примере экземпляр записи ЗАКАЗ свя- зан лишь с одним товаром, го набор СОДЕРЖИТ не имеез смысла — в нем всег да только один экземпляр-член, совпадающий с владельцем по набору ЗАКАЗЫ. Если же имеется в виду связь с несколькими товарами, тс для набора ЗАКАЗЫ нарушается приведенное выше правило. Это замечание относится, возможно, и к примеру, приведенному на рис. 3.11. 6 Здесь и далее в некоторых местах данной книги представлены концепции, существенно измененные или удаленные из ЯОД в его последней версии (см. примеч. 1). Приведем в связи с этим полностью текст разд 1.2 январского Отчета КЯОД 1978 г.: «В нижеследующем списке перечислены изменения, произведенные в специ- фикациях ЯОД с июня 1973 гл 1. Ключи базы данных переопределены как уникальные ссылки на записи в пределах одного процесса. Эти ключи нельзя больше специфицировать как элементы данных, а также как параметры упорядочения или селекции 2. Новое предложение KEY для записи позволяет объявить один или не- сколько идентификаторов (ранее — часть LOCATION MODE CALC) и ключей упорядочения записей, независимых от членства их в наборах. 3 Управление распределением ресурсов и осуществление настройки пере- несено в язык описан 4 хранения данных В связи с этим удалены следующие средства: SEARCH KEY, LOCATION MODE ACTUAL/VIRTUAL, PRIOR PROCESSABLE, LINKED TO OWNER и декларации индексов. 4. Новые декларации FREQUENCY для ключей записи и для производных элементов данных дают информацию, помогающую при оптимизации 5. Один и тот же тип записи может теперь быть и владельцем и членом од- ного и того же типа набора. 6. Добавлены средства STRUCTURAL CONSTRAINT и SELECTION BY STRUCTURAL CCLNSTRAINT для организации членства в наборах, основанного на значениях элементов данных. 7. CALL (ранее ON) позволяет теперь осуществлять более точное управле- ние моментом вызова процедур. 8. Удалено Е NCODE/DECODE. 9. Добавлен вариант FIXED членства в наборе. 10. Удалено средство AREA IS TEMPORARY. 11. Строчные элементы данных теперь могут иметь переменную длину. 12. Удалены наборы DYNAMIC. 13. WITHIN ANY AREA допускает более гибкое назначение области. I I. Изменено представление двоичных данных, заданных с помощью PICTU- RE. 15 . По всем разделам журнала произведены различные синтаксические и се- мантические уточнения». 7 Возможность использования процедур базы данных реализована в настоя- щее время во многих СУБД (см., например: Фридлендер Ф. Л., Савинков В. М. Пакет прикладных программ СУБД НАЕэОБ.— В кн.: Алгоритмы и организа- ция решения экономических задач Вып 12. М., Статистика, 1978). 8 В отчете КЯОД 1978 г. указано: «Для понимания концепции области ва?кно отметить следующее: область является поименованным подразделом базы данных;^ в схеме может быть объявлено произвольное число областей; каждая область должна быть поименована; 277
записи могут быть приписаны к области независимо от их участия в наборах. Данный тип записи или тип набора может иметь экземпляры во многих областях, а набор может распространяться по нескольким областям; каждая запись принадлежит одной и только одной области. Эта ассоциация является постоянной, так что запись не может изменять свою принадлежность области». 9 Эти «глобальные» поисковые ключи теперь можно определять с помощью предложения KEY (см. п. 2 примеч. 6). 10 В январском отчете КЯОД 1978 г. (см. примеч. 1) используются прежние термины РГБД: DELETE, REMOVE и INSERT. 11 Это ложное впечатление: формально имя-набора-1 и имя-набора-2 в одной формуле могут обозначать один и тот же набор, что и будет иметь место для неиерархических вариантов выбора набора. Предлагаемая автором замена сделала бы общую формулу выбора набора недействительной для иерархического варианта, при котором имя первого набора пути выбора не может совпадать с именем определяемого предложением набора. Х2 Для представления отношения «многие ко многим» между двумя типами записи (типичные примеры: «студенты и спецкурсы», «изделия и поставщики») в КОДАСМЛ-схеме приходится вводить третий тип записи-связки, который, как правило, содержит некоторые элементы данных (дата экзамена и оценка, количе- ство поставляемых изделий), но довольно часто не может содержать никаких разумных элементов и выполняет лишь функцию связи. 13 Подстатья данных является необязательной и должна быть здесь указана в квадратных скобках. 14 Здесь в синтаксисе имелась неточность, исправленная в более поздней версии ЯОД. Данная часть формулы должна иметь вид: WHERE OWNER IDENTIFIED BY (ид-Д.„ых.4 [EQUAL TO )]) - В настоящее время имеется ряд систем, в частност? СУБД НАБОБ (см. примеч. 7), обеспечивающих работу с ПЛ/1. 16 Если сортировка обеспечивается с помощью индекса, то и в данной ситу- ации всякая разумная система воспользуется этим индексом для более быстрого поиска требуемой записи. 17 Действительно, такая возможность имеется, и не только для хронологи- ческих типов набора, хотя в данной книге больше нигде ничего об этом не сказа- но. Подстатья члена набора может содержать предложение: DUPLICATES ARE NOT ALLOWED FOR {ид-данных-1} ...] ... 18 Если «иерархичность» связей между типами записи от точки входа до за- писи-владельца присуща самой прикладной модели данных, то использование вместо иерархического выбора набора последовательности с выбором по текущей записи-владельцу в каждом узле, действительно, усложнит действия програм- миста и существенно увеличит вероятность ошибок. 19 И все-таки данный оператор в некотором смысле меняет состояние участ- вующих в нем записей: нарушение режима (расширенного) контроля со стороны параллельного процесса фиксируется теперь не с момента предшествующего К^ЕР, а с момента последнего REMONITOR, что позволяет сэкономить новую серию операторов KEEP после первой неудачной попытки модифицировать груп- пу записей. 20 В версии ЯОД 1978 г. принят именно такой подход. 21 В приведенную классификацию почему-то не включено самое неприятное следствие: изменения в прикладных программах,
ОГЛАВЛЕНИЕ Предисловие к русскому изданию............................... Предисловие.................................................. 8 Глава 1. Исторический обзор................................ 9 1.1. Введение......................................... 9 1.2. Происхождение терминов........................... 9 1.3. Ранний период деятельности КОДАСИЛ................. 1.4. События 1971—1976 гг. . . ....................... 13 1.5. Текущее положение дел............................ 14 Литература................ 14 Глава 2. Компоненты СУБД ................................15 2.1. Введение......... • • • ......................... 15 2.2. Понятие схемы ................................. 15 2.2.1. Понятие базы данных........................ . 15 2.3. Язык описания данных схемы (ЯОД схемы).............16 2.4. Понятие подсхемы . . . ............................16 2.4.1. Язык описания данных подсхемы (ЯОД подсхемы) ... 17 2.5. Язык манипулирования данными (ЯМД)............... 18 2.5.1. Методы реализации ЯМД...................... . 18 2.5.2. Системы с несколькими включающими языками . • . . . 19 2.6. Резидентный исполнительный модуль СУБД........... 19 2.6.1. Выполнение прикладной программы................20 2.7. Язык управления размещением на внешних носителях (ЯУВН) 21 Литература .... ......... 21 Глава 3. Основные средства определения структур ........ 22 3.1 Тип записи...................................«••,•• 22 1.2. Тип записи для пользователей Алгола и Фортрана..... 22 3.2.1. Групповые элементы ... ............. 23 3.2.2. Работа с таблицами . . . . ............ . . 24 3.2.3. Квалификация ............... . .............25 3.2.4. Заключительные замечания .................... , 26 3.3. Сравнение внутренних и внешних структур записей....26 3.4. Типы набора........................................27 3.4. 1. Наборы (экземпляры наборов) ....••«•••••• 29 3.5. Назначение типа набора............................ 29 3.6. Построение структур с помощью типа набора........ 30 Литература............................................ 32 Глава 4. Представление типов записи во внешней памяти . . ... 32 4.1. Введение.................................. ...... 32 4.2. Ключ базы данных..........».•••....................32 4.3. Понятие о способе размещения..................... 33 4.3.1 Замечание о синтаксисе ...................... 34 4.3.2. Идентификаторы и имена базы данных........ . 35 4.4. Возможные способы размещения..................... 36 4.5. Способ размещения CALC......................... 36 4.5.1. Дубликаты значений ключа.................... 37 4.5.2. Коллизии (синонимы)............. . • • • 38 279
4.5.3. Нестандартные CALC-алгоритмы...................... 38 4.5.4. Выбор ключа...................,.....................39 4.6. Способ размещения DIRECT (ПРЯМОЙ)...................... 39 -4.6.1 . Назначение элементов типа ключа базы данных.......40 4.6.2. Применение способа размещения DIRECT ....... 41 4.6.3. Выборка записей................................... 42 4.7. Способ размещения VIA SET (ЧЕРЕЗ НАБОР)..................42 4.7.1. Выборка записей................................... 44 4.8. Области................................................ 44 4.8.1. Приписка типа записи к области............... . . . . 45 4.8.2. Временные области................................. 46 4.9. Заключение........................................... 47 4.9.1. Пример............................................ 48 Литература................................................ 48 Глава 5. Представление типов набора во внешней памяти .... 49 5.1. Введение............................................ . . 49 5.2. Методика представления ............................ . 50 5.3. Виды представления наборов............................. 50 5.4. Цепочное представление набора....................... . 50 5.5. Цепочка с указателем следующей записи.................. 51 5. 5.1. Проблема коррекции указателей.....................52 5. 5.2. Применение цепочек с указателем следующей записи . . 52 5.6. Цепочки с указателем следующей и предыдущей записей ... 53 5.6.1. Случай типа набора с несколькими типами записей-членов 53 5.6.2. Недостаток цепочек с указателем следующей и предыду- щей записей.............................................. 53 5.7. Цепочки с указателем владельца.......... 54 5.8. Массивы указателей..................................... 55 5.8.1. Реализация массивов указателей.........................56 5.9. Отказ КЯОД от указания вида представления набора .... 57 5.10. Синтаксис вида представления набора.....................57 5.10,1. Примеры описания наборов.......................... 58 Литература.................................................. 59 Глава 6. Упорядоченность набора и ключи поиска ......... 60 6.1. Введение.................................................60 6.2. Упорядоченность набора ............................. . 60 6.2.1. Зачем упорядочивают наборы?.........................60 6.2.2. Кто выбирает вид упорядочения?......................61 6.3. Сортируемые наборы.......................................61 6.3.1. Сортируемый одночленный тип набора...................61 6.3.2. Индексированные типы набора..........................63 6.3.3. Многочленные сортируемые типы набора............... 63 6.4. Хронологические типы набора..............................67 6.4.1. Магазины и очереди..................................67 6.4.2. Влючение «следующей» и «предыдущей».................69 6.4.3. Многочленные хронологические типы набора ...........71 6.5. Неоп>еделенный порядок набора ......................... 71 6.6. Постоянное и временное упорядочение наборов..............71 6.7. Синтаксис упорядочения набора . ....................... 72 6.8. Примеры упорядочения наборов........................... 73 6.9. Выбор варианта упорядочения набора..................... 75 6.10. Поисковые ключи.................................. • 76 6.10.1. Синтаксис........................................ 77 6.10.2. Примеры поисковых ключей......................... 78 6.10.3. Предложения по расширению концепции поискового ключа ..................................................79 Глава 7. Способ включения и допустимость исключения . ..............79 7.1. Введение . . . .................................... 79 7.2. Способ включения в набор ...........80 280
7.2.1. Неприсоединенные записи . ............. \ ♦ 81 7.2.2. Двойное включение............ ................. 82 7.3. Допустимость исключения ............................ 83 7.4. Замечания о реализации.......................• . . . . 83 7.5. Синтаксис определения способа включения и допустимости ис- ключения ..................................................83 7.6. Пример..................................... .... 84 Глава 8- Варианты выбора набора................................ 84 8.1. Введение . . .................................... 84 8.2. Критерий выбора набора................................85 8.3. Выбор набора по индикатору текущего состояния ...... 85 8.4. Выбор набора по способу размещения CALC...............86 8.5. Выбор набора по элементу типа ключа базы данных.......87 8.6. Иерархический выбор набора............................88 8.7. Синтаксис.............................................89 8.8. Использование более простых вариантов выбора набора . е 91 8.9. Особенность критерия выбора набора....................91 Глава 9. Внутренняя структура типа записи....................... . 93 9.1. Введение.............................................93 9.2. Исторические предпосылки.............................94 9.3. Назначение внутренней структуры записи................94 9.4. Типы элементов . ....................................95 9.5. Повторяющиеся группы (или агрегаты)...................96 9.6. Шаблоны...............................................97 9.7. Элементы-копии........................................98 9.8. Проверка достоверности элементов ....................99 9.9. Подстатья элемента данных............................100 9.10. Примеры.............................................102 Глава 10. Дополнительные возможности администратора данных . . 102 10.1. Введение ....................................... . . 102 10.2. Классификация возможностей ЯОД схемы................103 10.3. Процедуры базы данных............................... 104 10.4. Предложение ON (ПРИ)................................104 10.5. Процедурно управляемое размещение в памяти..........105 , 10.6. Процедуры базы данных на уровне элементов данных . . . 106 10.6.1. Предложение CHECK (ПРОВЕРКА)................. 106 10.6.2. Элементы-результаты (RESULT) ..................106 10.6.3. Предложение ENCODING/DECODING (КОДИРОВА- НИЕ/ДЕКОДИРОВАНИЕ) ....................................108 Глава 11. Синтаксис ЯОД схемы................................. 109 11.1. Введение............................................109 11.2. Общая структура синтаксиса..........................109 11.3. Статья схемы...................................... 109 11.4. Статья области ................................... 110 11.5. Статья записи ..................................... НО 11.6. Статья набора.......................................111 11.7. Заключение..........................................113 Глава 12. Подсхемы. ........................................... ИЗ 12.1. Введение........................................... 113 12.2. Связь с включающим языком...........................113 12.3. Определение подсхемы................................114 12.4. Рабочие области записей (рабочая область пользователя) . 114 12.5. Переопределение имен............................... 115 12.6. Преобразования между схемой и подсхемой.............116 12.6.1. Преобразования на уровне записи.................117 12.6.2. Преобразования на уровне групповых элементов или аг- регатов . ....................... . . ...............117 281
12.6.3. Преобразования на уровне элементов данных..........118 12.6.4. Заключительное замечание...........................119 12.7 . Изменение критерия выбора набора .................... 119 12.8* Синтаксис ЯОД подсхемы Кобола........................ 120 12.9 . Общий синтаксис ......................................121 12.10. Раздел заглавия.................................... • 122 12.1 1. Раздел отображения — секция псевдонимов . ...........122 12.1-2. Раздел структуры.....................................122 1 2.12.1. Секция областей..................................123 12.12.2. Секция записей....................................123 12.12.3. Секция наборов.................................. 124 12.13. Транслятор ЯОД подсхемы Кобола ..................... 125 Глава 13. Язык манипулирования данными.............................125 13.1. Введение............................................. 125 13.2. Взаимодействие с включающим языком................... . 125 13.3. Привязка к подсхеме....................................126 13.4. Прикладные программы и процессы . ................... 127 13.5. Регистры базы данных................................. 128 13.6. Индикаторы текущего состояния........................ 130 13.7. Общие принципы ЯМД.....................................131 13.8. Операторы ЯМД..........................................132 13.8.1. Оператор READY.................................. 133 13.8.2. Оператор FINISH....................................133 13.8.3. Оператор FIND .... ................................133 13.8.4. Оператор STORE .................................. 133 13.8.5. Оператор (ЗЕТ......................................133 13.8.6. Оператор ERASE................................... 134 13.8.7. Оператор MODIFY....................................134 13.8.8. Операторы CONNECT и DISCONNECT.....................134 13.8.9. Оператор ORDER................................. 134 13.8.10. Оператор ACCEPT...................................134 13.8.11. Оператор IF.......................................135 13.8.12. Оператор USE.................................... 135 13.8.13. Операторы KEEP, FREE и REMONITOR..................135 13.9. Заключение........................................... 135 Глава 14. Операторы READY и FINISH.................................135 14.1. Введение.................................... ....... 135 14.2. Синтаксис оператора READY ........................ . 136 14.2.1. Режимы использования ............... г 137 14.2.2. Монопольный режим доступа........................ 137 14.2.3. Защищенный режим доступа.......................... 138 14.2.4. Режим неограниченного доступа.................139 14.2.5. Общий обзор режимов использования. . ..........139 14.2.6. Открытие нескольких областей................... 140 14.2.7. Тупиковые ситуации............................141 14.2.8. Возможные исключительные состояния базы данных 142 14.3. Оператор FINISH...................................... 143 14.4. Синтаксические ошибки в READY и FINISH ........ 143 Глава 15. Операторы FIND и GET ....... . . . ..... . , 144 15.1. Оператор FIND. Введение ..... . . 3 . . . • . , . . . 144 15.2. Общий формат оператора FIND ...................... • 144 15.3. Категории оператора FIND............................. 145 15.4. Непосредственный вариант FIND..................... . 145 15.4.1. Поиск записей по способу размещения CALC ...... 145 15.4.2. Поиск записи в наборе............................ 147 ' 15.4.3. Поиск первой и последней записей в области.........148 15.5. Относительный вариант FIND.............................149 15.5.1, Поиск с применением связей в типе набора ...... 149 282
15.5.2. Поиск дубликатов............................ .... 152 15.5.3. Поиск записи-владельца ... ................... . 152 15.5.4. Поиск в наборе......................... .... 153 15.5.5. Поиск дубликатов в наборе................ . .... 154 15.5.6. Поиск следующей или предыдущей записи в области . . . 156 15.6. Повторный вариант FIND................................ 156 15.6.1. Поиск по значениям индикаторов текущего состояния . . 157 15.6.2. Поиск по значениям элементов типа ключа базы данных 158 15.7. Исключительные состояния базы данных....................159 15.8. Оператор (ЗЕТ. Введение............................... 160 15 8.1. Общие положения.......................* . .... 160 15.8.2. ОЕТ без параметров............................... 161 15.8.3. GET имя-записи. ................................. 162 15.8.4. GET элементы .................................... 162 15.8.5. Исключительные состояния базы данных...............162 15.9. Соотношение между FIND и GET...................... .... 163 Глава 16. Обновляющие операторы ЯМД....................... 163 16.1. Введение............................ ................ 16.2. Оператор MODIFY...................................... 16.1.2 . Возможные осложнения при выполнении MODIFY . 16.2.2 . Исключительные состояния базы данных...... . 16.3. Оператор ERASE............................... . . 16.3.1. Простой ERASE................................... 16.3.2. Вариант ERASE ALL .................... ......... 16.2.3. Вариант ERASE PERMANENT..................... . 16.3.4. Вариант ERASE SELECTIVE......................... 16.3.5. Исключительные состояния базы данных ....... 16.4. Оператор STORE.............................. . . . . 16.4.1. Фраза WITHIN ................................. 16.4.2. Декларации способа размещения .......... 16.4.3. Декларации типов набора и способов включения . . . 16.4.4. Критерий выбора набора ......................... 16.4.5. Упорядоченность набора......................... . 16.4.6. Поисковые ключи................................. 16.4.7. Вид представления набора.............. 16.4.8. Исключительные состояния базы данных............ 16.5. Оператор CONNECT . . ................... 16.5.1. Исключительные состояния базы данных............ 16.6. Оператор DISCONNECT ................................. 16.6.1. Исключительные состояния базы данных.......... . . 163 164 165 166 166 167 167 168 168 168 169 170 170 171 171 172 173 173 173 174 175 175 176 Глава 17. Другие операторы ЯМД ................. 176 17.1. Введение........................................ 17.2. Управление одновременным доступом........... . . 17.2.1. Оператор KEEP............... ................ 17.2.2. Оператор FREE........................... . 17.2.3. Оператор REMONITOR . ..................... 17.2.4. Заключительные замечания .................... 17.3. Оператор упорядочения набора...................... 17.4. Считывание системных регистров ................... 17.4.1. Считывание значений индикаторов текущего состояния 17.4.2. Считывание имен областей . , ................ 17.5. Проверка условий базы данных......... ....... . 17.5.1. Условия принадлежности к набору . ........ . 17.5.2. Условия наличия членов в наборе........ . . 17.5.3. Условия неопределенности значений . . ....... 17.5.4. Еще одно полезное условие............... . . . 17.6. Проверка исключительных состояний базы данных..... 176 177 177 178 179 179 180 181 182 182 183 183 184 184 185 185 283
Г л а в а 18. Система контроля доступа..............................187 18.1- Введение...............................................187 18.2- Компоненты подсистемы контроля доступа.................187 18.3- Предложения РГБД по контролю доступа....................188 18.3.1. Замки, определеляемые в схеме.............. .... 188 1 8.3.2. Замки, определяемые в подсхеме...............189 18.3.3. Программно-определяемые ключи......................191 18.4- Виды замков и ключей..................................194 18.4.1, Замки-литералы.....................................194 18.4.2. Замки-переменные ..................................195 18.4.3. Замки-процедуры....................................196 18.5. Критический обзор подхода КОДАСИЛ к контролю доступа 197 18.5.1, Защита данных и определение привилегий программиста 198 18.5.2. От кого защищаются данные? ........................199 18.5.3. Вынесение описаний замков защиты из ЯОД схемы . . . 199 18.5.4. Замок защиты для СОРУ ... ....................200 18.6. Предлагаемый подход к контролю доступа..................201 18.6.1. Служебная программа определения полномочий . . . 201 18.6.2. Язык защиты данных................................201 18.6.3. Язык привилегий программиста .....................203 Г л а в а 19. Язык управления размещением на внешних носителях . . . 205 19.1.................................................." Введение.............................................205 19.2. Взаимосвязь ЯОХД и ЯОД схемы............................205 19.3. Возможности ЯОХД.......................................207 19.3.1. Уровень областей...................... .......... 207 19.3.2. Уровень записей....................................208 19.3.3. Уровень типа набора................................209 19.4. Способы предоставления средств ЯОХД...................209 Литература ...................................................210 Г лава 20. Реструктуризация.......................................210 20.1. Замечания РГБД по реструктуризации....................210 25.2. Уточняющие формулировки КЯОД ...........................212 20.3. Реструктуризация и реорганизация .......................212 20.4. Спецификация реструктуризации на уровне схемы и ЯОХД . 213 20.4.1. Спецификация реорганизации.......................213 20.5. Процесс реструктуризации................................213 20.5.1. Следствия реструктуризации.......................214 20.6. Реструктуризация на уровне схемы........................214 20.6.1. Дополнения схемы...................................214 20.6.2. Сокращения схемы...................................215 20.6.3. ?4одификации схемы. . , ......................... . 216 20.7. Заключение.............................................217 Глава 21. Система TOTAL.............................................217 21.1. Основные компоненты.....................................217 21.2. Реализация ЯМД..........................................218 21.3. Концепция структурирования..............................218 21.3.1. Структуры связи между записями.....................219 21.3.2. Внутренняя структура записи........................220 21.4. Представление типа записи в памяти......................221 21.5. Представление типа набора в памяти......................222 21.6. Упорядочение набора.....................................222 21.7. Поисковые ключи.........................................223 21.8. Способ включения и допустимость исключения..............223 21.9. Выбор набора............................................224 21.10. Подсхема...............................................224 21.11. Концепции ЯМД..........................................225 21.12, Операторы ЯМД , , ................................ . 225 281
21.13. Операторы ЯМД, применяемые для записей-владельцев и записей-членов......................................... 226 21.13. 1. Операторы SINON, READY и FINISH . ...........226 21 .13.2. Многоцелевой оператор READ.................227 21.13. 3. Условный оператор FIND..................... 229 21.14. Операторы ЯМД, применяемые для типа записи-владельца . 230 21.14.1. Операторы поиска ..............................231 21.14.2. Операторы обновления......................... 232 21.15- Операторы ЯМД, применяемые для записей-членов . . . 232 21.15.1. Операторы поиска ............................ 232 21.15.2. Операторы обновления....................... 233 21.16. Заключение..........................................234 Глава 22. Система IMS............................................ . 235 22.1. Основные компоненты..................................235 22.2. Реализация ЯМД.......................................236 22.3. Концепции структурирования...........................236 22.3.1. Внутренняя структура записи. ...................238 22.3.2. Типы набора.....................................238 22.4. Представление типа записи в памяти...................240 22.5. Представление типа набора в памяти................. 241 22.6. Упорядочение набора..................................244 22.7. Поисковые ключи......................................244 22.8. Способ включения и допустимость исключения...........245 22.9. Выбор набора.........................................245 22.10. Подсхема............................................245 22.11. Концепции ЯМД.......................................246 22.11.1. Аргументы поиска сегмента......................247 22.11.2. Операторы Поиска................................ . 247 22.11.3. Операторы обновления...........................248 22.11.4. Другие операторы ЯМД ........................ 249 22.12. Заключение..........................................250 Литература . . ........................................ 250 Глава 23. Система ADABAS .......................................250 23.1. Основные компоненты..................................250 23.2. Реализация ЯМД . .................................. 250 23.3. Концепции структурирования...........................251 23.3.1. Внутренняя структура записи.....................251 23.3.2. Связи между записями............................251 23.4. Представление типов записи в памяти . ...............254 23.5. Представление типов набора в памяти................ 254 23.6. Упорядочение набора . ...............................254 23.7. Поисковые ключи.................................... 254 23.8. Способ включения и допустимость исключения...........255 23.9. Выбор набора.........................................255 23.10. Подсхема............................................255 23.11. Концепции ЯМД.......................................255 23.12. С аторы ЯМД....................................... 256 23.1. Операторы поиска ЯМД — FIND .......... 256 23.12.2. Операторы поиска ЯМД — READ.............. . . . 258 23.12.3. Обновляющие операторы ЯМД.................... 259 23.12.4. Другие операторы ЯМД......................... 259 23.13. Заключение........................................ 260 Глава 24. Реляционный подход................................... 260 24.1. Общие сведения..................................... 260 24.2. Реляционная терминология........................... 261 24..' 1. Атрибут, домен и элемент данных................261 24.2.2. Отношение и типы записей...................... 262 24.2.3. Кортежи и записи.............................. 262 285
24.2.4. Таблицы и файлы...................... • • • . 262 24.2.5. Тип набора и зависимость между отношениями. . . . 263 24.2.6. Степень отношения............................263 24.5. Краткое изложение реляционной теории..............263 24.4г. Ограничения реляционной теории в терминах КОДАСИЛ . . 265 24.5. Реляционные сети и сети КОДАСИЛ.................. 265 24.(5. Использование ключей ......................... . , 266 24.7 . Типы набора и свойства наследования. ........... 267 24.7.1. Определение связи.......................... 267 24.7.2. Упорядочение набора........................ 267 24.7.3. Способ включения........................... 268 24.7.4. Вид представления набора................... 268 24.5. Практические аспекты реляционной теории ..........269 £4.8.1. Уникальный первичный ключ ....•••.•.•• 269 £4.8.2. Представление связей типа набора ......... . 269 24.8- 3. Распространение первичных ключей...............270 24.9. Подъязыки данных (ЯМД) для реляционной базы данных 271 24.9.1. Реляционная алгебра...........................271 2 4.8.2. Реляционное исчисление.................... 272 24.10. Заключение. ................................. 272 Литература .............................................273 Глава 25. Ретроспективный обзор 273 25.1. Подведение итогов. . ............ ............... 273 25.2_ Критические замечания по поводу предложений КОДАСИЛ 274 25.3. Аспекты, имеющие более широкое значение...........274 25.4. Перспективность подхода КОДАСИЛ . . . . ...... . 276 Литература............................................ 276 Примечания к русскому изданию................••••••••.•• 276
Олле Т В. 053 Предложения КОДАСИЛ по управлению базами даи- ’ ных / Пер. с англ. В. И. Филиппова и С. М. Круговой. — М.: Финансы и статистика, 1981. — 286 с., ил. В пер.: 1 р. 30 к. В книге наряду с изложением формальных правил и возможностей баз дан- ных рассматриваются предложения КОДАСИЛ: как исторически развивалйсъ пред- лагаемые конструкции, каковы их достоинства и недостатки, в каких случаях пользователю рекомендуется их применять. Представлены наиболее распространен- ные действующие системы управления базами данных (СУБД). Для пользователей и разработчиков СУБД во всех отраслях народного хозяй- ства, а также для специалистов по системам обработки данных; может быть ес- лезна аспирантам и студентам, занимающимся системным программированием н обработкой данных. 10804-101 ° 010(01) 81 103-81 (С) 2405000000 ББК 32973 6Ф7Л
Т. В. Олле Предложения КОДАСИЛ по управлению базами данных Книга одобрена на заседании секции редсовета по электронной обработке данных в экономике 11 октября 1979 г. Зав. редакцией А. В. Павлюков Редактор /7. /(. Логинова Мл. редактор И. Н. Г орана Техн, редактор Л. Г. Челышева Корректоры Г А. Башарина, Г. И Терновская Худож. редактор Э. А Смирнов Переплет художника И. А1. Веселова ИБ № 1015 Сдано в набор 09.03.81, Подписано в печать 04 08.81. Формат 60X90 1/16 Бум кн.-журн Гарнитура «Литературная». Печать высокая. П. л. 18,0 Усл. п. л 18,0 Усл. кр.-отт. 18,0 Уч.-изд л. 19,1 Тираж 30 000 экз. Заказ 145 Цена 1 р. 30 к. Издательство «Финансы и статистика» Москва, ул. Чернышевского. 7 Московская типография № 4 Союзполиграфпрома при Государственном Комитете СССР по делам издательств, полиграфии и книжной торговли 129041, Москва, Б. Переяславская ул., д. 46