Классика баз данных - статьи

         

Использование классов %Net.SMTP и %Net.POP3 для отправки и приема электронной почты.


С помощью классов %Net.SMTP и %Net.POP3 системной библиотеки %Net, поставляемой в стандартной конфигурации, можно реализовать функции отправки и приема электронных писем на базе СУБД Cache'.

В Листинге 2 приведена Cache'-программа, с помощью которой реализуется отправка электронного письма с прикрепленным графическим файлом (test.jpg) по протоколу SMTP.

Листинг 2.

set s=##class(%Net.SMTP).%New() set s.smtpserver="SMTP.mail.ru" set s.timezone="-0400" set m=##class(%Net.MailMessage).%New() set m.From="test@company.com" do m.To.Insert("receiver@another.com") set m.Subject="Sent by Cache'' mail" set m.Charset="iso-8859-1" do m.TextData.Write("This is the main body.") do m.TextData.Write($char(13,10)) do m.TextData.Write("This is the second line.") do m.TextData.Write($char(13,10)) set status=m.AttachFile("c:\winnt","test.jpg") set status=s.Send(m) do m.%Close() do s.%Close() quit

Класс %Net.SMTP поддерживает также отправку сборных (multi-part) электронных писем.

Для реализации функции приема электронных писем можно воспользоваться системным классом %Net.POP3. В листинге 3 приведен пример использования класса %Net.POP3.

Листинг 3.

new mailserver,status,from,to,date,subject,messagesize,m,hdrs,key,mailMsg set mailserver=##class(%Net.POP3).%New() set mailserver.AttachDir="d:\attach\" ; need terminating \ set mailserver.Debug=0 set mailserver.StoreAttachToFile=1 write !,"Calling Connect" set status=mailserver.Connect("moon.kinich.com","testjsl","jsltest") write !,"Calling FetchMessage" set status=mailserver.FetchMessage(13,.from,.to,.date, .subject,.messagesize,.hdrs,.mailMsg,0) write !,"from="_from write !,"to="_to write !,"date="_date write !,"subject="_subject write !,"messagesize="_messagesize write !,"Closing mailserver="_mailserver.%Close() write !,"Closing mailMsg="_mailMsg.%Close() quit



Используемые источники


[1] Joe Celko "A Look at SQL Trees",



Исследования и разработки в области операционных систем


Сергей Кузнецов

Пожалуй, операционные системы в традиционно понимаемом смысле в

настоящее время являются скорее предметом индустриальных



разработок, чем исследований. Даже те работы, которые велись и

ведутся в университетах США, все более приобретают характер

полупромышленных разработок. По всей видимости, это связано,

во-первых, с накоплением громадного запаса методов и алгоритмов,

а во-вторых, с достаточно жесткой стандартизацией функций и

интерфейсов операционных систем. Пожалуй, единственной областью,

примыкающей к тематике операционных систем и подвергаемой

интенсивным исследованиям, является область объектных

операционных сред (основанных на специально разработанных или

традиционных ОС).

В этом материале мы кратко рассмотрим три темы: современное

состояние наиболее развитой на сегодняшний день и популярной в

академических и научных кругах операционной системы UNIX, а

также состояние дел в области стандартизации ОС; сравнительно

новую и перспективную технологию организации операционных систем

на основе микроядер.

1. ОС UNIX и стандарты Открытых Систем

Операционная система UNIX, являющаяся первой в истории мобильной

ОС, обеспечивающей надежную среду разработки и использования

мобильных прикладных систем, одновременно представляет собой

практическую основу построения открытых программно-аппаратных

систем и комплексов. Именно широкое внедрение в практику ОС UNIX

позволило перейти от лозунга Открытых Систем к практической

разработке этой концепции. Большой вклад в развитие направления

Открытых Систем внесла деятельность по стандартизации

интерфейсов ОС UNIX.

Тем не менее, до сих пор можно выделить несколько ветвей ОС

UNIX, различающихся не только реализацией, но временами и

интерфейсами и семантикой (хотя, по мере развития процесса

стандартизации, эти различия становятся все менее

значительными). В приводимом ниже кратком обзоре мы затрагиваем

только некоторые варианты ОС UNIX, которые, по нашему мнению,

наиболее существенны в настоящее время.


1.2 UNIX System V 4.x и опирающиеся на него операционные системы

Канонические исходные тексты ОС UNIX, как известно, были

написаны сотрудниками телефонной компании AT&T, и долгое время

авторские права, равно как и права на продажу лицензий на

использование исходных текстов принадлежали этой компании. В

дальнейшем, по причине технических сложностей с разработкой и

сопровождением сложного программного продукта и некоторых

юридических затруднений компания AT&T образовала дочернюю

компанию USL (UNIX System Laboratories) с основной задачей

развития и сопровождения исходных текстов ОС UNIX.

Именно USL выпустила вариант ОС UNIX System V 4.0, который стал

фактическим стандартом операционной системы UNIX и явился

основой многочисленных версий ОС UNIX, производимых поставщиками

рабочих станций и серверов. Последним успехом USL как дочерней

компании AT&T явился выпуска SVR 4.2. Помимо прочего, в этой ОС

был впервые в истории UNIX реализован механизм легковесных

процессов (threads), работающих на общей виртуальной памяти и

позволяющих использовать аппаратные возможности так называемых

"симметричных мультипроцессорных архитектур", в которых

несколько процессоров имеют равноправный доступ к общей

оперативной памяти.

В 1993 г. компания USL была поглощена компанией Novell, и в

настоящее время фактически является подразделением этой

компании. При этом владение торговой маркой UNIX было передано

консорциуму X/Open. В 1994 г. USL в составе Novell была почти

незаметна; видимо, сказывались необходимые структурные,

организационные и маркетинговые преобразования. Однако в начале

1995 г. компания Novell объявила о выпуске нового варианта своей

ОС UnixWare 2.0, основанного на System V 4.2, что свидельствует

о завершении процесса внедрения USL в Novell.

1.2.1 UnixWare компании Novell

Компания Novell приобрела широкую известность и заработала

основной капитал на рынке локальных сетей персональных ЭВМ.

Распространенная "сетевая" ОС NetWare на самом деле всего лишь



обеспечивает сетевой доступ персональных компьютеров, работающих

под управлением MS-DOS, к ресурсам серверов (главным образом,

файловых). Возрастающие возможности компьютеров, основанных на

процессорах компании Intel, их фактический переход из класса

персональных компьютеров в класс развитых рабочих станций,

недостаточные возможности ОС типа MS-DOS для эффективного

использования этих компьютеров заставили компанию Novell

обратить внимание на операционную систему UNIX.

Первая версия системы под названием UnixWare целиком основывалась

на SVR 4.0, но включала ряд расширений, специфичных для Novell.

Следует отметить, что многие пользователи этой системы были не

слишком ей довольны: она была не очень надежна и сложно

администрировалась. В начале 1995 г. появился релиз UnixWare 2.0,

основанный на SVR 4.2. По отзывам пользователей эта система

гораздо более продвинута. В частности, обеспечивается полный

графический интерфейс администратора, файловая система очень

надежна, допускается доступ к файлам, хранимым на серверах

NetWare и т.д. В конце 1995 г. компания Novell обещает выпустить

новый продукт, который будет основываться на UNIX, но при этом

будет поддерживать все функции NetWare.

1.2.2 Solaris компании Sun Microsystems

Известно, что в течении многих лет основой операционных систем

(SunOS) компании Sun являлся UNIX BSD. Однако, начиная с SunOS

4.0, произошел полный переход на System V 4.0. Это связано,

прежде всего, с тем, что SVR 4.0 включает функциональные

возможности UNIX линии BSD.

Sun Microsystems внесла ряд существенных расширений в SVR 4.0.

Прежде всего это касается обеспечения распараллеливания программ

при использовании симметричных мультипроцессорных компьютеров

(механизм потоков управления - threads). В SVR 4.0 этот механизм

отсутствовал (он появился только в SVR 4.2), а компания Sun уже

активно выпускала мультипроцессорные компьютеры. Поэтому в SunOS

был реализован собственный механизм threads, что потребовало

многочисленных переделок в ядре системы.



Solaris является внешней оболочкой SunOS и дополнительно включает

средства графического пользовательского интерфейса и

высокоуровневые средства сетевого взаимодействия (в частности,

средства вызова удаленных процедур - RPC). Заметим, что хотя

самая первая реализация механизма RPC принадлежит компании Xerox,

именно реализация Sun стала фактическим стандартом и

лицензирована многими компаниями.

1.2.3 HP/UX компании Hewlett-Parkard, DG/UX компании Data

General, AIX компании IBM


HP/UX, DG/UX и AIX обладают многими отличиями. В частности, в

этих версиях ОС UNIX поддерживаются разные средства генерации

графических пользовательских интерфейсов (хотя все они основаны

на использовании оконной системы X), по-разному реализованы

threads и т.д.

Однако все эти системы объединяет тот факт, что в основе каждой

из них находится SVR 4.x. Поэтому основной набор системных и

библиотечных вызовов в этих реализациях совпадает.

Заметим, что в компании IBM существовал план разработки полностью

самостоятельной реализации AIX на основе микроядра. Однако в

последнее время IBM отказалась от этой идее, хотя собственное

микроядро (новая реализация микроядра Mach) уже было создано.

1.3 Santa Cruz Operation и SCO UNIX

Варианты ОС UNIX, производимые компанией SCO и предназначенные

исключительно для использования на Intel-платформах, до сих пор

базируются на лицензированных исходных текстах System V 3.2.

Однако SCO довела свои продукты до уровня полной совместимости со

всеми основными стандартами (в тех позициях, для которых

существуют стандарты).

Консерватизм компании объясняется прежде всего тем, что ее

реализация ОС UNIX включает наибольшее количество драйверов

внешних устройств и поэтому может быть установлена практически на

любой Intel-платформе. Естественно, при переходе на другой

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

потребоваться массовая переделка драйверов.

Тем не менее, SCO имеет соглашение с французской компанией Chorus

Systems о разработки новой версии SCO UNIX, базирующегося на



микроядре Chorus и предназначенного для использования в системах

реального времени.

1.4 Open Software Foundation и OSF-1

OSF была первой коммерческой компанией, решившейся на полную

реализацию ОС UNIX на базе микроядра Mach. Результатом этой

работы явилось создание ОС OSF-1. Как утверждают, OSF-1 на самом

деле не является полностью лицензионно чистой системой: в ней

используется часть исходных текстов SVR 4.0.

На сегодняшний день наиболее серьезным потребителем OSF-1

является компания Digital Equipment на своих платформах,

основанных на микропроцессорах Alpha. В OSF-1 поддерживаются все

основные стандарты ОС UNIX, хотя многие утверждают, что пока

система работает не очень устойчиво.

1.5 Berkeley Standard Distribution, Free BSD, BSD Net и т.д.

Многие годы варианты ОС UNIX, разработанные в Калифорнийском

университете г. Беркли, являлись реальной альтернативой AT&T

UNIX. Например, ОС UNIX BSD 4.2 была бесплатно доступна в

исходных текстах и достаточно широко использовалась даже в нашей

стране на оригинальных и воспроизведенных машинах линии DEC. BSD

4.3 являлась основой популярной ОС Ultrix компании DEC. UNIX BSD

использовался в SunOS. И т.д.

Группа BSD оказала огромное влияние на общее развитие ОС UNIX. До

появления SVR 4.0 проблемой для пользователей являлась

несовместимость наборов системных вызовов BSD и System V. Как мы

отмечали выше, в SVR 4.0 был реализован общий набор системных

вызовов.

Около 5 лет назад в Беркли была начата работа над микроядерной

реализацией BSD 4.4. Работа была уже близка к завершению, когда

компания USL, являвшаяся в то время владельцем исходных текстов

System V, подала в суд на университет Беркли, мотивируя это тем,

что в BSD 4.4 нелегально используются части исходных текстов SVR

4.0. Процесс продолжался около двух лет и закончился победой

Беркли, хотя в то же время было выставлено условие произвести

полную очистку текстов BSD от следов System V. Все это,

естественно, затормозило выпуск BSD 4.4, полный вариант которой



до сих пор недоступен.

Несколько лет назад группа BSD разделилась на коммерческую и

некоммерческую части. Новая коммерческая компания получила

название BSDI. Обе подгруппы выпустили варианты ОС UNIX для

Intel-платформ под названиями 386BSD и BSD386, причем

коммерческий вариант был гораздо более полным.

Сегодня популярен новый свободно распространяемый вариант ОС

UNIX, называемый FreeBSD. Ведутся работы над более развитыми

версиями BSDNet.

1.6 Torvald Linus и LINUX

LINUX - это оригинальная реализация ОС UNIX для Intel-платформ,

выполненная молодым сотрудником университета Хельсинки Торвальдом

Линусом. По непроверенным слухам совсем недавно появилась версия

LINUX для PowerPC.

LINUX распространяется свободно, является очень экономичной ОС и

весьма популярен среди молодежи. Практически каждую неделю

появляется новый драйвер, работающий в LINUX. Этой ОС посвящена

одна из самых активных телеконференций в Internet. Уже издается

несколько регулярных журналов, связанных исключительно с

тематикой LINUX.

1.7 POSIX, XPG и т.д.

До тех пор, пока господствовала узкая трактовка ОС UNIX (т.е.

пока ОС UNIX не была коммерческим продуктом), не было потребности

в стандартизации средств этой операционной системы.

Немногочисленные высококвалифицированные пользователи ОС UNIX

сами могли разобраться в особенностях и отличиях используемой

версии системы и выбрать то подмножество ее средств, которое

обеспечивало переносимость разрабатываемого приложения.

Однако с выходом ОС UNIX на коммерческий рынок, переходом к

широкой трактовке системы и существенным увеличением числа

пользователей различных ее вариантов стало необходимым ввести

хотя бы возможность производства основанных на ОС UNIX

операционных систем, которые были бы действительно совместимы.

Для этого необходима стандартизация (интерфейсов) средств

операционной системы на разных уровнях. Такая работа ведется уже

около 10 лет, еще не завершена и вряд ли когда-либо будет

завершена в виде окончательного набора стандартов де-юре.


Тем не

менее, даже полученные результаты позволяют производителям

обеспечить пользователей разных аппаратных платформ операционными

системами, достаточно удобными для использования и позволяющими

разрабатывать мобильные прикладные системы, которые могут

выполняться на компьютерах, оснащенных операционными системами с

аналогичными свойствами.

Прежде чем перечислить наиболее важные официальные и фактические

стандарты, принимаемые во внимание производителями систем,

основанных на ОС UNIX, сформулируем, что же понимается под

стандартом интерфейсов ОС. Стандарт интерфейсов ОС - это обычно

сводка более или менее формальных синтаксических (интерфейсных) и

семантических (поведенческих) свойств специфицируемых средств

операционной системы.

1.7.1 System V Interface Definition (SVID)

Одним из наиболее ранних стандартов де-факто ОС UNIX явился

изданный UNIX System Laboratories (USL) одновременно с выпуском

версии ОС UNIX System V Release 4 документ System V Interface

Definition (SVID). Если кратко напомнить историю, то владельцем

оригинальных исходных текстов ОС UNIX являлась компания AT&T Bell

Laboratories (именно работники этой компании Ричи, Томпсон и

Керниган разработали в начале 1970-х самый первый мобильный

вариант ОС UNIX). В 1980-е годы компания AT&T основала дочернюю

компанию USL, которой были переданы права на исходные тексты и

торговую марку ОС UNIX. USL выпустила системы с System V R.4.0 до

System V R.4.2, после чего в конце 1993 г. была поглощена

компанией Novell, которая теперь является владельцем исходных

текстов ОС UNIX (под давлением общественности торговая марка

"UNIX" была передана компании X/Open).

Несмотря на все эти пертурбации SVID продолжает существовать и

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

объяснением этому является тот факт, что большинство коммерческих

вариантов ОС UNIX (в частности, четыре из пяти, рассматриваемых в

этом разделе) основаны на лицензированных у AT&T-USL-Novell



исходных текстах UNIX. Поэтому не очень сложно полностью

удовлетворять этому фактическому стандарту. Естественно, SVID как

документ, изданный одной компанией без его предварительного

общественного обсуждения, никогда не будет принят в качестве

официального стандарта.

1.7.2 Деятельность комитетов POSIX

Следует вспомнить, что наряду с версиями ОС UNIX, развивавшимися

в компании AT&T (затем в USL, а теперь - в Novell), исторически

существовало еще направление BSD (Berkeley Standard

Distribution), успешно поддерживавшееся небольшой, но всемирно

известной группой из университета г. Беркли (шт. Калифорния). В

свое время (в конце 1970-х) университет получил из AT&T исходные

тексты 16-разрядной ОС UNIX, на основе которых была произведена

32-разрядная система, которая сначала использовалась на

компьютерах семейства VAX, а затем была перенесена на многие

другие аппаратные платформы. В результате наборы системных

вызовов UNIX AT&T и BSD стали значительно различаться.

Хотя большинство коммерческих реализаций UNIX основывалось на

System V, UNIX BSD всегда был популярен в университетах, и

общественность потребовала определения некоторого интерфейса,

который являлся бы по сути объединением средств AT&T и BSD. Эта

работа была начата Ассоциаций профессиональных программистов

Открытых Систем UniForum, а затем продолжена в специально

созданных рабочих группах POSIX (Portable Operating System

Interface). В рабочих группах POSIX разрабатываются многие

стандарты открытых систем, но наиболее известным и авторитетным

является принятый ISO по представлению IEEE стандарт POSIX

1003.1, в котором определены минимальные требуемые средства

операционной системы (по сути дела, UNIX).

1.7.3 Деятельность X/Open

Международная организация X/Open, которая выполняет многие

работы, связанные с пропагандой и анализом использования открытых

систем, кроме того, собирает и систематизирует де-юре и де-факто

стандарты, имеющие промышленное значение, в так называемом X/Open



Common Application Environment (CAE). Спецификаций интерфейсов

средств, входящих в CAE, публикуются в многотомном документе

X/Open Portability Guide (XPG).

1.7.4 Стандарт ANSI C

Очень важным в мире UNIX является принятый сначала ANSI, а потом

и ISO международный стандарт языка программирования Си. Дело в

том, что в этом стандарте специфицирован не только

непосредственно язык Си, но и библиотеки, необходимые в каждой

стандартной реализации. Поскольку с самого своего появления язык

Си и соответствующие системы программирования были неразрывно

связаны с ОС UNIX, то состав стандартных библиотек достаточно

точно соответствует стандартной среде ОС UNIX.

Перечисленные четыре стандарта, только два из которых являются

официально принятыми, наиболее авторитетны для производителей

операционных систем, претендующих на совместимость с ОС UNIX.

Особенностью этих стандартов является их полная машинная

независимость.

Имеется другая разновидность стандартов де-факто,

распространяемых на некоторый класс аппаратных архитектур.

Примером такого стандарта может служить документ, принятый

международной организацией SPARC International документ SPARC

Complience Definition, содержащий машинно-зависимые уточнения к

машинно-независимым спецификациям интерфейсов. Аналогичный

документ разрабатывался организацией 88/Open, связанной с

RISC-процессорами фирмы Motorola.

Среди других индустриальных де-факто стандартов для современных

вариантов ОС UNIX наиболее важны фактический стандарт оконной

системы, поддерживаемый X Cosortium, в основе которого находится

лаборатория Массачусетского технологического института (MIT),

являющаяся разработчиком системы X, а также спецификации

интерфейсов инструментального средства разработки графических

пользовательских интерфейсов OSF/Motif, разработанные в Open

Software Foundation (OSF).

Заметим, что кроме того, в OSF разработан документ OSF

Application Environment Specification (AES), содержащий

спецификации интерфейсов ОС OSF/1, являющей собственной



реализацией OSF ОС UNIX на базе новой микроядерной технологии

(правда, до сих пор в этой реализации используются фрагменты

исходного текста System V). AES является расширением SVID, POSIX

1003.1 и XPG.

2. Микроядерные операционные системы

Микроядро - это минимальная стержневая часть операционной

системы, служащая основой модульных и переносимых расширений.

По-видимому, большинство операционных систем следующего поколения

будут обладать микроядрами. Однако имеется масса разных мнений по

поводу того, как следует организовывать службы операционной

системы по отношению к микроядру: как проектировать драйверы

устройств, чтобы добиться наибольшей эффективности, но сохранить

функции драйверов максимально независимыми от аппаратуры; следует

ли выполнять операции, не относящиеся к ядру, в пространстве ядра

или в пространстве пользователя; стоит ли сохранять программы

имеющихся подсистем (например, Unix) или лучше отбросить все и

начать с нуля.

В широкий обиход понятие микроядра ввела компания Next, в

операционной системе которой использовалось микроядро Mach.

Небольшое привилегированное ядро этой ОС, вокруг которого

располагались подсистемы, выполняемые в режиме пользователя,

теоретически должно было обеспечить небывалую гибкость и

модульность системы. Но на практике это преимущество было

несколько обесценено наличием монолитного сервера, реализующего

операционную систему UNIX BSD 4.3, которую компания Next выбрала

в качестве оболочки микроядра Mach. Однако опора на Mach дала

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

объектно-ориентированных сервисных функций, на основе которых

удалось создать элегантный интерфейс конечного пользователя с

графическими средствами конфигурирования сети, системного

администрирования и разработки программного обеспечения.

Следующей микроядерной операционной системой была Windows NT

компании Microsoft, в которой ключевым преимуществом

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



но и переносимость. (Заметим, что отсутствует единодушное мнение

по поводу того, следует ли на самом деле относить NT к

микроядерным ОС.) ОС NT была построена таким образом, чтобы ее

можно было применять в одно- и мультипроцессорных системах,

основанных на процессорах Intel, Mips и Alpha (и тех, которые

придут вслед за ними). Поскольку в среде NT должны были

выполняться программы, написанные для DOS, Windows, OS/2 и

систем, совместимых со стандартами Posix, компания Microsoft

использовала присущую микроядерному подходу модульность для

создания общей структуры NT, не повторяющей ни одну из

существующих операционных систем. Каждая операционная система

эмулируется в виде отдельного модуля или подсистемы.

Позднее микроядерные архитектуры операционных систем были

объявлены компаниями Novell/USL, Open Software Foundation (OSF),

IBM, Apple и другими. Одним из основных конкурентов NT в области

микроядерных ОС является Mach 3.0, система, созданная в

университете Карнеги-Меллон, которую как IBM, так и OSF взялись

довести до коммерческого вида. (Компания Next в качестве основы

для NextStep пока использует Mach 2.5, но тоже внимательно

присматривается к Mach 3.0.) Другим конкурентом является

микроядро Chorus 3.0 компании Chorus Systems, выбранное USL в

качестве основы новых реализаций ОС Unix. Некоторое микроядро

будет использоваться в SpringOS фирмы Sun,

объектно-ориентированном преемнике ОС Solaris. Очевидна тенденция

к переходу от монолитных к микроядерным системам (хотя, как мы

отмечали в предыдущем разделе, этот процесс не является

прямолинейным: компания IBM сделала шаг назад и отказалась от

перехода к микроядерной технологии). Кстати, это совсем не

новость для компаний QNX Software Systems и Unisys, которые уже в

течение нескольких лет выпускают пользующиеся успехом

микроядерные операционные системы. ОС QNX пользуется спросом на

рынке систем реального времени, а CTOS фирмы Unisys популярна в

области банкового дела. В обеих системах успешно использована



модульность, присущая микроядерным ОС.

2.1 Функции микроядра

Микроядро реализует базовые функции операционной системы, на

которые опираются другие системные службы и приложения. Основной

проблемой при конструировании микроядерной ОС является

распознавание тех функций системы, которые могут быть вынесены из

ядра. Такие важные компоненты ОС как файловые системы, системы

управления окнами и службы безопасности становятся периферийными

модулями, взаимодействующими с ядром и друг с другом.

Когда-то казалось, что многоуровневая архитектура ядра ОС UNIX

является вершиной в области конструирования операционных систем.

Основные функциональные компоненты операционной системы -

файловая система, взаимодействие процессов (IPC - interprocess

communications), ввод-вывод и управление устройствами - были

разделены на уровни, каждый из которых мог взаимодействовать

только с непосредственно примыкающим к нему уровнем.

Несмотря на неплохие практические результаты такая структура

теперь все больше воспринимается монолитной, поскольку вся

операционная система связана иерархией уровней. Множественность и

нечеткость интерфейсов между уровнями затрудняет модификацию

системы; для этого требуется хорошее знание операционной системы,

масса времени и элемент везения.

В микроядерных архитектурах вертикальное распределение функций

операционной системы заменяется на горизонтальное. Компоненты,

лежащие выше микроядра, используют средства микроядра для обмена

сообщениями, но взаимодействуют непосредственно. Микроядро лишь

проверяет законность сообщений, пересылает их между компонентами

и обеспечивает доступ к аппаратуре.

Это свойство микроядерных систем позволяет естественно

использовать их в распределенных средах. При получении сообщения

микроядро может его обработать или переслать другому процессу.

Поскольку для микроядра безразлично, поступило ли сообщение от

локального или удаленного процесса, подобная схема передачи

сообщений является удобной основой удаленных вызовов процедур



(RPC - remote procedure calls). Однако пересылка сообщений

производится медленнее обычных вызовов функций; оптимизация

пересылки сообщений является критическим фактором успеха

микроядерной операционной системы. Например, в ОС Windows NT в

некоторых случаях для оптимизации используется разделяемая

память. Расходы на дополнительную фиксированную память микроядра

оправдываются повышением эффективности передачи сообщений.

2.2 Переносимость, расширяемость и надежность

Поскольку вся машинно-зависимая часть ОС изолирована в микроядре,

для переноса системы на новый процессор требуется меньше

изменений и эти изменения логически сгруппированы. При имеющемся

разнообразии на рынке процессоров способность операционной

системы работать на разных процессорах является единственной

возможностью убедить пользователей покупать новые машины.

Расширяемость также является необходимым свойством современных

операционных систем. В отличие от аппаратных средств, которые

устаревают за несколько лет, операционные системы могут с пользой

использоваться в течение десятилетий. В жизни каждой операционной

системы настает момент, когда в нее требуется внести функции, не

заложенные в исходную конструкцию. Микроядерная организация

операционных систем позволяет добиться возможности управляемых и

надежно работающих расширений на основе ограниченного набора

четко определенных интерфейсов микроядра.

В действительности, правильнее говорить не только о

расширяемости, но и о масштабируемости микроядерных ОС с

возможностью получения варианта операционной системы, в наилучшей

степени соответствующей особенностям аппаратной платформы и

прикладной области. Микроядерная организация ОС позволяет легко

добиться и этого качества.

Одной из проблем традиционно организованных операционных систем

является наличие множества интерфейсов прикладного

программирования (API - Application Programming Interface), не

все из которых хорошо документированы. В результате невозможно

гарантировать правильность программ, использующих несколько API,



и даже правильность работы самой операционной системы.

Микроядро, обладающее небольшим набором API (микроядро OSF

обеспечивает около 200 системных вызовов, а крохотное микроядро

QNS - всего лишь 14), увеличивает шансы получения качественных

программ. Конечно, этот компактный интерфейс облегчает жизнь

только системных программистов; прикладной программист по

прежнему должен бороться с сотнями вызовов.

2.3 Разделение функций

Основным принципом организации микроядерных ОС является включение

в состав микроядра только тех функций, которым абсолютно

необходимо выполнять в режиме супервизора и в защищенной памяти.

Обычно в микроядро включаются машинно-зависимые программы

(включая поддержку мультипроцессорной работы), некоторые функции

управления процессами, обработка прерываний и поддержка пересылки

сообщений.

Во многих случаях в микроядро включается функция планирования

процессов, но в реализации Mach компании IBM планировщик

процессов размещен вне микроядра, а микроядро используется только

для непосредственного управления процессами. Конечно, при этом

требуется тесное взаимодействие внешнего планировщика и входящего

в состав ядра диспетчера.

В некоторых реализациях (например, в реализации OSF) в микроядро

помещаются драйверы устройств. В реализациях IBM и Chorus

драйверы размещаются вне микроядра, но для регулирования режимов

разрешения и запрещения прерываний часть программы драйвера

выполняется в пространстве ядра. В NT драйверы устройств и другие

функции ввода-вывода выполняются в пространстве ядра, но реально

используют ядро только для перехвата и передачи прерываний.

Следует заметить, что оба подхода допускают динамическое

подключение драйверов к системе и их отключение.

Однако имеются другие доводы в пользу выделения драйверов из

состава микроядра. Например, поскольку во многих случаях драйверы

могут не зависеть от особенностей аппаратуры, такой подход

облегчает переносимость системы.

2.4 Mach и IBM

В разрабатывавшейся компанией IBM ОС Workplace (теперь она



отказалась от завершения этой ОС) использовалось микроядро Mach

3.0, расширенное в кооперации с OSF средствами поддержки

параллельной обработки и реального времени. Микроядро заведовало

функциями взаимодействия процессов, управления виртуальной

памятью, управления процессами и нитями (threads), управления

процессорами (включая мультипроцессорные системы), а также

управления вводом-выводом и обработки прерываний. Файловая

система, планировщик процессов, сетевые службы и система

безопасности вынесены из микроядра. В IBM эти компоненты называют

PNS (personally neutral services), поскольку они используются во

всех эмуляторах операционных систем.

Управление процессами и нитями в Workplace являлись функцией

ядра. Но на самом деле в ядре был расположен только диспетчер

процессов. Планировщик, ведающий приоритетами, определяющий

порядок выполнения и заказывающий диспетчеризацию процессов и

нитей, функционировал вне ядра.

Управление памятью также распределялось между микроядром и PNS.

Ядро управляло аппаратурой страничной памяти. Подсистема

управления страничной памятью, работающая вне ядра, определяла

стратегию замещения страниц. Подобно планировщику эта подсистема

являлась заменяемым компонентом.

На уровне PNS могут располагаться не только такие внутренние

подсистемы как файловая система и драйверы устройств, но и

сетевые службы и даже системы управления базами данных. По мнению

IBM, размещение подобных служб в непосредственной близости от

микроядра позволит повысить их эффективность за счет сокращения

числа вызовов функций и возможно использовать собственные

драйверы устройств.

2.5 Mach и OSF/1

ОС OSF/1 1.3 также основана на микроядре Mach. IBM является

членом OSF, и эти компании обменивались технологиями организации

микроядра. Однако по некоторым важным направлениям подходы IBM и

OSF различаются. В версии 1.3 весь сервер OSF/1 работает в

пользовательском пространстве и использует функции Mach.

Почему же OSF решилась на микроядерную реализацию монолитного



сервера Unix? Как говорят специалисты OSF, OSF/1 является слишком

хорошей и надежной системой, чтобы можно было ее бросить и начать

все сначала. В OSF/1 1.3 используется более 90% кода предыдущих

версий OSF/1. С другой стороны, чтобы улучшить возможности

управления объектами, часть ядра Mach была переписана на Си++.

В результате OSF/1 1.3 получилась не такой модульной, как ОС

Workplace. Но использовав значительную часть OSF/1, компания OSF

смогла раньше IBM получить более или менее полную микроядерную

реализацию систему.

OSF ориентируется на массивно параллельные аппаратные системы.

Активно изучаются вопросы изменения поведения операционной

системы при возрастании числа процессоров. В такой системе

микроядро Mach будет работать на всех процессорах, а сервер OSF/1

потребуется только на некоторых из них.

Как планирует OSF, в будущих версиях OSF/1 на основе Mach будет

поддерживаться возможность размещения сервера OSF/1 в

пространстве ядра или в пользовательском пространстве в

соответствии с выбором системного администратора при

конфигурировании системы. Выполнение сервера OSF/1 в пространстве

ядра позволит повысить производительность, так как вместо

передачи сообщений будут использоваться вызовы процедур, и сервер

всегда будет целиком располагаться в памяти. При выполнении

сервера в пользовательском пространстве будет возможен его

свопинга, что потенциально увеличит память, доступную для

программ пользователя. Заметим, что примерно такой же подход

используется USL в версиях Unix, основанных на микроядре Chorus.

Системные функции будут разработаны и отлажены в пользовательском

пространстве, а потом можно будет перенести в пространство ядра

для достижения наилучшей производительности.

2.6 Можно ли считать NT микроядерной ОС?

Основным назначением микроядра ОС Windows NT является упрощение

переноса системы: все машинно-зависимые программы

сконцентрированы внутри микроядра. Microsoft пока не пытается

вычленить микроядро NT. В частности, поэтому многие полагают, что



NT на самом деле не обладает микроядром ОС, подобным Mach и

Chorus. Отмечается также, что в NT из пространства ядра должным

образом не вынесены функции более высокого уровня (хотя

аналогичные замечания применимы и к OSF/1 и Chorus/MiX) и что

драйверы устройств в NT минимально взаимодействуют с ядром, а

большей частью непосредственно работают с более низким уровнем

абстракции аппаратуры (HAL - Hardware Abstraction layer).

Приложения Windows NT общаются с "подсистемами окружения",

которые работают в режиме пользователя и аналогичны прикладным

средам в ОС Workplace. Эти подсистемы поддерживаются

исполнительной системой NT, которая работает в пространстве ядра

и никогда не откачивается на диск. В состав исполнительной

системы входят менеджер объектов, монитор безопасности, менеджер

процессов и менеджер виртуальной памяти. Исполняющая система, в

свою очередь, основывается на службах нижнего уровня,

предоставляемых ядром (или, если угодно, микроядром) NT. Эти

службы включают планирование процессов и нитей, обработку

прерываний и исключительных ситуаций, синхронизацию процессоров и

восстановление после сбоев системы. Ядро исполняется в

привилегированном режиме и никогда не откачивается из оперативной

памяти. Параллельные верви в ядре возникают только при обработке

прерываний. Ядро основывается над уровнем HAL, в котором

сконцентрирована большая часть аппаратно-зависимых программ.

Специалисты компании Microsoft говорят, что при создании NT

преследовались задачи улучшения производительности и сетевых

возможностей, а также поддержания определенного набора прикладных

сред. Эти задачи отражено в результирующем разделении функций

между ядерными и неядерными модулями. Например, для убыстрения

работы файловой системы и передачи данных в сети в ядре

производится буферизация небольших (от 16 до 32 Кб) порций

считываемых и записываемых данных, которые типичны в приложениях,

работающих в режиме клиент-сервер или распределенном режиме.

Многие другие решения принимались на основе подобных



прагматических соображений. Например, для эмуляции Win32

традиционная иерархия процессов не требуется, но для других

подсистем окружения (например, для OS/2 и Posix) это необходимо.

Исполнительная система NT обеспечивает набор средств управления

процессами, достаточный для текущего набора прикладных сред NT и

для схожих с ними, которые пока не поддерживаются (например,

VMS). Радикально отличающиеся случаи, для реализации которых

может потребоваться модификация исполнительной системы, не

предусматриваются.

Заметим, что хотя менеджеры ресурсов уровня исполнительной

системы расположены в пространстве ядра, они взаимодействуют

путем обмена сообщениями, так же, как и подсистемы

пользовательского уровня. Поэтому исполнительную систему, видимо,

не следует считать монолитом.

ОС Windows NT является объектной, хотя и не полностью

объектно-ориентированной. Системные ресурсы, такие как процессы,

нити и файлы, выделяются и управляются как объекты; каждый тип

объектов обладает набором атрибутов и методов. Видимые

пользователю ресурсы, включая окна, меню и файлы, также основаны

на объектном подходе. Являясь объектами, эти ресурсы могут

именоваться, защищаться и разделяться. В NT различаются объекты

уровня ядра и уровня исполнительной системы. Объекты ядра владеют

нитями, событиями, прерываниями и очередями. Объекты

исполнительной системы, создаваемые и манипулируемые менеджером

ресурсов, обрамляют базовые ресурсы ядра, добавляя к ним,

например, имена и дескрипторы безопасности, и передают их, в свою

очередь, подсистемам пользовательского режима.

Подобно другим микроядрам, ядро NT заведует обработкой прерываний

и переключениями контекста. Прерывание обрабатывается ядром, а

затем переправляется в подпрограмму обработки прерывания (ISR -

interrupts service routine). Для связывания уровня прерывания с

ISR в ядре используется объект прерывания; это позволяет

концептуально отделить драйверы устройств от аппаратуры

прерываний. В этом также различие подсистем ввода-вывода NT и



большинства других микроядер. В Mach и Chorus драйверы устройств

имеют доступ к аппаратуре только через средства ядра. Менеджер

ввода-вывода в NT, который включает файловую систему, драйверы

устройств и сетевую поддержку, обычно работает напрямую с уровнем

HAL, лежащим ниже ядра. Поддержка ядра требуется для обработки

прерываний, но в остальных отношениях драйверы работают

автономно.

В Microsoft утверждают, что имелись существенные основания для

подобной организации интерфейса драйверов устройств. Например,

IBM не смогла реализовать все функции драйверов устройств за

пределами ядра; пришлось находить способ, позволяющий части

драйвера работать в пространстве ядра. Для обработки и пересылки

прерываний в NT устанавливается объектная связь с драйвером

устройства, а затем драйвер может работать непосредственно со

связанным с ним устройством через HAL. Ничто не мешает писать

специализированные драйверы устройств, но они должны быть

отделены от прикладной программы и должны взаимодействовать с

подсистемой ввода-вывода NT.

2.7 AT&T и Chorus

Микроядро Chorus во многих отношениях походит на реализации Mach,

выполненные IBM и OSF. Chorus включает поддержку распределенных

процессоров, нескольких распределенных серверов операционной

системы (во многом похожую на комбинацию Mach-OSF/1), управления

памятью и обработки прерываний. Поддерживается также прозрачное

взаимодействие с другими экземплярами микроядра Chorus, что

делает Chorus хорошей основой для сильно распределенных систем.

Существует несколько реализаций микроядра Chorus. Chorus/MiX,

версия компании Chorus операционной системы с интерфейсами Unix,

включает отдельные версии, совместимые с SVR3.2 и SVR4. USL

собирается объявить Chorus/MiX V.4 микроядерной реализацией SVR4.

USL и Chorus Systems планируют совместную работу по разработке

Chorus/MiX V.4 в качестве будущего направления Unix. Специально

для использования на персональных компьютерах компания Chorus

поддерживает реализацию Chorus/MiX, совместимую с SCO.



Драйверы устройств не включаются в ядро. Аналогично подходу IBM,

драйверы получают доступ к аппаратуре через ядро. Это дает

возможность компоненту более высокого уровня - менеджеру

устройств, отслеживать работу драйверов, функционирующих в разных

узлах распределенной системы.

2.8 Новые микроядерные системы

Операционная системы SpringOS фирмы Sun, которая пока находится в стадии проектирования и разработки, основывается на микроядре и объектах. Вероятно, в SpringOS будет использоваться

значительный объем существующих программ Solaris подобно тому,

как в OSF/1 используется существующий сервер OSF/1. Компания Sun

не объявляла об использовании какого-либо существующего микроядра

и, по-видимому использует собственную разработку.

2.9 Зрелые микроядра

QNX и CTOS - это две зрелые микроядерные операционные системы,

поставляемые на протяжении нескольких лет. 8-килобайтное

микроядро QNX поддерживает только планирование и диспетчеризацию

процессов, взаимодействие процессов, обработку прерываний и

сетевые службы нижнего уровня. Это микроядро обеспечивает всего

лишь 14 системных вызовов. Микроядро QNX может быть целиком

размещено во внутреннем кэше некоторых процессоров, таких как

Intel 486.

Чтобы построить минимальную систему QNX, требуется добавить к

микроядру менеджер процессов, который создает и управляет

процессами и памятью процессов. Чтобы ОС QNX была применима не

только во встроенных и бездисковых системах, нужно добавить

файловую систему и менеджер устройств. Эти менеджеры исполняются

вне пространства ядра, так что ядро остается небольшим. По

утверждениям специалистов компании QNX Software заявляет, что

подобная система, основанная на передаче сообщений, имеет

производительность, по меньшей мере сравнимую с

производительностью других традиционных операционных систем.

CTOS, появившаяся в 1980 году, была написана для рабочих станций

фирмы Convergent Technologies - семейства машин на основе

процессоров Intel для работы в "кластерных сетях", соединенных по

обычным телефонным проводам. Продаваемые в настоящее время фирмой

Unisys, эти основанные на CTOS машины продемонстрировали

преимущества распределенных вычислений на основе передачи

сообщений задолго до того, как этот термин стал модным. Крохотное

4-килобайтное микроядро CTOS взяло на себя только планирование и

диспетчеризацию процессов и взаимодействие процессов на основе

сообщений. Все другие системные службы взаимодействуют с ядром и

друг с другом через четко определенные интерфейсы сообщений.

Сетевые средства входят в состав CTOS и являются действительно

прозрачными для прикладных программ, которым не требуется знать,

будет ли обработан запрос на обслуживание локально или удаленно.

В любом случае сообщения передает одна и та же система

взаимодействия процессов.


Исследовательская инфраструктура


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

Во-первых, CoRR - Computing Research Repository (http://xxx.lan1.gov/archives/cs) и индивидуальные Web-сайты обеспечивают эффективную систему электронных публикаций. Конференциям и журналам следует перестать акцентироваться на бумажных копиях своих трудов -- скорее им нужно представлять Web-сайты для организации предлагаемых статей и обеспечить редакторские комментарии к этим статьям. Мы полагаем изменить схему конференций на "полностью стендовую" или "большей частью стендовую". Многие статьи настолько специальны, что их презентация доступна только для нескольких специалистов, интересующихся данной темой. Эти специалисты могут провести более эффективное групповое обсуждение на стендовой сессии. Время на презентацию следует предоставлять тем авторам, идеи которых не следуют духу "delta-X", а также приглашенным докладчикам, которые обобщают текущие результаты в сформировавшихся областях и новшества в новых областях.

В дополнение к этому, мы полагаем, что для распространения информации лучше всего существенно увеличить число принимаемых статей. Это открыло бы дорогу для более новаторских статей без вытеснения сильных результатов категории delta-X, к которым имеют склонность рецензенты представленных статей.

Последнее и, возможно, наиболее дискуссионное наше предложение относиться к процессу публичного рецензирования. Каждый программный комитет и редакционный совет проводит громадную работу по рецензированию большого объема представляемых статей. Мы хотим каким-то образом добывать и публиковать эту ценную информацию. Как только автор делает документ публично доступным, например, представляя его в CoRR, добровольные рецензенты должны иметь возможность опубликовать свои рецензии в модерируемом форуме. Особенно полезными будут организованные рецензии тематически связанных статей, в которых сравнивается и сопоставляется материал. Мы поддерживаем усилия H.V. Jagadish по изучению этих вопросов и началу формирования такой базы данных рецензий.

[1] Laguna Beach meeting of 1988 [SIGMOD Record 18(1) : 17-26].

[2] Lagunita meetings of 1990 and 1995 [SIGMOD Record 19(4) : 6-22, SIGMOD Record 25(1) : 52-63]

[3] ACM 1996 meeting "Strategic Directions in Database Systems - Breaking Out of the Box", ACM Computing Surveys 28{4} : 764-778



История администрирования БД Oracle


Платформа Oracle не всегда была такой “ навороченной ” . Во времена Oracle V4 администратор БД зачастую оставался лишь разработчиком. Едиственным способом резервирования данных было "холодное" резервирование, то есть копирование всего программного обеспечения БД Oracle и файлов данных только при "выключенной" БД. Выход Oracle V5 и появление SQL*net ознаменовали собой развитие нового подхода клиент-сервер. Кроме того, в Oracle V5 были включены дополнительные средства настойки, такие как explain plan , средства аудита и тому подобное. В помощь администратору БД предоставлялся ряд дополнительных функций, призванных облегчить его работу. Начиная с Oracle V6 стало происходить разделение администраторов по специализациям. Корпорация Oracle выпустила целый пакет приложений; внедрила параллельный сервер; размеры баз данных можно было уже смело охарактеризовать, как очень большие; по этим причинам системой становилось все труднее управлять, что еще более усугубялось наличием ошибок и разрушением данных. Кроме того, в Oracle V6 впервые были введены триггеры и язык PL/SQL, а заинтересованной общественности представлен механизм репликации. Сложность же пакета Oracle V7 достигла небывалых до той поры высот, воплотив понятие целостности ссылочных данных или отношения первичный/внешний ключ на уровне БД. Это позволило упростить написание приложений , однако добавило лишней головной боли администраторам БД. Oracle V8, в свою очередь, познакомил всех с разбиением таблиц и индексов, и массой новых средств индексации. Oracle8i поднял планку еще выше благодаря поддержке файловой системы Интернет, Java-триггеров и т . д.

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



Итак, что же такое реляционная модель?


В предыдущей заметке я отмечал, что, как это не странно, Кодд не определял термин "реляционная модель" до 1979 г. [1] Возможно, еще более странно, что он не определял более общий термин "модель данных" до 1981 г. ! В статье под названием "Модели данных в управлении базами данных" [6] он определяет модель данных как комбинацию трех компонентов:

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

Кстати, замечу, что здесь слово "объект" используется не в современном ограниченном смысле.

Строго говоря, такого рода замечания не слишком осмысленны. Если учесть, что отсутствует точное определение термина объект в "современном ограниченном смысле", то тем более непонятно, что означает этот термин (или это не термин?) в старом добром смысле Кодда. (Примечание С.Кузнецова.)

Далее в статье обсуждается, для достижения каких целей предназначены модели данных в целом и реляционная модель, в частности, и приводятся данные в пользу того, что - в отличие от распространенного представления - реляционная модель была в действительности первой определенной абстрактной моделью данных. (Как мы видели в предыдущей заметке, так называемые иерархическая и сетевая "модели" были определены путем абстрагирования уже существующих реализаций. Хотя интересно заметить, что сам Кодд использует словосочетание "иерархическая и сетевая модели" в двух самых первых статьях, датированных 1969-м и 1970-м годами!)

Но, видимо, возникает вопрос: "Что же в точности представляет собой реляционная модель?". Если внимательно просмотреть серию статей Кодда, то можно заметить, что его собственные определения эволюционизировали с 70-х до начала 80-х гг. (И на самом деле, изменялись.) Одним из последствий этого было то, что критики смогли обвинить самого Кодда и реляционный подход в целом в том, что "створки ворот раздвигаются" слишком сильно.
Например, Майкл Стоунбрейкер написал [7], что " можно видеть четыре разных версии" модели:

Версия 1: Определена в статье в CACM в 1970 г. [8] Версия 2: Определена в статье по поводу Тьюринговской преми в 1981 г. Версия 3: Определена 12-ю правилами Кодда и оценочной системой [9] Версия 4: Определена в книге Кодда [10].

Вероятно, по причине того, что нас немного задела такая критика, мы с Хью Дарвеном постарались привести в Третьем Манифесте свою собственную аккуратную формулировку того, что такое реляционная модель (или чем она должна быть!). Действительно, мы хотели, чтобы Манифест отчасти рассматривался бы как такая определительная формулировка. За подробностями следует обращаться к самой книге; здесь же хотелось бы только сказать, что мы видим свой вклад в этой области прежде всего как расстановку всех точек над i и черточек на t, которые не были расставлены должным образом в работах Кодда. Мы не нисколько не отклонились от видения Кодда в каких-либо существенных аспектах; весь Манифест в очень большой степени следует духу идей Кодда и развивает основанное им направление.


«Избежал ли ловушки» Кодд?


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

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

Как мы видим, в [1] также утверждается, что Кодд «избегает ловушки» требования вычислительной полноты и за счет этого не сталкивается с проблемой неразрешимости. В [1] ничего не говорится явно о том, как можно избежать этой ловушки, но приводятся намеки на то, что для этого нужно провести четкую границу между частями языка, которые имеют отношение к работе с базой данных и вычислениями:

Мое пожелание состоит в том, чтобы явно разделить в Tutorial D теоретико-множественную семантику и семантику вычислительного языка … Следует переформулировать ОО-предписание 3, чтобы сказать, что подъязык приложений языка D должен быть вычислительно полным и полностью процедурным, а подъязык баз данных языка D должен быть не вычислительно полным, должен быть полностью непроцедурным и должен быть разрешимым (хотя мне не очень понятно, как эти подъязыки могут взаимодействовать) … [Еще одна попытка, позже:] Разделите D на RD (реляционную, непроцедурную часть) и CD (вычислительную, процедурную часть).
Тогда ОО-предписание 3 следует переформулировать так, чтобы сказать, что RD должен быть не вычислительно полным, и в нем не должна обеспечиваться возможность вызова какой-либо операции, которую невозможно реализовать средствами RD … Реляционный язык баз данных RD должен быть разрешимым. Следовательно, он не должен быть вычислительно полным, и в нем не должна поддерживаться возможность вызова какой-либо процедуры, которую в принципе невозможно реализовать средствами RD.

Но следуют ли этим ограничениями предложения языка самого Кодда? Нет! Рассмотрим следующие выдержки из собственных статей Кодда: Из самой первой (1969 г.) статьи про реляционную модель [2]: Пусть подъязык выборки называется R и основной язык – H … R обеспечивает возможность спецификации выборки любого поднабора данных из банка данных … Класс ограничительных выражений, которое могут использоваться в спецификации набора, находится в точно определенном … соответствии с классом правильно построенных формул исчисления предикатов … Любая требуемая арифметическая функция может определяться с использованием языка H и вызываться из конструкций языка R [курсив добавлен].

Из пересмотренного варианта статьи, опубликованного в 1970 г. в Communications of the ACM [3]: Пусть подъязык выборки называется R и основной язык – H … R обеспечивает возможность спецификации выборки любого поднабора данных из банка данных … Класс ограничительных выражений, которое могут использоваться в спецификации набора, должен обладать описательной мощностью класса правильно построенных формул прикладного исчисления предикатов … В условных или других частях операторов выборки могут потребоваться арифметические функции. Такие функции могут определяться на языке H и вызываться из конструкций языка R [курсив добавлен].

И в статье, посвященной подъязыку данных ALPHA [4], говорится следующее: Все вычислительные функции определяются с помощью операторов основного языка; все операции выборки и сохранения – с помощью операторов подъязыка данных.


Однако в операторе подъязыка данных может содержаться вызов функции, определенной с помощью операторов основного языка … Расширяемая библиотека функций, которые могут вызываться из запросов, обеспечивает средства расширения возможностей выборки DSL [Data SubLanguage] ALPHA.

В этой статье далее приводится несколько примеров использования таких функций как в разделе «целевого списка», так и в разделе «условия» запросов. Так что я бы сказал, что во всех трех статьях [2-4] Кодд не только «не избегал ловушки» – очевидно, что он даже и задумывался о наличии ловушки, которую нужно стараться избегать.

Замечание: Комментируя ранний вариант настоящей статьи, автор [1] утверждал, что разделение Коддом языков R и H было достаточным для того, чтобы «избежать ловушки». В частности, он утверждал, что (a) одним из эффектов такого разделения являлось то, что к вызову из языка R функции, определенной средствами языка H, можно было относиться с точки зрения языка R как к константе, и (b) что ловушки удалось избежать, потому что в функциях, определенных на языке H, отсутствовал доступ к переменным, определенным на языке R. После размышлений я пришел к выводу, что не понимаю эти утверждения. В частности, в функциях, используемых Коддом в примерах в [4], очень часто производится доступ к переменным, «определенным на языке R», – в число этих функций входят аналоги всем знакомых агрегатных операций COUNT, SUM, AVG, MAX и MIN, которые, конечно, явно определяются для работы с отношениями. (Если речь идет о том, что эти функции могут только читать свои операнды и не могут изменять их, то это верно и для Tutorial D, так что, по-видимому, имеется в виду не это.)

Отклоняясь от темы, я хотел бы добавить, что по причинам, которые мне не хотелось бы здесь объяснять, я никогда не относился к числу поклонников идеи подъязыка данных (частично по этой причине появилось ОО-предписание 3 Манифеста). Как я писал в [7], Я никогда не был убежден в том, что выделение доступа к данным в отдельный «подъязык» является хорошей идеей, [хотя] она присутствует в нашей практике в течение довольно долгого времени в форме встраиваемого SQL.Кстати, в связи с этим интересно заметить, что после добавления в стандарт SQL в 1996 г. механизма PSM («Persistent Stored Modules») сам SQL стал теперь вычислительно полным языком – что означает отсутствие дальнейшей потребности в основном языке (при использовании SQL).


В этом разделе мы опишем


В этом разделе мы опишем некоторые черты языка SQL/89, сопровождая описание соображениями о целесообразности и/или способе использования тех или иных конструкций при программировании потенциально мобильных прикладных систем.


Язык описания интерфейсов.


Язык описания интерфейсов (IDL), используемый OMG определяет типы объектов посредством спецификации их интерфейсов. Интерфейс состоит из множества именованных операций и их параметров. Хотя и описание на IDL обеспечивает ORB всей необходимой информацией о типе объекта, для работы вовсе необязательно, чтобы ORB-у был доступен исходный текст этих описаний. Эта же информация может быть заложена также в виде заглушек со стороны клиента и скелета со стороны сервера, а также в динамически изменяемом хранилище описаний, что позволит ORB-у нормально функционировать.

Язык описания интерфейсов рассматривается как средство, с помощью которого реализация объекта сообщает своим потенциальным клиентам о том, какие операции доступны и каким образом их следует вызывать. Можно оттранслировать описание на языке IDL в исходный код на конкретном языке программирования.



Язык реляционных баз данных SQL и его стандарты


Сергей Кузнецов

Одним из основных преимуществ реляционного подхода к

организации баз данных (БД) является то, что пользователи

реляционных БД получают возможность эффективной работы в

терминах простых и наглядных понятий таблиц, их строк и столбцов

без потребности знания реальной организации данных во внешней

памяти.

Реляционная модель данных, содержащая набор четких предписаний к

базовой организации любой реляционной системы управления базами

данных (СУБД), позволяет пользователям работать в ненавигационной

манере, т.е. для выборки информации из БД человек должен всего

лишь указать список интересующих его таблиц и те условия, которым

должны удовлетворять выбираемые данные. СУБД скрывает от

пользователя выполняемые ей последовательные просмотры таблиц,

выполняя их наиболее эффективным образом. Очень важная

особенность реляционных систем состоит в том, что результатом

выполнения любого запроса к таблицам БД является также таблица,

которую можно сохранить в БД и/или по отношению к которой можно

выполнять новые запросы.

Базовым требованием к реляционным СУБД является наличие мощного и

в тоже время простого языка, позволяющего выполнять все

необходимые пользователям операции. В последние годы таким

повсеместно принятым языком стал язык реляционных БД SQL -

Structured Query Language (теперь все чаще название языка

понимается как Standard Query Language).

До появления SQL в СУБД (независимо от того, на какой модели они

основывались) приходилось поддерживать по крайней мере три языка,

которые обычно имели мало общего: язык определения данных (ЯОД),

служащий для спецификации структур БД (обычно общую структуру БД

называют схемой БД); язык манипулирования данными (ЯМД),

позволяющий создавать прикладные программы, взаимодействующие с

БД; и язык администрирования БД (ЯАДБ), с помощью которого можно

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

БД или производить ее настройку с целью повышения эффективности).

Кроме того, если требовалось предоставить пользователям СУБД


интерактивный доступ к БД, приходилось вводить еще один язык,

операторы которого выполняются в диалоговом режиме. Язык SQL

позволяет решать все эти задачи.

Следует отметить, что к достоинствам языка SQL относится наличие

международных стандартов. Первый международный стандарт был

принят в 1989 г., и соответствующая версия языка называется

SQL-89. Этот стандарт полностью поддерживается практически во

всех современных коммерческих реляционных СУБД (например, в

Informix, Sybase, Ingres, DB2 и т.д.). Стандарт SQL-89 во многих

частях имеет чрезвычайно общий характер и допускает очень широкое

толкование. В этом стандарте полностью отсутствуют такие важные

разделы, как манипулирование схемой БД и динамический SQL. Многие

важные аспекты языка в соответствии со стандартом определяются в

реализации.

Возможно, наиболее важными достижениями стандарта SQL-89 являются

четкая стандартизация синтаксиса и семантики операторов выборки и

манипулирования данными и фиксация средств ограничения

целостности БД, включающих возможности определения первичного и

внешних ключей отношений и так называемых проверочных ограничений

целостности, позволяющих сформулировать условие для каждой

отдельной строки таблицы. Средства определения внешних ключей

позволяют легко формулировать требования так называемой

целостности БД по ссылкам. Формулировка ограничений целостности

на основе понятия внешнего ключа проста и понятна.

Осознавая неполноту стандарта SQL-89, на фоне завершения разработки

этого стандарта специалисты различных фирм начали работу над

стандартом SQL2. Эта работа также длилась несколько лет, было

выпущено 4нескольк 0о проектов стандарта, пока, наконец, в марте

1992 г. не был выработан окончательный проект стандарта (после

чего стандарт и соответствующий язык стали называть SQL-92). Этот

стандарт существенно более полный и охватывает практически все

необходимые для реализации аспекты: манипулирование схемой БД,

управление транзакциями и сессиями (сессия - это



последовательность транзакций, в пределах которой сохраняются

временные отношения), подключение к БД, динамический SQL. Наконец

стандартизованы отношения-каталоги БД, что вообще-то не связано с

языком непосредственно, но очень сильно влияет на реализацию.

Заметим, что в стандарте представлены три уровня языка - базовый,

промежуточный и полный. В течение нескольких лет после принятия

стандарта производители СУБД, утверждавшие совместимость своих

продуктов со стандартом, на самом деле в лучшем случае

поддерживали промежуточный уровень языка SQL-92 (естественно, с

собственными расширениями). Только в последних выпусках СУБД

ведущих производителей обеспечивается совместимость с полным

вариантом языка.

Наконец, одновременно с завершением работ по определению

стандарта SQL-92 была начата разработка стандарта SQL3. Общей

точкой зрения ведущих производителей СУБД является то, что

будущие продукты, обладая более развитыми возможностями, должны

быть совместимы с предыдущими выпусками. Хотя многие разработчики

и пользователи реляционных СУБД осознают наличие многих

неустранимых недостатков языка SQL, от него теперь уже невозможно

отказаться (как невозможно отказаться от использования языка Си в

процедурном программировании). Следовательно, нужен новый

стандарт языка, обеспечивающий такие очевидно необходимые

возможности как определяемые пользователями типы данных, более

развитые средства определения таблиц, наличие полного механизма

триггеров и т.д. Нужен именно стандарт, а не наличие развитых

частных версий языка, поскольку это выгодно и производителям и

пользователям СУБД. Почему же так затянулась его разработка?

Мне кажется, здесь сказываются несколько факторов. Во-первых,

объектные расширения языка выходят за пределы реляционной модели

данных, т.е. они лишаются классической теоретической базы.

Во-вторых, уже стандарт SQL-92 был очень объемным, а чем больше

язык, тем сложнее его развивать (вспомните, как долго готовился

стандарт языка Ада).Наконец, маркетинговая политика

компаний-производителей СУБД (как и других компаний) состоит в

том, чтобы убедить потенциальных покупателей в наличии уникальных

возможностей своего продукта. Поэтому они не могут ждать принятия

нового стандарта и вынуждены использовать частные расширения

языка. В целом ситуация несколько парадоксальна: появление нового

стандарта в основном зависит от специалистов ведущих компаний,

которые являются членами комитета SQL3, а текущая деятельность

компаний затрудняет работу этого комитета.

Тем не менее, я верю, что стандарт SQL3 рано или поздно появится

и будет реализован во всех развитых СУБД. Это выгодно всем.


Языки программирования объектно-ориентированных баз данных и оптимизация запросов


Сергей Кузнецов

Введение

Объектно-ориентированные (ОО) системы управления данными

привлекают все большее внимание как исследователей и

разработчиков, так и потенциальных пользователей из прикладных

областей. С одной стороны это объясняется развитием и внедрением

в практику объектно-ориентированного подхода (ООП) в целом (ОО

программирование и проектирование программных систем, ОО

технологии организации пользовательских интерфейсов,

распределенные объектные системы и т.д.). Но с другой стороны,

интуитивно ясно, что максимальный эффект можно получить именно от

использования ОО баз данных, преодолев, наконец, известный

конфликт между структурной и поведенческой частями информационных

систем.

Вместе с тем, несмотря на существование ряда коммерческих

реализаций ООСУБД, доступных в настоящее время на рынке, уровень

технологии таких систем существенно уступает уровню развитых

реляционных систем. Это касается и модельных характеристик систем

(например, языков запросов) и реализационных аспектов (например,

оптимизации запросов).

Часто возникает впечатление, что хотя ограничения существующих

систем пытаются объяснять некими принципиальными соображениями

(например, что развитые возможности конструирования классов,

подкрепленные средствами наследования классов позволяют

ограничиться запросами только на одном классе объектов), на самом

деле эти ограничения являются следствием недостаточно развитой

технологии. Кажется, что в условиях отсутствия признанного лидера

в области ООСУБД (каким была, например, компания IBM со своим

проектом System R в области РСУБД), единственным путем к

выработке такой технологии является продолжающаяся (иногда

дублирующая) работа исследователей.

В предыдущих работах мы стремились к тому, чтобы показать

принципиальную возможность построения ненавигационного языка

запросов к ООБД на основе усиления теоретико-множественного

смысла понятия класс и предложить общую концепцию языка

программирования ООБД, который естественно (без потери импеданса)


включает в себя язык запросов . В этих работах не содержались

какие- либо детальные технические проработки, изложение велось на

идейном уровне.

Продолжая действовать в том же стиле и неявно предполагая уже

существующими язык запросов и язык программирования ООБД с

желаемыми свойствами, в этой статье мы исследуем возможности

оптимизации запросов к ООБД. Это очень важная тема, потому что

если удастся обеспечить очень мощный язык запросов, но по причине

отсутствия оптимизации его реализация будет неэффективной, то

наличие такого языка будет в известной степени бессмысленным. С

другой стороны, даже эскиз возможных способов оптимизации (если

они не будут подвергнуты серьезной критике) дает основания

заняться более детальной технической проработкой.

Статья организована по следующему плану. В первом разделе

рассматриваются две основные функции языка программирования ООБД

- обеспечение возможности разработки приложений и определение

схемы ООБД (типов и классов, включая определение методов

объектов). С точки зрения оптимизации запросов в этой статье нас

в большей степени интересует вторая функция. Во втором разделе мы

уточняем, о каком языке запросов к ООБД идет речь.

Подчеркивается, что ненавигационная природа языка запросов не

только не противоречит объектно-ориентированной сущности БД, но

напротив, существенно увеличивает мощность системы. В третьем

разделе во введенном к этому моменту контексте анализируются

возможные подходы к оптимизации запросов. Основную проблему

представляет инкапсулированность объектов ООБД. Поэтому

возможности оптимизации в основном определяются доступностью тел

методов объектов во время компиляции запроса. Наконец, в

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

1. Две функции языка программирования ООБД

Конечно, наиболее важной функцией языка программирования ООБД

должно быть обеспечение удобных и естественных для ООП средств

разработки прикладных информационных систем . Такие программы

работает во внешнем типовом (схемном) окружении ООБД,



манипулируют с объектами ООБД (возможно, с помощью языка

запросов) и непосредственно используют выбранные из базы данных

объекты путем процедурного вызова методов.

Естественно, что язык программирования ООБД сам должен быть

объектно-ориентированным. Следовательно, в нем должны содержаться

средства определения типов и классов с желательной поддержкой

наследования. Но типы и классы, определяемые в прикладной

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

ООБД. Поэтому вполне закономерно нагрузить язык программирования

ООБД и функцией определения схемы ООБД, т.е. набора типов и

классов, которые впоследствии станут внешней средой прикладных

программ.

При выполнении этой второй функции процедурная часть языка

программирования ООБД служит для определения методов объектов. С

точки зрения прикладного программиста методы могут

рассматриваться как "внешние" атрибуты объекта (в отличие от его

"внутренних" атрибутов, содержащихся в переменных состояния

объекта). Другими словами, в терминах, более привычных для

области баз данных, набор методов объекта в некотором смысле

представляет определенное в реализации представление (view)

объекта.

Заметим, что хотя во многих практически используемых языках ОО

программирования (например, в Си++) допускается прямой доступ к

переменным состояния объекта, если эти переменные соответствующим

образом специфицированы, с точки зрения программиста (ООБД или

приложения) полная инкапсуляция объекта (т.е. доступ к переменным

состояния только через методы объекта) является более

естественной и удобной.

Языки программирования ООБД обеспечивают (или, по крайней мере,

должны обеспечивать) унифицированный стиль программирования ООБД

и приложений. Основная разница состоит в том, что приложение

работает в среде ООБД (и программируется в среде схемы ООБД).

Приложение должно иметь возможность выбирать объекты ООБД. Для

обеспечения мощных и удобных средств прикладного программирования

язык программирования ООБД должен быть более или менее тесно (и



естественно) интегрирован с языком запросов к ООБД.

2. Общее представление языка запросов ООБД

В наиболее общем смысле язык запросов ООБД должен позволять

производить новые классы объектов на основе существующих в ООБД

классов и заданных условий выборки. Место нового класса в

иерархии классов ООБД и его тип должны определяться на основе

существующих классов при интерпретации (или компиляции) запроса.

Существует мнение, что на практике языки запросов к ООБД

требуются только в интерактивном режиме, а для приложений

достаточна явная навигация в существующих классах объектов .

По нашему мнению, эта идея является неправильной. Она следует не

из каких-либо теоретически обоснованных соображений, а лишь

упрощает реализацию. Такой подход ограничивает программиста

приложений и часто заставляет его включать в прикладную программу

функции, свойственные языкам запросов. Это не только вызывает

избыточное программирование, но и снижает эффективность

программы.

Фактически, ограничение возможностей выполнения запросов к ООБД

из прикладной программы является шагом назад по отношению к

реляционным системам. Конечно, языки запросов реляционных БД не

очень естественно сопрягаются с языками программирования.

Конечно, программа на языке Си со встроенными операторами SQL

выглядит несколько кустарно. Но тем не менее, имеется эффективный

способ использования SQL из прикладной программы. На наш взгляд,

эту возможность нельзя терять в новом поколении СУБД, особенно,

если учитывать потенциальную возможность интеграции языка

программирования и языка запросов ООБД без потери импеданса .

3. Оптимизация запросов в системах ООБД

Как обычно, основной целью оптимизации запроса в системе ООБД

является создание оптимального плана выполнения запроса с

использованием примитивов доступа к внешней памяти ООБД.

Оптимизация запросов хорошо исследована и разработана в контексте

реляционных БД . Известны методы синтаксической и

семантической оптимизации на уровне непроцедурного представления



запроса, алгоритмы выполнения элементарных реляционных операций,

методы оценок стоимости планов запросов.

Конечно, объекты могут иметь существенно более сложную структуру,

чем кортежи плоских отношений, но не это различие является

наиболее важным. Основная сложность оптимизации запросов к ООБД

следует из того, что в этом случае условия выборки формулируются

в терминах "внешних" атрибутов объектов (методов), а для реальной

оптимизации (т.е. для выработки оптимального плана) требуются

условия, определенные на "внутренних" атрибутах (переменных

состояния).

На самом деле, похожая ситуация существует и в РСУБД, при

оптимизации запроса над представлением БД. В этом случае условия

также формулируются в терминах внешних атрибутов (атрибутов

представления), и в целях оптимизации запроса эти условия должны

быть преобразованы в условия, определенные на атрибутах хранимых

отношений. Хорошо известным методом такой "предоптимизации"

является подстановка представлений , которая часто (хотя и не

всегда в случае использования языка SQL) обеспечивает требуемые

преобразования. Альтернативным способом выполнения запроса на

представлением (иногда единственным возможным) является

материализация представления.

В системах ООБД ситуация существенно усложняется двумя

обстоятельствами. Во-первых, методы обычно программируются на

некотором процедурном языке программирования и могут иметь

параметры. Т.е. в общем случае тело метода представляет из себя

не просто арифметическое выражение, как в случае определения

атрибутов представления, а параметризованную программу,

включающую ветвления, вызовы функций и методов других объектов.

Вторая сложность связана с возможным и распространенным в ООП

позднем связывании: точная реализация метода и даже структура

объекта может быть неизвестна во время компиляции запроса.

Одним из подходов к упрощению проблемы является открытие

видимости некоторых (наиболее важных для оптимизации) внутренних

атрибутов объектов .


В этом контексте достаточно было бы

открыть видимость только для компилятора запросов, т.е.

фактически запретить переопределять такие переменные в

подклассах. С точки зрения пользователя такие атрибуты выглядели

бы как методы без параметров, возвращающие значение

соответствующего типа. С нашей точки зрения, лучше было бы

сохранить строгую инкапсуляцию объектов (чтобы избавить

приложение от критической зависимости от реализации) и обеспечить

возможности тщательного проектирования схемы ООБД с учетом

потребностей оптимизации запросов.

Общий подход к предоптимизации условия выборки для одного

(супер)класса объектов может быть следующим (мы предполагаем, что

условия формулируются с использованием логики предикатов первого

порядка без кванторов; в предикатах могут использоваться методы

соответствующего класса, константы и операции сравнения):

Шаг А: Преобразовать логическую формулу условия к конъюнктивной нормальной форме (КНФ). Мы не останавливаемся на способе

выбора конкретной КНФ, но естественно, должна быть выбрана "хорошая" КНФ (например, содержащая максимальное число атомарных

конъюнктов).

Шаг B: Для каждого конъюнкта, включающего методы только с

известной во время компиляции телом, заменить вызовы методов на

их тела с подставленными параметрами. (Для простоты будем

предполагать, что параметры не содержат вызовов функций или

методов других объектов.)

Шаг C: Для каждого такого конъюнкта произвести все возможные

упрощения, т.е. вычислить все, что можно вычислить в статике.

Хотя в общем виде эта задача является очень сложной, при разумном

проектировании ООБД в число методов должны будут войти методы с

предельно простой реализацией, задавать условия на которых будет

очень естественно. Такие условия будут упрощаться очень

эффективно.

Шаг D: Если теперь появились конъюнкты, представляющие собой

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

констант, использовать эти конъюнкты для выработки оптимального

плана выполнения запроса.


Если же такие конъюнкты получить не

удалось, единственным способом "отфильтровать" (супер)класс

объектов является его последовательный просмотр с полным

вычислением (возможно упрощенного) логического выражения для

каждого объекта.

Понятно, что возможности оптимизации будут зависеть от

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

программирования методов, от особенностей конкретного языка

запросов и от того, насколько продуманно спроектирована схема

ООБД. В частности, желательно, чтобы используемый язык

программирования стимулировал максимально дисциплинированный

стиль программирования методов объектов. Язык запросов должен

разумно ограничивать возможности пользователей (в частности, в

отношение параметров методов, участвующих в условиях запросов).

Наконец, в классах схемы ООБД должны содержаться простые методы,

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

состояния, которые служат основой для организации методов

доступа.

Заметим, что указанные ограничения не влекут зависимости

прикладной программы от особенностей реализации ООБД, поскольку

объекты остаются полностью инкапсулированными. Использование в

условиях запросов простых методов должно стимулироваться не

требованиями реализации, а семантикой объектов.

Заключение

На наш взгляд, в ООП имеется ряд принципиальных аспектов,

отходить от которых нельзя независимо от конкретной области

применения подхода. В частности, в число этих аспектов входит

принципы инкапсулированности объектов и наследования классов

(и/или типов). Они должны поддерживаться и в ООБД.

С другой стороны, в области баз данных также имеются

установившиеся принципиальные решения, к числу которых относится,

например, наличие ненавигационного языка запросов и возможность

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

возможности должны поддерживаться и в ООСУБД.

Наличие непроцедурного языка запросов предполагает реализацию в

компиляторе запросов развитого механизма оптимизации.


Однако

существенное увеличение сложности ООБД по сравнению с

реляционными базами данных не позволяет решить задачу оптимизации

запросов в общем виде. Мы полагаем, что допустимы ограничения, не

влияющие на принципиальные решения.

В этой статье мы привели только набросок возможной схемы

предоптимизации запросов к ООБД. Это достаточно грубая схема, не

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

конкретизировав язык программирования и язык запросов ООБД.

Литература

Malkolm Atkinson, Francois Bansilhon, David DeWitt, Klaus

Dittrich, David Maier, Stanley Zdonik. The Object-Oriented

Database System Manifesto // 1st Int. Conf. Deductive and

Object-Oriented Databases, Kyoto, Japan, Dec. 4-6, 1989

Kyung-Chang Kim, Won Kim, Darrell Woelk. Acyclic Query

Processing in Object-Oriented Databases // Entity-Relationship

Approach: Bridge User: 7th Int. Conf., Rome, Nov. 16-18, 1988.-

329-346

B. Paul Jenq, Darrell Woelk, Won Kim, Wan-Lik Lee. Query

Processing in Distributed ORION // Advances in Database

Technology - EDBT'90.- Lecture Notes in Computer Science.- 416,

1990.- 169-187

C. Lecluse, P. Richard. The O2 Database Programming Language

// 15th Int. Conf. Very Large Data Bases, Amsterdam, Aug. 22-25,

1989.- 411-422

O. Deux et al. The Story of O2 // IEEE Trans. Knowledge and

Data Eng.- 2, N 1.- 1990.- 91-108

Sergei D. Kuznetsov. OODBMS's Query and Programming Languages:

What Do They Provide and What Do We Need (Extended Abstract).

Submitted to the Second East-West Workshop on Advanced Databases.

С.Д.Кузнецов. Об основаниях ненавигационных языков запросов

систем объектно-ориентированных баз данных // Труды Рабочего

семинара "Перспективы развития систем баз данных и информационных

систем", М., Московская секция ACM SIGMOD, ИПИ РАН, 1993, стр.

44-53

С.Д.Кузнецов. О подходе к естественной интеграции

объектно-ориентированного языка программирования и непроцедурного

языка запросов к объектно-ориентированным базам данных.

Представлено на Семинаре Киевской секции ACM SIGMOD, октябрь

1993.

С.Д.Кузнецов. Методы оптимизации выполнения запросов в

реляционных СУБД // Тем. изд. "Итоги науки и техники.

Вычислительные науки". Т.1. Стр. 76-153

Stonebraker M. Implementation of Integrity Constraints and

Views by Query Modification // Proc. ACM SIGMOD Int. Conf. Manag.

Data, San Jose, Calif., May 23-26, 1975. New York, 1975.- C.

65-78


Языковая конструкция


Тот факт, что R*O - система полностью описывается ее проекциями (реляционной и объектной), позволяет предположить, что язык используемый для описания системы должен объединять конструкции языка реляционных БД (например SQL) и O-языка (например Java или С++). Например следующая конструкция

CREATE TABLE ADDR { ... }; class Client { ... ADDR postaddress; ... };

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

Подобный подход может представлять интерес, поскольку подразумевает неизменность исходных языковых конструкций и, вместе с тем, придает им новые возможности. В принципе, можно использовать языковые конструкции любых О- и R- языков. Отметим, что в данном случае SQL не является встроенным языком и, соответственно, О-язык не является базовым языком. Скорее О-язык можно рассматривать как расширение DDL SQL позволяющее объединить отдельные записи в виде сложных объектов.



Виталий Чужа, Microsoft Certified Professional,


Виталий Чужа, Microsoft Certified Professional,

Для успешного выполнения задач, связанных с администрированием MS SQL Server 2000, можно использовать электронную почту, но для этого потребуются службы SQL Server Agent и MSSQLServer. О том, каким же образом настроить и применить в работе эти службы, и пойдет речь в данной статье



Это больше, чем HTML


HTML - это язык, используемый для создания Web-страниц и основанный на предопределенном наборе "тегов", показывающих читающему текст программному обеспечению ("браузеру"), как представлять содержимое страницы. Подобно HTML, XML представляет собой систему тегов, описывающих компоненты документа. В наиболее простой инкарнации можно представлять XML как развитый вариант HTML. В действительности это не так: XML и HTML являются подмножествами того, что называется стандартным обобщенным языком разметки (Standard Generalized Markup Language - SGML). SGML - это сложный теговый язык, который, как тактично намекает OMG (Object Management Group, www.omg.org), "по причине [своей] сложности и сложности требуемых инструментальных средств не получил широкого распространия" (XML Metadata Interchange (XMI) Proposal to the OMG OA&DFT RFP3: Stream-based Model Interchange Format).

Как уже отмечалось, HTML состоит из набора предопределенных "тегов", заставляющих браузер выполнять над документом определенные действия. Обычно эти теги описывают аспекты представления, такие как стили и размеры фонтов, размещение строк и т.д. Однако некоторые теги также идентифицируют ссылки на другие страницы, рисунки и графику. Идея состоит в том, что любой браузер в Internet знает, как интерпретировать эти теги и что с ними делать. Однако, поскольку эти теги прежде всего предназначены для представления данных, невозможно использовать их для описания структуры данных или описания содержимого документа каким-либо другим образом.

В отличие от этого, XML дает пользователям возможность определять теги, предоставляя огромные возможности для описания структуры и природы информации, представленной документом. Однако это означает, что стандартные браузеры не смогут ничего сделать с этими расширениями. Поэтому создание программного обеспечения для XML является гораздо более сложным делом.



Качественные атрибуты объектов.


Значение атрибута объекта как значение отношения.

Как мы уже отмечали, атрибуты объектов могут представлять собой группу повторения и этим отличаются от атрибутов отношений, значения которых должны быть атомарными. Здесь понятие "группа повторения" берется в самом широком смысле, т.е. речь идет о множестве значений одинакового типа. В модели "объект-качество" это отличие приобретает строгий характер.

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

Надо заметить, что значение качества и значение качественного атрибута объекта - это не одно и тоже, даже когда речь идет об одном и том же качестве (типе) Q. Значение качества - это кортеж отношения (скалярное значение качественного типа Q). Значение же качественного атрибута - это множество таких кортежей и его можно рассматривать как значение отношения Q. Однако источником этих значений (значения качества и значения отношения, являющегося атрибутами объекта) является одно и тоже множество Q. Домен Q, на котором определено значение качества, есть ни что иное, как отношение, переменной которого является атрибут объекта.

Теперь можно сказать о важнейшем отличии между традиционными реляционными системами и подходом, предлагаемым моделью "объект-качество". В традиционных реляционных системах отсутствует разницы между понятиями "отношение" и "переменная отношения". Например, Дейт, определяя понятие "отношение", говорит, что "отношение - это не очень точный термин; более точным является термин переменная отношения".
Судя по этому можно сказать, что Дейт имеет в виду, что каждому отношению соответствует только одна и только одна переменная отношения, и любое отношение в каждый момент времени может иметь одно и только одно значение.

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

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

совокупности изменяющихся во времени табличных отношений, основными свойствами которых являются ключи и домены; правил вставки-обновления-удаления (соблюдение ограничений по первичным и внешним ключам); реляционной алгебры состоящей из набора реляционных операторов.

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

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


Качество как отношение.


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

Качества описываются и сравниваются только путем явного задания и прямого сравнений значений и никаким иным способом (этот положение является основным, а последующие пункты - это необходимые условиями, позволяющими выполнить его). Одинаковые значения одного и того же качества, никак не отличаются друг от друга и, фактически, являются одним и тем же значением. Структура любого качества является строго единообразной (здесь имеется в виду единообразие структуры в каждый момент времени). Конечно, структура качества может быть изменена, но это должно быть сделано единовременно для всех значений и переменных данного качества. Важное добавление: качество не наследуется - это бессмысленно, поскольку подразумевает изменение структуры.

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

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

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

int

Value
...
-2
-1
0
1
2
...
Модель "объект-качество" подразумевает, что точно так же в качестве базового типа в объектных системах можно использовать отношение с арностью большей, чем 1.


Качество (концепция).


На последний вопрос мы можем найти ответ в философии. Надо отметить, что между моделированием данных и философией имеется прямая связь - информация есть результат познания, а вопросами познания занимается именно философия. Важным для нас будет утверждение, которое фактически является философской аксиомой - процесс познания есть процесс взаимодействия. Вещи окружающего мира познаются только в их взаимодействии с другими вещами, будь то органы чувств, измерительные инструменты или какие-либо другие объекты реального мира. Следствием этого является очень важное высказывание - вся информация описывающая вещь является информацией о возможных взаимодействиях между этой вещью и другими вещами. Например, если существует информация о весе некоторого автомобиля, то это значит, что этот автомобиль будет притягиваться к земле и давить на основание; если человек имеет адрес - ему можно послать письмо; если стена имеет цвет - следовательно, она поглощает солнечный цвет в определенной части солнечного спектра и мы можем ее видеть. Это перечисление можно продолжать, поскольку число возможных способов взаимодействий между вещами неизвестно и, возможно, бесконечно.

В статье "Представление сложных идентифицируемых объектов в реляционных базах данных" я попытался ввести термин "сущность", который определяется как "информацию являющейся достаточной для установления определенной связи". К сожалению, использование слов "сущность" и "связь" может вызвать путаницу у русскоязычных читателей. Дело в том, что эти слова уже используется в сфере моделирования данных. Я имею в виду модель "сущность-связь" Чена, где в это слово вкладывается иной (абсолютно иной!) смысл. В русском языке слово "сущность" имеет несколько значений и, соответственно, может быть переведено на английский по-разному. Чен использует слово "entity", что означает "нечто существующее" и близко по смыслу к слову "объект" или "вещь".
В упомянутой статье термин "сущность" имеет смысл " существенная характеристика, позволяющая описать вещь с определенной точки зрения". В этом случае слово "сущность" может быть переведено на английский как "essence" и близко по смыслу слову "качество". Поэтому в дальнейшем будет употребляться именно этот термин - "качество". .Ему можно дать следующее определение: качество - это абстракция определяющее и описывающая способность вещей к определенному взаимодействию. Информация о вещи есть информация о её качествах.

Важно понимать, что качество описывает не сам факт взаимодействия (связь) и уж тем более не вещи, с которыми описываемая вещь взаимодействует. Например, качество "вес" вовсе не значит, что описываемая вещь давит на что-то, но не вызывает сомнения то, что она способна давить. Точно так же качество "цвет" не значит, что на описываемую вещь в данный момент кто-то смотрит, однако на нее можно посмотреть. Аналогично, качество "адрес" не значит, что по этому адресу уже послано письмо, но именно оно определяет возможность этого действия. Когда мы говорим, что вещь обладает некоторым качеством, это значит, что она обладает способностью взаимодействовать с другими объектами вполне определенным образом.

Качество является абстракцией, позволяющей описать вещь не описывая её реальное строение. Для примера рассмотрим тот же самый автомобиль. Фактически он представляет собой совокупность узлов, которые состоят из деталей, в свою очередь состоящих из атомов, .... и т.д. Соответственно, вес автомобиля является суммой весов узлов (деталей (атомов (... (и т.д.)))). Однако ли значит это, что для того, что бы знать вес автомобиля, нам нужно знать, как он устроен? Нет, для этого достаточно просто взвесить его и сохранить полученную информацию о его весе. Информация о весе никак не отражает внутреннее строение автомобиля. Наоборот, она описывает его как нечто целое, что обладает способностью притягиваться к земле или давить на дорогу, т.е.


взаимодействовать с окружающими вещами.

Еще один пример. Для описания некоторых вещей мы можем использовать свойство "адрес". Тем самым мы определяем, что данная вещь (например, человек, или фирма, или что-то еще) является адресуемой (в самом банальном смысле - ей можно послать письмо, или посмотреть по карте её местоположение). Информация о качестве "адрес" является результатом следующих связей между вещами: описываемая вещь находится в доме номер X расположенном на улицеY имеющейся в городе Z. Здесь "дом", "улица" "город" - это вещи, а "номер дома ", "название улицы", "имя города" - качества этих вещей. Свойство "адрес" является обобщением всех вышеперечисленных качеств всех вышеперечисленных вещей. Однако для того, что бы описать адресуемую вещь, нам совершенно не нужно описывать дома, улицы и города - надо просто знать адрес этой вещи. Существование этой информации позволяет сказать, что описываемая этой информацией вещь обладает способность к определенному взаимодействию - ей можно послать письмо, определить ее положение на карте и т.п. И в данном случае атрибут "адрес" не описывает строение реально существующих вещей, однако позволяет описать её способность к определенному взаимодействию с другими вещами.

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



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



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



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


Качество (логика).


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

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

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

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

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

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


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

Качества можно сравнивать на основании следующих принципов:

1. между собой могут сравниваться значения только одного и того же качества. Только такое сравнение является осмысленным.

2. единственным способом сравнения качеств является сравнение значений качества. Качества, описываемые одинаковыми значениями, являются одинаковыми и никак иначе не отличаются друг от друга.

Следствием этого является то, что

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

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

1. можно сравнивать объекты разных классов. На самом деле, верней была бы фраза "можно пытаться сравнить объекты разных классов". Дело в том, что объекты в любом случае должны сравниваться в терминах качеств, поскольку вещи сравниваются именно в этих терминах. А для этого сравнения в первую очередь необходимо, что бы объекты описывались одинаковыми качествами.

2. два разных объекта, даже если их состояние (значение) абсолютно одинаково, все равно являются разными, отличаются друг от друга. Единственным критерием, позволяющим однозначно отличить один объект от другого, является объектный идентификатор - OID.


Только в том случае, когда объекты имеют одинаковый OID, можно сказать, что речь идет об одном и том же объекте.

3. объекты ,имеющие разную структуру, тем не менее, могут относиться к одному классу. Это верно по крайне мере в следующих случаях:

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

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


Как это работает.


В самом общем виде работа системы основанной на модели "объект-качество", может быть проиллюстрирована следующим примером (исключительно иллюстративным) . Предположим, что нами определено качество Q

Property Q { int i; long l; }

При обработке этого выражения системой на уровне хранение будет создано новое отношение R со схемой [OID, S, i:int, l:long]. Следующее выражение

Class C { Attr Q; }

приведет к тому, что в каталоге классов появиться информация о новом классе С, с качественным атрибутом типа Q. Теперь мы можем создать объект этого класса:

C rObject = new C;

Это процесс можно разделить на следующие этапы

в стержневое отношение R0 система добавляет кортеж, в котором содержится OID создаваемого объекта и информация о том, что этот объект будет ассоциироваться со схемой класса С на основании информации, содержащейся в ассоциированной схеме класса, в отношение R система добавляет новый кортеж. Значение атрибута "OID" этого кортежа равно OID созданного объекта, а значение атрибута "S" соответствует имени атрибута "Attr"

Далее OID объекта присваивается ссылочной переменной rObject. Теперь можно изменить значение атрибута созданного объекта

rObject.Attr.i = 1;

На основании информации, содержащейся в кортеже стержневого отношения, описывающем объект, идентифицируемый OID, содержащемся в ссылочной переменной rObject, система определяет, что этот объект ассоциирован со схемой класса C. В этой схеме класса содержится информация о том, что атрибут Attr имеет качественный тип Q. Поскольку информация об атрибутах этого типа содержится в отнощении R, то предыдущее выражение может быть приведено системой к следующему запросу на изменение данных:

UPDATE SET R.i = 1 WHERE R.OID = rObject AND R.S = "Attr"



Как MySQL работает с памятью.


Здесь приведено описание того, как MySQL сервер работает с оперативной памятью. В скобочках жирными буквами указаны переменные, которые влияют на то или иное значение.

Key_buffer является общим для всех потоков. Все остальные буфера выделяются по мере необходимости.

Каждое соединение использует некоторое количество памяти. Это память для стека (thread_stack), буфер соединения (net_buffer_length) и буфер результата (net_buffer_length)

Для каждого запроса, требующего последовательно сканировать таблицу, выделяется буфер чтения (record_buffer).

Все JOIN запросы выполняются в один проход и для большинства таких запросов нет необходимости применять вспомогательные таблицы. В основном вспомогательные таблицы формируются в памяти, но если такая таблица имеет слишком большой размер записи или используется тип BLOB, то она сохраняется на диске. Если размер вспомогательной таблицы, которая хранится в памяти, превысит tmp_table_size, то будет возвращена ошибка table_name is full. Для избежания такой ошибки нужно или увеличить значение tmp_table_size, или включить опцию SQL_BIG_TABLES ( можно сделать либо запросом SET SQL_BIG_TABLES=1, либо запускать mysqld с опцией -big-tables). При включенной опции SQL_BIG_TABLES все вспомогательные таблицы формируются не в памяти, а на диске.

Запросы с сортировкой выделяют в памяти буфер для сортировки (sort_buffer) и используют один или два временных файла.

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

Для таблиц с BLOB-полями буфер автоматически увеличивается до размера самого большого BLOB-поля.

Дескрипторы всех открытых таблиц хранятся в кэше, который работает по принципу FIFO. Размер кэша определяется переменной table_cache. Если несколько потоков открывают одну и туже таблицу, то для каждого потока выделяется свой дескриптор таблицы.

Команда mysqladmin flash-tables закрывает все таблицы, которые не используются в данный момент, а все используемые таблицы помечает для закрытия. Такая операция позволяет освободить неиспользуемую память.



Как отключить подставляемость


Зачем нужно отключать или ограничивать подставляемость? Я могу захотеть, чтобы таблица содержала только объекты конкретного типа внутри иерархии, а не всякие подтипы. Для обеспечения этого требования, Oracle предоставляет возможность отключать подставляемость на любом уровне для столбца или атрибута, включая встроенные атрибуты и вложенные коллекции. Для этого используется следующее предложение:

NOT SUBSTITUTABLE AT ALL LEVELS

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

CREATE TABLE meal ( served_on DATE, appetizer food_t, main_course food_t, dessert dessert_t ) COLUMN appetizer NOT SUBSTITUTABLE AT ALL LEVELS ;

Предложение NOT SUBSTITUTABLE используется, чтобы указать, что при задании значения для столбца appetizer нельзя использовать подтип еды. Я не хочу, чтобы кто-нибудь вставил десерт в качестве закуски.

Рассмотрим теперь код в Листинге 1. Я пытаюсь вставить два различных приема пищи. В первом INSERT'е я указываю объект типа food_t в качестве закуски. Во втором insert'е я пытаюсь подсунуть десерт в качестве закуски. Результатом выполнения является следующая ошибка:

ERROR at line 1: ORA-00932: inconsistent datatypes

Предложение NOT SUBSTITUTABLE можно применить и к целой объектной таблице. Листинг 2 демонстрирует эту возможность. Я создал таблицу объектов food_t, с именем brunches. В нее можно успешно вставлять объекты типа food_t, но при попытке вставить десерт в таблицу возникает та же ошибка "несовместимые типы данных".

Вот что следует помнить об ограничениях подставляемости:

Не существует механизма отключения подставляемости для REF столбцов. Столбец должен быть столбцом верхнего уровня, чтобы предложение NOT SUBSTITUTABLE AT ALL LEVELS было применимо к нему. Это предложение нельзя применить к атрибуту объектного типа.



Как работать с таблицами для достижения большей производительности.


По возможности все поля декларировать как NOT NULL. Это сделает работу с таблицами более быстрой и сохранит 1 бит на каждое такое поле.

Применять значения по умолчанию (DEFAULT). При вызове запроса INSERT в таблицу будут записываться только те поля, значения которых отличаются от DEFAULT.

Используйте настолько малые типы INT, насколько это возможно. Например, применять MEDIUMINT намного лучше, чем обычный INT.

Если у вас нет записей с переменной длиной ( ни одного поля с типом VARCHAR, BLOB или TEXT), то таблица сохраняется в формате " постоянной длиной записи ". Это несколько расходует память, но намного повышает скорость работы.

При использовании нескольких последовательных INSERT запросов, лучше все данные указать в одном INSERT, чем делать несколько INSERT.

При загрузке данных в таблицу лучше использовать LOAD DATA INFILE, чем INSERT, такой метод в 20 раз быстрее.

Для увеличения скорости LOAD DATA INFILE и INSERT нужно увеличить значение переменной key_buffer.

Если ожидается много запросов INSERT или UPDATE, работающих одновременно, то для большей скорости рекомендуется приметь LOCK TABLES.

Время от времени нужно дефрагметировать таблицы. Это делается утилитой isamchk с опциями - evi.



Как удержать администратора БД?


Лучший способ удержать Вашего АБД - это не заставлять его сидеть на службе по выходным и сделать его работу более предсказуемой и контролируемой. Этого легко добиться, увеличив количество администраторов, инструментальных средств или и то, и другое одновременно. Пересечение обязанностей защищает компанию от потери накопленного опыта, одновременно предоставляя АБД возможности для карьерного роста.Стандартизировать скрипты или программные средства. Снизить избыточную деятельность . Воспользоваться услугами консультантов для заполнения пробелов и повышения квалификации существующего персонала.



Каталог.


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

1) Каталог качеств определяет существование множества именованных качеств и описывает структуру этих качеств. Можно предполагать, что строение этой части каталога должна быть похожа на строение каталогов традиционных реляционных БД. Поскольку существование множества качеств Q на уровне представления определяют существование множества отношений R на уровне хранения, то информация представленная в каталоге качеств служит для построения системы сохранения данных. В каталоге качеств должно существовать отношение RQ, перечисляющее существующее в системе качества с первичным ключом IDQprim, в качестве которого может выступать атрибут, содержащий уникальные имена качеств или их уникальные идентификаторы.

2) Каталог классов определяет существование множества именованных классов и содержит полную информацию о структуре этих классов. Существовании множества классов подразумевает наличие в каталоге классов отношения RC с первичным ключом ClassIDprim, в качестве которго может выступать атрибут, содержащий уникальные имена классов или их уникальные идентификаторы. Мы уже говорили, что информация, позволяющая определить класс объекта, должна содержаться в стержневом отношении R0. Эта информация должна рассматриваться как внешний ключ ClassID, связанный с первичным ключом ClassIDprim отношения RC. Это гарантирует, что для каждого существующего в системе объекта в каталоге классов будет содержаться его описание; информацию о структуре класса невозможно удалить, пока в системе существует хотя бы один объект этого класса.

Так же в каталоге классов определяется существование множества именованных атрибутов классов. Это подразумевает наличие в каталоге классов отношения RS, в котором перечисляются существующие в системе атрибуты объектов.
Совершенно естественно, что первичным ключом этого отношения должен являться атрибут Sprim, определенный на домене DS. Для всех остальных отношений Ri (i > 0) множества R атрибут S (К-часть) должен рассматриваться как внешний ключ, связанный с первичным ключом Sprim отношения RS. Таким образом, каждому атрибуту качественного типа ставиться в соответствии его описание в каталоге классов.

Отношение RS, перечисляющее атрибуты классов, должно служить так же для того, что бы хранить информацию о типах атрибутов. Эта информация может быть представлена в виде атрибута, являющимся внешним ключом IDQ, связанным с первичным ключом IDQprim отношения RQ.

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

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


Классификация АБД


Существует несколько видов администраторов БД, а их обязанности вполне могут отличаться от компании к компании. Вот характеристики некоторых типов АБД и занимаемых ими положений:

Оперативные (operational) АБД:

манипулируют дисковым пространством наблюдают за текущей производительностью системы реагируют на возникающие неисправности БД обновляют системное ПО и ПО базы данных контролируют структурные изменения БД запускают процедуры резервного копирования данных выполняют восстановление данных создают и управляют тестовыми конфигурациями БД

Тактические (tactical) АБД:

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

Стратегические (strategic) АБД:

выбирают поставщика БД устанавливают корпоративные стандарты данных внедряют методы обмена данных в рамках предприятия определяют корпоративную стратегию резервирования и восстановления данных устанавливают корпоративный подход к ликвидации последствий аварии и обеспечению доступности данных

Старшие (senior) АБД:

досконально знают свой персонал пользуются высоким спросом могут написать скрипт, который освободит их из запертого сундука, брошенного в океан, и чрезвычайно гордятся своими произведениями тратят уйму времени на подготовку младших АБД очень ценятся руководством и получают бешеные деньги

Младшие (junior) АБД:

мечтают стать старшим АБД не слишком сильны в написании скриптов имеют большую склонность к использованию средств управления БД тоже неплохо получают

Прикладные (application) АБД:

в курсе информационных нужд компании помогают в разработке прикладных задач отвечают за разработку схемы и ее изменения вместе с системным АБД обеспечивают должный уровень резервирования/ восстановления данных занимаются построением тестовых БД


Системные (system) АБД:

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

Наемныю (contract) АБД :

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

Администраторы-руководители :

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


Классификация объектов


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

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

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



Классика баз данных



Сергей Кузнецов


Сергей Кузнецов


Э.Ф. Кодд,
Оригинал: IBM Research Report RJ599 (# 12343), August 19, 1969. Заново опубликовано в ACM SIGMOD Record, March 2009
Перевод: Сергей Кузнецов


Джим Грей, 1996 г.
Новая редакция: Сергей Кузнецов, 2009 г.


А.Зильбершац, С.Здоник, 1996 г.

Перевод: М.Р. Когаловский
Новая редакция: Сергей Кузнецов, 2009 г.


Хамид Пирамеш, Джозеф Хеллерстейн, Вакар Хасан, 1992 г.

Перевод: Сергей Кузнецов


Э. Ф. Кодд, 1979 г.

Перевод: М.Р. Когаловский
Новая редакция: Сергей Кузнецов, 2009 г.


Сергей Кузнецов


Питер Гесснер, Гай Лохман, Берндхард Шайфер, Юн Ванг, 1993 г.
Перевод: Сергей Кузнецов


Альберт Чен, Юнг-Фенг Као, Майк Понг, Диана Шак, Сунил Шарма, Джей Вайшнав, Хансйорг Зеллер, 1993 г.
Перевод: Сергей Кузнецов


Геннадий Антошенков, 1993 г.
Перевод: Сергей Кузнецов


Индерпал Сингх Мумик, Шелдон Финкельштейн, Хамид Пирамеш, Раджу Рамакришнан, 1990 г.
Перевод: Сергей Кузнецов


Правин Сешарди, Джозеф Хеллерстейн, Хамид Пирамеш, Клифф Леюнг, Раджу Рамакришнан, Дивеш Сривастава, Питер Стюки, С. Сударшан, 1996 г.
Перевод: Сергей Кузнецов


М. Тамер Оззу, Патрик Валдуриз, 1996 г.
Новая редакция: Сергей Кузнецов, 2009 г.


Под ред. Ави Зильбершатца, Майка Стоунбрейкера и Джеффа Ульмана, 1996 г.
Новая редакция: Сергей Кузнецов, 2009 г.


М.М. Злуф, 1977 г.
Новая редакция: Сергей Кузнецов, 2009 г.


Х. Беренсон, Ф. Бернштейн, Д. Грэй, Д. Мелтон, Э. О'Нил, П. О'Нил, 1995 г.
Новая редакция: Сергей Кузнецов, 2009 г.


Джон М. Смит, Диана К. Смит, 1977 г.
Перевод: М.Р. Когаловский
Новая редакция: Сергей Кузнецов, 2009 г.


Д.Д. Чамберлин, М.М.Астрахан, К.П.Эсваран, П.П.Грифитс, Р.А.Лори, Д.В.Мел, П.Райшер, Б.В.Вейд, 1976 г.
Новая редакция: Сергей Кузнецов, 2009 г.


Петер Пин-Шен Чен, 1976 г.

Перевод: М.Р. Когаловский
Новая редакция: Сергей Кузнецов, 2009 г.


М. Аткинсон, Ф. Бансилон, Д. ДеВитт, К. Диттрих, Д. Майер, С.Здоник, 1989 г.

Перевод: М.Р. Когаловский
Новая редакция: Сергей Кузнецов, 2009 г.


Х. Дарвин, К. Дэйт, 1995 г.



Перевод: М.Р. Когаловский
Новая редакция: Сергей Кузнецов, 2009 г.



Дэвид Девитт, Джим Грэй, 1992 г.
Новая редакция: Сергей Кузнецов, 2009 г.



Майкл Стоунбрейкер, Лоуренс Роув, Брюс Линдсей, Джеймс Грей, Майкл Кери, Майкл Броуди, Филипп Бернштейн, Дэвид Бич, 1990 г.

Перевод: М.Р. Когаловский
Новая редакция: Сергей Кузнецов, 2009 г.



Е.Ф. Кодд, 1970 г.

Перевод: М.Р. Когаловский
Новая редакция: Сергей Кузнецов, 2009 г.



Ракеш Агравал, Анастасия Айламаки, Филипп Бернштейн, Эрик Брювер, Майкл Кери, Сураджит Чаудхари, Анхай Доан, Даниэла Флореску, Майкл Франклин, Гектор Гарсиа Молина, Йоханнес Герке, Ле Грюнвальд, Лаура Хаас, Элон Хэлеви, Джозеф Хелерстейн, Яннис Иоаннидис, Хэнк Корт, Дональд Коссман, Сэмюэль Мэдден, Роджер Магулас, Бенг Чин Ой, Тим О’Рейли, Раджу Рамакришнан, Суннита Сарагави, Майкл Стоунбрейкер, Александер Залай, Герхард Вейкум, 2008 г.

Пересказ и комментарии: Сергей Кузнецов



Майкл Франклин, Элон Хэлеви, Дэвид Майер, 2005 г.

Перевод -



Джим Грей, Дэвид Лью, Мария Нието-Сантистебан, Алекс Шейли, Дэвид Девитт, Герд Хебер, 2005 г.
Перевод -



Волкер Маркл, Гай Лохман, Виджайшанкар Раман, 2003 г.

Перевод: Сергей Кузнецов



А.Эйзенберг, Дж.Мелтон, 1999 г.

Сергей Кузнецов



Фил Бернштейн, Майкл Броуди, Стефано Чери, Дэвит Девитт, Майк Франклин, Гектор Гарсиа-Молина, Джим Грей, Джерри Хелд, Джо Хеллерстейн, Х.М. Ягадиш, Майкл Леск, Дейв Майер, Джеф Науфтон, Хамид Пиранеш, Майк Стоунбрейкер, Джеф Ульман, 1998 г.

Перевод: Сергей Кузнецов



Сураджит Чаудхари, 1998 г.

Перевод: Сергей Кузнецов


Под редакцией Пола МакДжонса, 1997 г.

Перевод: Сергей Кузнецов



Дон Чемберлин, 1996 г.

Перевод: Сергей Кузнецов



Матиас Ярке, Юрген Кох, 1984 г.

Перевод -



П. Селинджер, М. Астрахан, Д. Чемберлин, Р. Лури, Т. Прайс, 1979 г.
Перевод -


Кодирование базовых типов.


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

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

должно кодироваться с позиции m*n, где m

- это целое число. В CDR n может принимать значения 1, 2, 4 или 8. Если необходимо, то выровненному значению предшествует область минимально возможного размера, необходимого для выравнивания. Значение байтов внутри этой области не определено.

Выравнивание определяется относительно начала потока. Первый байт в сообщении или инкапсуляции имеет индекс 0.



Кодирование инкапсуляции.


Первый байт инкапсуляции кодирует порядок байт внутри нее - значение типа 0 означает кодирования по принципу первым - старший байт, 1 - младший. Далее идут данные. Флаг порядка байт не включается в данные, но он включается в инкапсуляцию. Все значения внутри инкапсуляции выравниваются относительно ее начала, первый байт (с индексом 0) соответственно занимает флаг порядка байт. Если инкапсуляция кодируется как последовательность величин типа octet

(байтов), то ей предшествует значение типа unsigned long, содержащее общий размер инкапсуляции. Никакого выравнивания для инкапсуляции не предполагается, но такой способ кодирования всегда гарантирует 4-байтное выравнивание для первого байта инкапсуляции.



Кодирование псевдообъектов.


Спецификация CORBA определяет несколько псевдообъектов, которые не являются ни базовыми ни составными типами и кодируются специальным образом. Ввиду особой специфичности данного кодирования и оно здесь не рассматривается.



Кодирование составных типов.


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

Элементы структуры кодируются в том порядке, в котором они определены в описании на IDL. Каждый элемент кодируется образом, соответствующим его типу.

Объединение кодируется значением дискриминатора и членом объединения, соответствующим данному значению.

Массив кодируется как последовательность его элементов. Так как длина массива фиксирована, она не кодируется. Если массив имеет несколько измерений, то первый индекс изменяется наиболее медленно, а последний - наиболее быстро.

Последовательность элементов кодируется как величина типа unsigned long, за которым следуют элементы последовательности. Это значение определяет количество элементов. Каждый элемент кодируется в соответствии со своим типом.

Строка кодируется как величина типа unsigned long, содержащее длину строки, и отдельными символами - элементами строки. Длина строки и ее представление в виде списка символов включают завершающий нулевой символ, что дает возможность использования стандартных функций библиотеки языка C (например, strcpy) для декодирования сообщения.

Значение перечислимого типа кодируется в виде величины типа unsigned long, соответствующей данному значению. Первому в порядке перечисления в определении на IDL значению соответствует 0, второму - 1 и так далее.



Когда расширение не является расширением?


When's an extension not an extension?

C.J. Date

()

С самого начала по отношению к реляционной модели наблюдался необычайно высокий уровень критики. Более конкретно, в течение многих лет утверждалось, что (a) в модели не хватает тех или иных возможностей и, следовательно, (b) ее необходимо некоторым образом расширять. В этой заметке я хочу достаточно детально исследовать суть дел, связанных с "расширением реляционной модели". В частности, мне хочется представить свои соображения по поводу собственной расширенной версии Кодда, известной под названием RM/T.



Компилирование исходников.


Для достижения наибольшей производительности сервера нужно учитывать такие факты:

При компиляции pgcc с опцией -O6 mysqld работает на 11 % быстрее, чем если компилировать обычным gcc.

Если использовать динамическую линковку, то результат будет на 13% медленней, чем при статической.

Если использовать TCP/IP соединения, то результат на 7.5% хуже, чем при использовании UNIX - сокетов.

В связи с этим рекомендуется поставить компилятор pgcc ( ). Этот совет, конечно, имеет смысл, если у вас Pentium процессор. Pgcc будет полезен не только для компилирования MySQL, разработчики этого компилятора утверждают, что откомпилированные им программы минимум на 5% работают быстрее, чем откомпилированные с помощью gcc.

Запуск конфигуратора может иметь такой вид ( во внимание вышеизложенные факты ): CFLAGS="-O6 -fomit-frame-pointer" \ CXX=gcc \ CXXFLAGS="-O6 -fomit-frame-pointer \ -felide-constructors -fno-exceptions -fno-rtti" \ ./configure \ --enable-assembler \ --disable-shared \ --with-mysqld-ldflags="-all-static" \ --with-client-ldflags="-all-static" \ --with-unix-socket-path=/tmp/mysql.sock \ --prefix=/usr



Комплексное функционирование


Что бы увидеть общее представление механизма взаимодействия с поисковой системой нужно взглянуть на рис. 3.

Рис.3

Как видно из рисунка, существует три потока управления. Первый обслуживает запросы пользователя, второй выполняет поисковые запросы, а третий занимается индексированием новых документов поступающих в систему. Первый поток - это скрипт на Perl, Servlet, ASP или PHP, который из ключевых слов пользователя формирует поисковые SQL запросы. Второй поток - это СУ базой данных, которая поддерживает целостность данных, индексный механизм и обслуживает SQL запросы. Третий поток - это тоже скрипт, который работает с новыми документами, индексирует их и посылает запросы в базу данных на внесения новой индексной информации.



Корректность


С XML-документом связаны три уровня корректности:

Правильно построенный XML-документ - это такой, в котором элементы правильно структурированы в виде дерева с корректно расставленными открывающими и закрывающими тегами. Правильно построенные документы существенны для информационного обмена. Действенный XML-документ правильно построен и содержит теги, соответствующие объявлению типа документа. Он содержит только элементы и значения атрибутов, которые соответствуют DTD. Хотя XML-документ может подготавливаться и читаться без DTD, DTD существенно для установления действенности. Синтаксически корректный XML-документ находится вне контроля XML. Разработчик такого документа отвечает за его логическую структуризацию. (См. упоминавшуюся выше статью OMG.)



Краткое сравнение Oracle SQL и ANSI SQL


Вязовецков Алексей Сергеевич,

Целью данной статьи является выявление различий между реализацией SQL в СУБД Oracle 8 и ANSI SQL92. В частности делается анализ языка обработки данных (DML) и не рассматривается язык определения данных (DDL), также не рассматривается объектное расширение языка SQL, предназначенного для работы с объектными таблицами Oracle и отсутствующее в стандарте ANSI. Язык SQL СУБД Oracle 8 (далее Oracle SQL), по заявлению фирмы-производителя , соответствует начальному уровню ANSI SQL (entry level), однако некоторые особенности реализации его превосходят, а некоторые отличаются. Статья делает попытку описать отличия и дополнения и будет полезна для написания приложений более легко переносимых с СУБД Oracle на другую СУБД, удовлетворяющую стандарту ANSI. Хотя и существует мнение что нельзя перенести приложение с одной СУБД на другую без изменения кода, информация данной статьи поможет это сделать в случае необходимости более легко.



Лабораторная работа: MySQL


Олег П. Филон,

Заняться выполнением этой лабораторной работы меня побудили несколько причин. Во-первых, занимаясь построением серверов и сетей на основе Линукс'а, я догадывался, что где-то совсем рядом лежит сказочно богатый континент, пока не нанесенный на мою карту компьютерного мира. Во-вторых, авторы одной из самых популярных открытых программ - СУБД MySQL, недавно приняли GNU GPL (General Public License) как лицензию, по которой распространяется эта программа, и теперь MySQL является полноценным проектом GNU. Эти юридические тонкости имеют самое непосредственное отношение к нам, пользователям, чему я немного ниже приведу пример. И наконец, в-третьих, пытаясь отыскать хорошие руководства по SQL в сети, я в конце концов обнаружил, что самые лучшие он-лайновые учебники по этой теме, оказывается, написаны нашими соотечественниками, на русском языке, и лежат у меня на диске - в зеркале сервера

Особенно полезны учебный курс Пушникова А.Ю., и курс лекций Сергея Кузнецова. Недавно к ним добавилось подробное , сделанное Паутовым Алексеем Валентиновичем на основе оригинальной документации и такое же доскональное.

Итак, пришла пора взяться за учебники, а для меня еще и достать припасенный для такого случая особый файл. Этот файл представляет собой телефонный справочник службы 09 нашего города, пару лет назад попавший в местную ФИДО-сеть. Мне не очень важна его актуальность, зато очень подходит его размер - свыше 120 тысяч записей. Очень часто примеры, даваемые в учебниках, являются слишком игрушечными, чтобы вызывать интерес. Затем, на крошечной БД невозможно почувствовать скорость и мощь современных программ и компьютеров, или наоборот, плохо настроенную БД или неправильно составленный запрос. Кроме этого, ситуация с построеним БД вокруг уже имеющихся данных вполне жизненна.

Вполне возможно, что у вас файла с такими данными в пределах досягаемости нет. Ничего страшного - его можно сделать самому, использовав подручные средства - например, взять простой текстовый файл, обычные textutils, и интерпретатор языка awk.
Пример, как это можно сделать, приведен . Конечно, данные в таком файле будут случайными, только внешне похожими на настоящий телефонный справочник.

Для начала надо установить на вашем компьютере MySQL. Не буду пересказывать главы из документации, имеющиеся в описании Алексея Паутова. Скажу лишь, что для установленного у меня дистрибутива Дебьян установка программы свелась к выполнению команды:

...$ dpkg -i mysql-server_номер_версии.deb mysql-client_номер_версии.deb

В дистрибутиве Mandrake, который я также иногда использую, используется программа-установщик rpm с соответствующими ключиками, или же какая-то из графических надстроек над rpm. Вполне возможно, что в вашей Линукс системе эта СУБД установилась сама собой по умолчанию.

Инсталяция MySQL под Windows, равно как и Apache, PHP и Perl, рассказана на том же ЦитФоруме.

Предупреждаю, однако, что все, что написано ниже, проверено только под Линуксом.

Если вам повезло, и команда

...$ mysql

из вашего шелла выдала приглашение наподобие:

Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 28 to server version: 3.22.32-log Type 'help' for help. mysql>

, то в ответ на него наберите \q, оставим на время интерпретатор SQL запросов, и займемся администрированием сервера MySQL.

Прежде всего, надеюсь, вы установили пароль администратора сервера БД, и пока его не забыли. Теперь нужно завести пользователей и дать им некоторые права. Все администрирование ведется через обычные таблицы MySQL, и их правка также осуществляется стандартными SQL командами. Самая первая таблица, которая определяет допуск юзера к серверу, так и называется - user. Давайте глянем, кто у нас там есть и что он может делать:

...$ mysqldump -u root -p --opt mysql user>mysql-users.sql

После выполнения этой команды у нас появился файл mysql-users.sql Загрузим его в текстовый редактор, чтобы поподробнее изучить, и, возможно, немного поправить.

# MySQL dump 7.1 # # Host: localhost Database: mysql #-------------------------------------------------------- # Server version 3.22.32-log # # Table structure for table 'user' # DROP TABLE IF EXISTS user; CREATE TABLE user ( Host char(60) DEFAULT '' NOT NULL, User char(16) DEFAULT '' NOT NULL, Password char(16) DEFAULT '' NOT NULL, Select_priv enum('N','Y') DEFAULT 'N' NOT NULL, Insert_priv enum('N','Y') DEFAULT 'N' NOT NULL, Update_priv enum('N','Y') DEFAULT 'N' NOT NULL, Delete_priv enum('N','Y') DEFAULT 'N' NOT NULL, Create_priv enum('N','Y') DEFAULT 'N' NOT NULL, Drop_priv enum('N','Y') DEFAULT 'N' NOT NULL, Reload_priv enum('N','Y') DEFAULT 'N' NOT NULL, Shutdown_priv enum('N','Y') DEFAULT 'N' NOT NULL, Process_priv enum('N','Y') DEFAULT 'N' NOT NULL, File_priv enum('N','Y') DEFAULT 'N' NOT NULL, Grant_priv enum('N','Y') DEFAULT 'N' NOT NULL, References_priv enum('N','Y') DEFAULT 'N' NOT NULL, Index_priv enum('N','Y') DEFAULT 'N' NOT NULL, Alter_priv enum('N','Y') DEFAULT 'N' NOT NULL, PRIMARY KEY (Host,User) ); # # Dumping data for table 'user' # LOCK TABLES user WRITE; INSERT INTO user VALUES ('localhost','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y'), ('localhost','ophil','','N','N','N','N','Y','N','Y','N','N','Y','N','N','N','N'), ('localhost','proba','','N','N','N','N','N','N','N','N','N','N','N','N','N','N'); UNLOCK TABLES;



Вот уже и показались первые SQL-предложения, хотя мы пока не начинали программировать или что-либо запрашивать. В предложении CREATE TABLE перечислены все 14 различных привилегий, которые могут иметь или быть лишены пользователи. Первые 6 - Select, Insert, Update, Delete, Create и Drop, касаются права пользователя работать с записями таблиц и с самими таблицами. Следующие 4 - Reload, Shutdown, Process и File - касаются сервера в целом. Привилегии Grant, References, Index и Alter дают право передавать права, а также изменять, связывать и индексировать таблицы.

Два важных замечания.

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

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

Если в ваши планы входит дать доступ к серверу всем пользователям и под любым именем, заведите пользователя с пустым именем ''. Те же правила применяются к именам и адресам компьютеров-хостов.

Теперь, размножив и поправив записи в таблице, но ни в коем случае не ее структуру, отправим команды обратно в MySQL.

...$ mysql -u root -p < mysql-users.sql

и попросим сервер перечитать измененные права

...$ mysqladmin -u root -p reload

Еще одно замечание насчет паролей. В рассмотренном нами файле поля паролей пусты, и это надо немедленно исправить. Править их в текстовом файле неудобно, потому что MySQL используем для шифрования пароля отдельную программу, и хранит пароль в зашифрованом виде. Чтобы установить пароль, например, пользователю "proba", надо выполнить такую команду:

...$ mysql mysql -e 'update user set password=password("0") where user="proba";'



Поздравляю, мы только что составили и выполнили первый SQL запрос в нашей лабораторной работе, хотя и сделали это из командной строки, со всеми ее удобствами и неудобствами. К неудобствам можно отнести то, что наш пароль высветился на экране, мог попасть в список процессов, в разные журнальные файлы. Будет лучше не полениться, запустить монитор mysql и задавать пароли в нем с помощью того же запроса внутри СУБД MySQL.

Отличие от обычной системы паролей в том, что имена пользователей БД могут быть не связаны с их регистрационными именами в системе, пользователи не могут менять свои пароли, и этот пароль известен администратору БД.

Разобравшись с самой первой административной таблицей user, остальные таблицы: db, host, tables_priv, columns_priv, func - правим аналогично.

Каждую из команд, посылаемую MySQL, можно задавать либо в мониторе запросов mysql, либо из командной строки, либо создав файл и отправив его в интерпретатор MySQL через тот же монитор. Можно также обратиться к MySQL через интерфейсы с другими языками программирования из программ, написанных на C, Perl, PHP, Python и других.

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

Итак, обговорив разные способы ввода команд и вывода результата, займемся собственно SQL предложениями и преобразованием исходных данных. Доставшийся мне по случаю файл 09phone.txt представляет собой текстовый файл с полями в фиксированых колонках, как здесь :

107003 банки "приорбанк" первомайская ул. 1 бнк 107007 центры информацио жукова ул. 4а цен 107026 предприятия транс артиллерийская ул. 8а пре

и каждая запись содержит 5 полей:

номер телефона фамилия или название организации улица номер дома номер квартиры или примечание



Если бы исходные данные пришли из другой SQL БД и были в виде, как уже изученная нами таблица user, все, что нам пришлось бы сделать, это отправить в интерпретатор этот файл. Если бы текстовый файл был в более удобоваримом виде, например, с полями, разделенными знаками табуляции, то загрузить его в таблицу также можно было бы за один шаг. Но в нашем случае придется создать временную таблицу

create table tmp ( line varchar(80) );

и импортировать в нее данные с помощью

load data infile '/tmp/09phone.txt' into table tmp;

Таким образом мы записали в таблицу tmp каждую запись как строку без разделения на поля. Импорт занял на моем компьютере около 4.4 сек. Здесь и далее и привожу время только для сравнения, для своего компьютера и настроек программы, сделанных по умолчанию.

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

Сначала создадим таблицу

create table old ( phonum int unsigned not null, title varchar(64) not null, street varchar(40) not null, bldng varchar(8) not null, other varchar(8) not null );

а затем заполняем ее данными, пройдя по всем строкам таблицы tmp:

insert into old ( phonum, title, street, bldng, other ) select trim(mid(line,1,6)), trim(mid(line,8,18)), trim(mid(line,34,19)), trim(mid(line,58,4)), trim(mid(line,63,3)) from tmp;

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

drop table tmp;

Опять же, только для сравнения, 123 тысячи записей обработаны за 8.6 сек.Для того, чтобы узнать время запроса из программы, содержащей все команды и выполняемой неинтерактивно, пришлось применить такой способ:

create table times ( start int unsigned ); insert into times values ( unix_timestamp() );

Чистый SQL и MySQL не поддерживают никаких иных переменных, кроме таблиц и полей, так что для хранения времени пришлось завести отдельную таблицу.


Нет также ничего похожего на print или echo, так что сообщать результат получилось только злоупотребив оператором select:

select "импорт данных выполнен: ", unix_timestamp()-start, " сек." from times;

Получившаяся таблица old еще нуждается в нормализации, но уже первые тривиальные запросы выявили одну проблему. Сортировка по алфавиту использовала по умолчанию чуждую русскому языку кодировку ISO-8859-1. Хотя в последних версиях, возможно, уже можно менять порядок сортировки на ходу, в той версии, которая входит в Debian v2.2, для правильной работы с русским языком необходима перекомпиляция (сборка) программы с параметром

...$ ./configure --with-charset=koi8_ru

В Debian'е для сборки пакетов есть масса скриптов, которые и делают всю работу. Таким образом, поправив файл debian/rules и произведя магическое заклинание

...$ debuild -b -uc 2>&1|tee build.log

вскоре я получил готовый к инсталяции пакет с правильным понятием по-русски.

Но тут же возникла следующая проблема. FSF (Free Software Foundation) и Debian очень щепетильно относятся к любым ограничениям на свободу программ, и те ограничения на коммерческое использование MySQL, которые были в их старой лицензии, привели к тому, что MySQL оказался в секции non-free. Желание иметь клиентскую часть свободной вынудило разработчиков вырезать из оригинальных исходников чисто GPL-ные куски и образовать отдельное дерево исходников. По-английски это называется "fork", а в русском языке вполне подходит слово "раскол". Хоть это слово и с маленькой буквы, явление весьма неприятное, распыляющее силы разработчиков и создающее неудобства пользователям. В моем случае пришлось пересобирать также и GPL-ные исходники, а затем бороться с конфликтом зависимостей пакетов.

Но вот борьба позади, и мы приступаем к разбиению единой таблицы на несколько связанных и нормализованных, что, собственно, и дает право называться СУБД реляционной. Из таблицы old с теми же полями, что и в исходном файле, мы сделаем 3 таблицы, связанные, как это обычно рисуется на схемах, таким образом:



phone ------ phonum building naim -------- street bd_id >------------ bd_id ------ other st_id >----------- st_id bldng nick

Значок >-- обозначает сторону "много" в отношении "один ко многим" и означает, что в одном здании может быть много телефонных номеров, а на одной улице много зданий.

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

create table street ( st_id smallint unsigned not null auto_increment, nick varchar(32) not null, primary key (st_id) ); insert into street ( nick ) select distinct street from old;

Заполнение таблицы заняло 12.1 сек. Теперь создадим таблицу building

create table building ( bd_id smallint unsigned not null auto_increment, st_id smallint unsigned not null references street, bldng varchar(8) not null, tmp varchar(40) not null, # временно, для соответствия с old primary key (bd_id) );

и также заполним ее

insert into building ( st_id, tmp, bldng ) select distinct street.st_id, street.nick, old.bldng from old, street where old.street=street.nick;

Таблица заполнялась аж 5 мин. 23 сек., так что было время задуматься. Прояснить ситуацию в таких случаях помогает особая команда explain, например

explain select distinct street.st_id, street.nick, old.bldng from old, street where old.street=street.nick;

которая выдала следующую подсказку:

+--------+------+---------------+------+---------+------+--------+------------+ | table | type | possible_keys | key | key_len | ref | rows | Extra | +--------+------+---------------+------+---------+------+--------+------------+ | street | ALL | NULL | NULL | NULL | NULL | 591 | | | old | ALL | NULL | NULL | NULL | NULL | 122794 | where used | +--------+------+---------------+------+---------+------+--------+------------+

Оказывается, для каждой записи из old происходит поиск в таблице street, т.е. просматриваются O(122794*591) строк.



Попробуем проиндексировать эти две таблицы по общему полю

create index street on street (nick); create index street on old (street);

Тот же самый запрос теперь выглядит изнутри вот так:

+--------+------+---------------+------+---------+------+--------+ | table | type | possible_keys | key | key_len | ref | rows | +--------+------+---------------+------+---------+------+--------+ | street | ALL | street | NULL | NULL | NULL | 591 | | old | ALL | street | NULL | NULL | NULL | 122794 | +--------+------+---------------+------+---------+------+--------+ ----------------------------------------------+ Extra | ----------------------------------------------+ | range checked for each record (index map: 1) | ----------------------------------------------+

и занимает 19.7 секунд. Даже с учетом ~1 мин. на создание индексов, выигрыш в скорости заметен. Разобравшись с индексами, можно их удалить

drop index street on street; drop index street on old;

Создаем теперь новую таблицу phone

create table phone ( phonum char(6) not null default "000000", naim varchar(48) not null default "", bd_id smallint unsigned not null references building, other varchar(8) not null );

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

create index building on building (tmp, bldng); create index building on old (street, bldng); insert into phone ( phonum, naim, bd_id, other ) select old.phonum, old.title, building.bd_id, old.other from old, building where old.street=building.tmp and old.bldng=building.bldng;

Индексы создались за 3 и 45 сек., а данные вставились за 19 сек. Теперь можно удалить рабочую таблицу и лишние индекс и поле:

drop table old; drop index building on building; alter table building drop tmp;

Подведем некоторые итоги.

Из исходного 8-мегабайтного текстового файла получились 3 связанные таблицы общим размером ~3.8MB.


Простые запросы, например

select p.phonum, p.naim, s.nick, b. bldng from phone p, street s, building b # короткие синонимы таблиц where p.bd_id=b.bd_id # таким образом and b.st_id=s.st_id # связывают таблицы and p.phonum like "%1234%" # собственно запрос order by p.naim;

занимают ~1.6 сек. Это приблизительно совпадает с результатом сканера grep на оригинальном текстовом файле при поиске тех же строк, и немного превосходит время, демонстрируемое интерпретатором awk.

Но, конечно, MySQL создан не для того, чтобы соревноваться с grep или awk. Используя язык SQL, можно создавать БД и манипулировать данными любой сложности. В области клиент-серверных приложений MySQL вполне способен конкурировать с признанными коммерческими СУБД. Но вся мощь MySQL раскрывается в соединении с технологиями Internet, если так можно выразиться, в "дважды клиент-серверных" технологиях. Доступ к БД выполняется из приложений, запускаемых на web-сервере, результат выдается в виде HTML страниц. Затем web-сервер доставляет страницу в клиентский браузер.

В таком виде web-сервер Apache и реляционная СУБД MySQL образуют необычайно масштабируемую платформу для создания приложений. MySQL успешно трудится на самых разных аппаратных платформах, включая суперкомпьютеры, и может обслуживать много web-серверов, работающих на одном или на разных компьютерах. А можно настроить такой же тандем для работы на единственной скромной персоналке.

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



Волкер Маркл, Гай Лохман, Виджайшанкар


Волкер Маркл, Гай Лохман, Виджайшанкар Раман

24.04.2003

Перевод -

Оригинал: V. Markl, G. M. Lohman, V. Raman.

LEO: An autonomic query optimizer for DB2
. IBM SYSTEMS JOURNAL, VOL 42, NO 1, 2003.


Ложные и истинные расширения


Некоторые утверждения о недостатках реляционной модели правильны, другие - нет. Соответственно некоторые предложенные расширения являются правильными в том смысле, что они действительно добавляют полезную функциональность; однако имеются и ложные расширения в том смысле, что они либо (a) не добавляют никакую новую функциональность, либо (b) функциональность, которую они добавляют, не является полезной. В число примеров правильных расширений входят операции EXTEND и SUMMARIZE, операции реляционного сравнения и теория обновления базы данных через представления. (Уверен, что можно согласиться с тем, что все эти примеры действительно обеспечивают новую полезную функциональность.) Примеры ложных расширений включают такие вещи как запросы с квотами, поддержку дат и времени и "тип данных REF" (REF = reference). Позвольте развить эту мысль:

Запросы с квотами полезны с прагматической точки зрения, но по существу они являются всего лишь синтаксической сокращенной записью для уже существующей функциональности. Если говорить более точно, то имея в виду ложные расширения, я не утверждал, что это обязательно плохо - я всего лишь имел в виду, что это на самом деле не расширение модели. Поддержка дат и времени также полезна. Более того, это не просто сокращенная синтаксическая запись для того, что уже существует - действвительно обеспечивается новая функциональность. Однако это все-таки не расширение модели, поскольку вопрос о том, какие типы данных поддерживаются, не имеет ничего общего с моделью ("типы ортогональны таблицам"). Но "тип данных REF" является ложным расширением, поскольку он бесполезен! На самом деле, это возвращает в модель все эти указатели и связанные с ними вещи. Кодд сознательно отказался от этого много лет тому назад [1]. Ложные расширения - когда они действительно провозглашаются расширениями - приводят к искаженному пониманию истинной сути модели. Конечно, это в особенности свойственно сообществу SQL; конечно, из этого происходят недостатки SQL; многие проблемы SQL пытаются связать с "недостатками реляционной модели", а решение пытаются искать в "расширениях объектной модели". (Как я уже много раз писал раньше, наибольшей проблемой SQL является как раз то, что в этом языке не поддерживается реляцтонная модель.) Самым свежим и, видимо, наиболее вопиющим примером является так называемая объектно/реляционная модель, которая кратко обсуждается в следующем разделе.



Машины баз данных


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

И были совершенно правы.



Масштабируемость.


Протокол GIOP/IIOP должен поддерживаться как отдельными ORB-ами, так и ORB-ами, объединенными в сеть на уровне Internet и, возможно, шире.



Microsoft Transaction Server


18 мая в рамках проходившего в Нью-Йорке Дня Масштабируемости демонстрировалась работа гипотетической банковской системы, клиентами которой являлась примерно четверть населения земного шара. Общая база данных находилась под управлением 20-ти серверов Microsoft SQL Server 6.5 на платформе Compaq. Еще 20 компьютеров имитировали деятельность со стороны клиентов. Диспетчеризацию клиентской нагрузки и управление транзакциями выполняли 5 серверов Microsoft Transaction Server (MTS). За день система смогла обслужить миллиард(!) транзакций, из которых значительная доля пришлась на долю распределенных (т.е. проходящих через несколько серверов баз данных).

Microsoft Transaction Server 1.0 был выпущен в декабре прошлого года и в традиционном понимании является сервером поддержки работы приложений, составляющих ПО промежуточного слоя. Он осуществляет автоматическое управление процессами и потоками, имеет встроенные службы безопасности для контроля вызовов и использования объектов, обеспечивает поддержку распределенных транзакций по протоколу двухфазной фиксации OLE 2PC и интеграцию с MS DTC, предоставляет графический интерфейс для регистрации и управления компонентами (MTS Explorer), т.е. фактически предоставляет готовые средства решения задач системного программирования, которые, как мы отметили выше, неизбежно возникают при разработке . С этой стороны положительный аспект применения MTS заключается в том, что при разработке компонент не нужно программировать вручную реакцию на разнообразные исходы в системе. Воспользуемся одним из примеров в составе MTS и рассмотрим класс Account компоненты Bank. Он имеет метод Post для дебитования или кредитования определенного банковского счета. Однако, как правило, банковская операция означает дебет одного счета и кредит другого. Вопрос: сколько дополнительного программирования потребуется, чтобы вызов двух методов в программе на VB, VC++ и т.д. выполнялся как одна транзакция? С использованием MTS решение становится тривиальным.



Множественное присваивание


В Третьем Манифесте предписывается не только присваивание, но и то, что называется в нем множественным присваиванием. Множественное присваивание – это операция, которая позволяет «одновременно» выполнить несколько индивидуальных присваиваний без какой-либо проверки целостности до конца выполнения всех индивидуальных присваиваний. Например, показанная ниже операция «двойного DELETE» с логической точки зрения является множественным присваиванием:

DELETE S WHERE S# = S#('S1') ,

DELETE SP WHERE S# = S#('S1') ;

Обратите внимание на запятую после первой операции DELETE, синтаксически указывающую, что это еще не конец всего оператора.

В [1] поднимает несколько вопросов относительно множественного присваивания. Вот соответствующая цитата:

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

Мои подробные ответы: Я не понимаю, как вы собираетесь реализовывать множественное присваивание.

Мы полагаем, что оно будет реализовываться в соответствии с определением. Семантика операции определяется в Третьем Манифесте [14] и в отдельной статье [13].

Если имеется, например, пять индивидуальных присваиваний, то они будут выполняться в заданном порядке сверху вниз, или же этот порядок произволен, или же считается, что они будут выполняться в параллель?


Полный ответ на этот вопрос содержится в [13] и [14]. При небольшом упрощении основная идея состоит в том, что (a) вычисляются выражения из правых частей индивидуальных присваиваний (в произвольном порядке, поскольку порядок не является существенным), а затем (b) выполняются присваивания переменным из левых частей в том порядке, в каком они написаны.

Ваш алгоритм перезаписи для устранения нескольких ссылок на одну и ту же переменную порождает больше проблем, чем разрешает.

Работы [13] и [14] действительно включают некоторый «алгоритм перезаписи» для объединения – не устранения! – «нескольких ссылок на одну и ту же переменную». Если этот алгоритм действительно порождает «больше проблем, чем разрешает», было бы полезно привести конкретные черты этих проблем.

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

Фраза «можно было бы предположить» здесь, по-видимому, относится к алгоритму перезаписи. В этом алгоритме, конечно, не предполагается, что «между индивидуальными присваиваниями отсутствуют побочные эффекты». На самом деле, все наоборот: основная суть алгоритма состоит в том, чтобы точно соблюсти действие побочных эффектов, а не в том, чтобы их утратить.

Если принять это предположение, то, очевидно, будут существовать некоторые упорядоченные множества присваиваний (обычно оформляемые в виде транзакций), которые невозможно переписать в виде множественного присваивания, поскольку это приведет к результату, отличному от ожидаемого …

Я не могу слегка не упрекнуть Критика B за его использование фразы «упорядоченные множества» … Однако более важно то, что мы хотели бы увидеть пример последовательности присваиваний, которую было бы нельзя переписать в виде множественного присваивания. Очевидно, что можно было бы попытаться написать что-то вроде следующего:

X := x ;

Y := f(X) ;

Но следующее множественное присваивание приведет к тому же ожидаемому результату:

X := x ,

Y := f(x) ;

Мне нравится идея множественного присваивания, но не за счет отказа от транзакций и, следовательно, не за счет отказа от отложенной проверки ограничений.

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

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


Множественные спецификации группировки


Теперь мы знаем, каким образом можно определять раздел GROUP BY для выполнения группировки по отдельным столбцам или выражениям, для проведения одномерного анализа с использованием ROLLUP или многомерного анализа с использованием CUBE, для создания произвольной коллекции групп с использованием GROUPING SETS. Требуется знать еще одну вещь: каким образом можно комбинировать эти возможности и использовать их совместно в одном разделе GROUP BY. Раздел GROUP BY может содержать несколько спецификаций группировки, разделенных запятыми. В каждой спецификации можно использовать любую из обсуждавшихся возможностей. Общее число групп, производимых разделом GROUP BY, получается путем перемножения числа групп, производимых каждой спецификацией группировки. Например, GROUP BY state производит три группы, и GROUP BY sex производит две группы, поэтому GROUP BY state, sex производит шесть групп. Аналогично, если GROUP BY ROLLUP (state, county) производит семь групп, и GROUP BY sex производит две группы, то GROUP BY ROLLUP (state, county), sex произведет 14 групп, формируемых по всем возможным комбинациям спецификаций группировки.

Синтаксическая диаграмма на рис. 1 показывает, как можно использовать различные виды группировки в расширенном разделе GROUP BY. DB2 UDB также поддерживает некоторые комбинации методов группировки (например, можно использовать ROLLUP и CUBE внутри операции GROUPING SETS), но для упрощения они отсутствуют в диаграмме. В документации DB2 UDB содержится детальная информация об этих комбинациях.

Рис. 1. В расширенном разделе GROUP BY возможны разные спецификации группировки



Модель компонентных объектов. Основные понятия.


Художник не рисует картину по пикселам. Сначала на холст ложатся грубые штрихи, и только потом наступает прорисовка деталей. Идея компонентного подхода в программировании возникла одновременно с программированием, поскольку она соответствует, если можно так выразиться, естественной модульности аналитического мышления, когда решение достаточно объемной задачи начинается с ее разбиения на несколько подзадач, те, в свою очередь, дробятся на еще более мелкие и иерархически более зависимые фрагменты и т.д. вплоть до тех деталей, решение которых элементарно. По той же причине компоненты упрощают отладку приложения- вспомните поиск корня методом половинного деления. Более того, сборка из независимых компонент существенно увеличивает масштабируемость, так как в зависимости от требуемой функциональности мы можем добавить в него те или иные компоненты или, наоборот, изъять так, чтобы приложение не обрушивалось, а плавно и корректно деградировало. Мы можем физически "размазать" приложение по сети, установив разные компоненты на разные компьютеры, и снова повысить тем самым масштабируемость, но уже в плане производительности. Наконец, компоненты универсальны, как атомы или гены: компоненты, из которых состоит ваше приложение, в различных сочетаниях с другими компонентами могут использоваться при построении новых приложений, т.е. именно благодаря им суждено сбыться вековой мечте человечества о повторной используемости кода, с которой мы начали наш рассказ. Итак, компоненты- это круто. Теперь несколько слов о том, как это все работает.

Распределенная компонентная модель объектов (DCOM)- это (см.[1]) набор стандартов построения, размещения и взаимодействия компонент и реализующих их механизмов, которые позволяют объектам внутри компонент посылать вызовы другим компонентам, а также принимать и обрабатывать запросы от других компонент вне зависимости от их положения на компьютере или в сети, от способов реализации, от того, являются ли они прикладными или объектами операционной системы и т.д.
Для этого объекты (D)COM "договариваются" о предоставлении друг другу сервисов через строго определенные интерфейсы, которые на идеологическом уровне можно рассматривать как своего рода обязательство объекта предоставить заявленную функциональность при условии вызова в соответствии с опубликованными им правилами, а на бытовом- как группы семантически связанных функций, объединенных в абстрактные виртуальные классы. Пусть, например, имеем некоторый набор функций, оформленный в виде

struct I1 { virtual void f11()=0; virtual int& f12()=0; ... }

Любой класс, намеренный использовать эту функциональность, может быть оформлен, например, в виде наследования:

class AnyCls : public I1 ...

Однако, что предпринять, если нам потребовалось расширить набор функций? Переписать struct I1 означает вернуться к проблемам, описанным в п.1. Следовательно, логично будет свести дополнительные функции в новый интерфейс:

struct I2 { virtual void f21()=0; ... }

А как быть тогда с AnyCls? Интерфейсов может не один и не два, а множественное наследование выручает до известного предела, после которого возникают разного рода проблемы, начиная от слабой читаемости программы и заканчивая потерями в производительности. Решение состояло в использовании вложенных классов:

class AnyCls { protected: ... public: AnyCls {...;} class C1 : public I1 { public: C1() {} virtual void f11(); virtual int& f12(); ... } m1; class C2 : public I2 { public: C2() {} virtual void f21(); ... } m2; ... } void AnyCls::C1::f11(){ ... ;} ... , которые, с одной стороны, упакованы в родительском классе и не видны за его пределами, а с другой, имеют доступ к его элементам. Заметим, что с помощью функций CoCreateInstance или IUnknown::QueryInterface (см.ниже) клиент работает только с указателями на таблицы виртуальных функций интерфейсов, т.е. реально создав объект того же класса AnyCls, он тем не менее не имеет указателя на него. Таким образом он никогда не получает прямого доступа к внутренним данным объекта, даже если бы они не были protected.


Моделированию на С++ основных механизмов работы COM посвящена, например, [2], часть IV и желающие всегда могут обратиться к этой литературе, а также к [3], которая по справедливости считается основополагающей работой в области компонентного подхода, до сегодняшнего дня не утратившей своей актуальности.

Интерфейсы являются настолько основополагающим понятием COM, что для их описания используется специальный язык- IDL (язык определения интерфейсов), по своей структуре очень похожий на С++. В определении интерфейса описываются заголовки входящих в него функций с указанием их имен, возвращаемых типов, входных и выходных параметров, а также их типов. Это и есть та часть контракта, которая будет сообщать, что может и как надо вызывать объект, взявший на вооружение данный интерфейс. Каждый интерфейс получает свой 16-байтовый глобальный идентификатор, который присваивается ему программой генерации на основании времени создания, адреса сетевой платы и пр. После опубликования интерфейс фиксируется и дальнейшие изменения в нем не допускаются. IDL допускает наследование, так что возможны производные интерфейсы. Более того, все интерфейсы являются производными от одного базового интерфейса под названием IUnknown. В состав IUnknown входят 3 метода. QueryInterface используется для получения указателей на другие интерфейсы объекта, при условии, что указатель на начальный интерфейс был получен при помощи CoCreateInstance. Методы AddRef и Release применяются для подсчета ссылок, т.е., грубо говоря, сколько клиентов в данный момент используют интерфейсы данного объекта. AddRef выполняется автоматически, как только со стороны клиента поступает запрос на указатель интерфейса. Однако если внутри клиентской программы происходит порождение новой ссылки на интерфейс, о которой серверный объект не догадывается, вызов AddRef возлагается на клиента. Клиент не имеет права разрушить серверный объект, но по окончании работы с ним он обязан вызвать метод Release, который уменьшит на единичку число пользователей объекта.


Когда оно станет равным 0, объект сам себя уничтожит.

В том случае, если объект создан как in-process сервер (dll), т.е. выполняется внутри клиентского процесса, особых проблем не возникает. Если же объект реализован в виде out-of-process сервера, выполняющегося как отдельный процесс на том же или удаленном хосте, немедленно появляется вопрос о передаче указателя на интерфейсы и параметров вызовов методов между процессами. Вопрос нетривиальный тем более потому, что различные компьютеры могут использовать разные форматы представления данных. Ответ состоит в использовании proxy-объекта внутри клиентского процесса и заглушки внутри сервера. Proxy- это обычный COM-объект, который представляет те же интерфейсы, что и вызываемый клиентом, однако вместо непосредственного вызова методов он принимает переданные клиентом параметры и упаковывает их для передачи средствами межпроцессной или межмашинной (RPC- remote procedure call) коммуникации. Заглушка на стороне сервера принимает и распаковывает эти параметры, вызывает соответствующий метод серверного объекта и передает их ему. Возвращение результатов клиенту происходит по той же схеме в обратном направлении. Такой процесс называется маршалингом (демаршалингом). Обычно все развитые средства разработки COM-объектов предоставляют возможность автоматической генерации proxy и заглушки для интерфейса. Если разработчика по каким-то причинам это не устраивает, он может запрограммировать нестандартный маршалинг при помощи определенного в COM интерфейса IMarshal. Возникает интересный момент: если код маршалинга способен автоматически создаваться на стадии компиляции программы, то почему бы не использовать эту возможность для динамической генерации маршалеров во время выполнения программы? Такой подход (он известен как позднее связывание), несмотря на дополнительные затраты, существенно повышает гибкость программирования, ибо решение о вызовах тех или иных интерфейсов может приниматься по ходу дела в зависимости от прикладной логики.


Однако для этого клиент должен "на лету" уметь получать доступ к информации об интерфейсах, необходимой для выполнения маршалинга. Этим требованиям отвечает библиотека типов, которая перечисляет все интерфейсы, поддерживаемые тем объектом, для которого она создается, и описывается в терминах уже упоминавшегося нами выше IDL. Как и для COM-объектов, при установке в registry записывается ID библиотеки и ее местоположение. При вызове средствами СОМ API библиотека типов предоставляет интерфейс ITypeLib, который, в свою очередь, позволяет получить указатели на интерфейс ITypeInfo для каждого интерфейса, перечисленного в библиотеке, с помощью которых добывается информация о параметрах методов и их типов, необходимая для динамического маршалинга.

Обычно основным потребителем этой информации оказывается интерфейс IDispatch (естественно, производный от IUnknown), который наверняка знаком программистам на Visual Basic. Методы этого интерфейса GetTypeInfo и GetTypeInfoCount позволяют динамически запрашивать запущенный объект относительно информации о всех его интерфейсах. Другой метод, IDispatch::Invoke фактически представляет собой оператор switch, который в зависимости от переданного значения идентификатора (DISPID) вызывает тот или иной метод диспинтерфейса. Иногда в литературе можно встретить суждение, что Visual Basic не работает с указателями, поэтому для него потребовалось создать некий универсальный механизм, умеющий работать только с одним интерфейсом IDispatch. Это не совсем корректное замечание. Во-первых, в свете нашего разговора о маршалинге очевидно, что единственная пара proxy-заглушка для IDispatch не в состоянии предусмотреть преобразование параметров для самых различных методов диспинтерфейса, поэтому часть преобразования неявно выполняет сам клиент, упаковывая параметры в variant. Во-вторых, только первая версия Visual Basic распознавала исключительно диспинтерфейсы. Во всех остальных случях QueryInterface совершенно аналогично возвращает указатель на виртуальную таблицу, содержащую реализацию запрашиваемого интерфейса.


В терминах Visual Basic это известно как объектная ссылка (object reference). Т.е., если переменная объявлена как dim x As <Something>, где <Something>№ Object, то будет использоваться раннее связывание. В первую очередь компилятор (VB5) будет искать способы прямого вызова через виртуальную таблицу (vtable binding) и только в случае неудачи прибегнет к диспинтерфейсу. При этом по информации в библиотеке типов он постарается найти DISPID и кэшировать его, чтобы сэкономить на достаточно дорогом вызове GetIDsOfNames в период выполнения. При ссылках типа dim x As Object или Set x = y, где создание объекта y происходит во время работы программы, компилятор, естественно, лишен возможности сделать какие-либо предположения о природе объектов х и не сможет оптимизировать их вызовы. В этом случае, как нетрудно догадаться, будет иметь место позднее связывание. Позднее связывание преимущественно характерно для Visual FoxPro 5.0, в него также включена оптимизация для поддержки vtable binding- см. функцию sys(2333). Иногда интерфейсы описываются как двойственные, т.е. содержащие диспинтерфейсные представления для виртуальных таблиц своих методов.

Одним из ярких проявлений преимуществ компонентной модели служит OLE-автоматизация, или программируемость, тесно связанная с двойственными и диспинтерфейсами. OLE-автоматизация явилась одним из этапов развития COM, и практически каждый наверняка с ней сталкивался. Речь идет о том, что при всей полноте своей функциональности приложение будет представлять еще большую ценность для разработчиков, если позволит использовать эту функциональность не только в интерактивном режиме, но и из пользовательских программ. Вместо того, чтобы снабжать приложение дополнительным API для этих целей, автор может просто оформить его как OLE Automation сервер, что приблизительно означает, что приложение сознательно "засвечивает" вовне некоторые из своих методов, использовавшихся для внутренней реализации заявленной функциональности. При этом, во-первых, достигается экономия программистского труда: автору не нужно сначала разрабатывать приложение, а потом писать API к нему.


Во-вторых, пользователь мыслит в тех же категориях, что и автор, что значительно облегчает освоение программы. В третьих- и это плюс, характерный для всей технологии COM,- предоставленная функциональность остается на вооружении пользователя при разработке им каких-то своих программ, никак не связанных с данным OLE Automation сервером. Простой пример: если у нас на компьютере установлен Microsoft Office, то зачем нам изобретать велосипед и писать программу проверки орфографии, если мы можем создать объект Word.Application и вызвать для него метод SpellChecking:

dim x As New Word.Application Debug.Print x.SpellChecking("Abra Cadabra") ...

То же самое относится, например, к использованию статистических функций Microsoft Excel и т.д. В качестве OLE Automation серверов могут рассматриваться не только офисные приложения, но и сами средства разработки- тот же Visual Basic или Visual FoxPro- и даже тяжелые серверные продукты семейства Microsoft BackOffice, например, Microsoft SQL Server, который с помощью SQL-DMO (distributed management objects) обеспечивает выполнение практически всех административных функций из клиентского приложения (разумеется, при наличии соответствующих прав доступа).

dim oSQLServer As New SQLOLE.SQLServer oSQLServer.Connect "ntalexejs", "sa"

dim newdb As New SQLOLE.Database newdb.Name = "sqlole"

newdb.ExtendOnDevices ("oledat=5") newdb.TransactionLog.DedicateLogDevices ("olelog=2")

oSQLServer.Databases.Add newdb


Модель "объект - качество".


Евгений Григорьев. ()

Основная цель этой статьи - показать призрачность проблемы "объекты или отношения" являющейся одним из основных вопросов моделирования данных. Автор основывается на том, что информация, возникающая в процессе познания окружающего мира, обладает вполне определенной структурой. Ее анализ приводит к модели, позволяющей описывать данные одновременно и как множество отношений и как множество объектов.

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

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

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

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

Этот подход выглядит наиболее логичным. И все же в нем существует противоречие, которое не позволяет считать его полностью верным. Вот цитата того же Дейта "…фундаментальный принцип реляционной модели… можно сформулировать следующим образом - вся информация в базе данных должна быть явно представлена в терминах отношений и никак иначе". Сразу же возникает вопрос - каким же образом будет сохраняться в такой базе данных информация о некотором произвольно сложном (т.е.ненормализованном) значении? Подход, предлагаемый Дейтом, не дает на него ответа.

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

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


Модели данных


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

Работ в этой области было действительно мало, а стандартную модель многие хотели бы видеть, но пока шансов немного.



МУЛЬТИПЛЕКСОР ПРОТИВ ШЛЮЗА - ЗА И ПРОТИВ


Windows NT представляет собой хороший пример операционной

системы, мультиплексирующей несколько стеков протоколов - NetBEUI/SMB, TCP/IP и Novell

IPX/NCP (компонент NWLink реализует протокол сетевого уровня IPX, а NWCS - протокол

NCP, обеспечивающий доступ к файлам и принтерам).

В составе Windows NT Server

3.51 поставляется шлюз Gateway Service for NetWare, который обеспечивает для всех клиентов

этого сервера прозрачный доступ к файл- и принт-сервисам серверов NetWare. Другим

примером шлюза является компонент Microsoft BackOffice - SNA Server. Этот сервер

обеспечивает клиентам Windows NT прозрачный доступ к мэйнфреймам и мини-компьютерам

IBM.

У каждого из названных подходов свои достоинства и недостатки.

К

достоинствам шлюзов относится то, что при их использовании в сеть вносятся минимальные

изменения: дополнительное программное обеспечение устанавливается только на одном из

серверов, а клиентские станции остаются без каких-либо изменений. Полностью сохраняется

привычная пользовательская среда.

При мультиплексировании протоколов

дополнительное программное обеспечение- соответствующие стеки протоколов - должно быть

установлено либо на каждую клиентскую машину, которой может потребоваться доступ к

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

обслуживания клиентов из другой сети. В Windows NT имеются средства борьбы с

избыточностью, свойственной этому подходу: операционная система может быть

сконфигурирована для работы с несколькими стеками протоколов, но динамически загружаются

только те, что нужны сейчас.

В принципе при работе с несколькими стеками протоколов

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

командами, правилами и методами адресации. В Windows NT сделана попытка в какой-то

степени облегчить жизнь пользователю в этой ситуации. Независимо от используемого

протокола прикладного уровня (например Microsoft SMB или Novell NCP) ему предоставляется

один и тот же интуитивный графический интерфейс, с помощью которого он просматривает и


выбирает нужные удаленные ресурсы. Однако некоторые сервисы пока еще не охвачены этим

универсальным средством; большинство сервисов стека TCP/IP - ftp, tftp, r*, ping и другие -

используют режим командной строки. Пользователь должен выучить названия команд, их

синтаксис и значения многочисленных ключей. Telnet - еще один сервис стека TCP/IP-

использует для диалога собственный графический интерфейс, поскольку по своей природе

эмуляция терминала значительно отличается от файлового сервиса.

Как и всякий

централизованный ресурс, шлюз снижает надежность сети. С другой стороны, централизация

облегчает контроль доступа пользователей к "чужой" сети, диагностику и обработку

ошибочных ситуаций.

Шлюз является более медленным средством по сравнению с

переключаемыми стеками протоколов. Во-первых, из-за относительно больших затрат времени

на собственно процедуру трансляции, а во-вторых, из-за задержек запросов в очереди к

разделяемому всеми клиентами шлюзу. Это делает шлюз плохо масштабируемым

решением.


Наблюдения


Наблюдение может быть либо новым, первичным, то есть оно производится над новым, вновь созданным объектом, и тогда объект идентифицируется в силу того, что он создан; либо наблюдение может быть повторным, то есть проводится над объектами, над которыми ранее уже проводились какие-то наблюдения, и тогда объект или объекты выбираются на основе ранее зафиксированных параметров, либо через явное обозначение объекта.

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

Создание нового наблюдения может инициироваться несколькими способами:

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

Источником информации для наблюдения могут быть вводимые пользователем данные либо данные, автоматически поступающие в вычислительную систему по каким-либо каналам.

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

Рис. 3

На рис. 3 показано соотношение между наблюдениями и состояниями (si) для одного объекта. Прямоугольники обозначают наблюдения, двойная линия со стрелкой указывает наблюдения, определяющие исходные для наблюдений состояния. Начиная с момента t3 наряду с состоянием s2 возникает s2' и состояние объекта расщепляется.

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

Тип наблюдения включает в себя задание областей определения параметров, участвующих в нем. Обычно для того, чтобы задавать область определения параметров в моделях данных вводится понятие домена. Например, в модели IDEF1X [3] домен определяется как неизменяемый класс, для которого существует наперед заданное (возможно бесконечное) множество экземпляров. В то же время, на практике понятие домена обычно в чистом виде не реализуется или реализуется только на уровне простых типов данных (домены "целое", "вещественное" и т.п. и их подмножества), т.е. определение домена для какого-либо атрибута эквивалентно определению типа данных для соответствующей переменной включающего языка. Требование неизменности домена возникает из-за того, что если область определения какого-либо атрибута изменяется, то требуется проверить все уже существующие значения этого атрибута на предмет соответствия новой области определения. Более того, если даже это сделано, то непонятно, как быть со значениями, которые больше не принадлежат домену. С другой стороны, возможность ограничения области определения атрибутов изменяющимся во времени множеством сущностей все же поддерживаются через механизмы ограничений целостности, - например, foreign key.

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


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

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

В типе наблюдения могут описываться ограничения, накладываемые на состояния объекта. Эти ограничения определяют ожидаемое поведение объекта при данном типе наблюдения:

Допустимость того или иного состояния Допустимость перехода из одного состояния в другое и взаимосвязи между наблюдениями

Допустимость состояния определяет соотношение между параметрами объекта, фиксируемыми в данном наблюдении. Например, систолическое артериальное давление никогда не может быть меньше диастолического. Надо отметить, что подобные ограничения являются свойством конкретного типа наблюдения, а не объекта. Так, несмотря на то, что в одном обследовании может присутствовать ограничение на возраст, в другом типе обследования оно может быть снято или изменено.

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

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

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

Итак, при описании типа наблюдения можно указывать такие его характеристики, как

Описания параметров Определение форм ввода и вывода Определение ограничений Определение связанных с проводимым наблюдений Права доступа


НАПРАВЛЕНИЕ СОГЛАСОВАНИЯ


В то время как на трех нижних уровнях модели

OSI протоколы почти всегда симметричны по отношению к взаимодействующим компьютерам,

протоколы прикладного уровня, как правило, несимметричны и состоят из клиентской части,

запрашивающей и потребляющей удаленный ресурс, и серверной части, предоставляющей этот

ресурс в общее пользование. У клиентской части протокола даже имя особенное- редиректор

или инициатор запросов. Такие протоколы обычно называют протоколами типа "клиент-

сервер".

При организации взаимодействия двух разнородных сетей в общем случае

нужно решать две задачи - обеспечение доступа клиентов сети А к серверам сети В и

обеспечение доступа клиентов сети В к серверам сети А. Эти задачи независимы, и их можно

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

выяснить, необходимо ли полное решение или достаточно и частичного.

Большинство

имеющихся на рынке продуктов предоставляет только однонаправленное согласование

прикладных сервисов. Например, шлюз Gateway Service for NetWare обеспечивает клиентам

Windows NT доступ к файл- и принт-сервисам NetWare, но не предоставляет клиентам NetWare

доступ к аналогичным сервисам Windows NT. Обратная задача может быть решена с помощью

продукта File and Print Services for NetWare, устанавливаемого на серверах Windows NT. Он

представляет собой серверную часть протокола NCP, которая в режиме мультиплексирования

работает параллельно с серверной частью "родного" для Windows NT протокола

SMB.



Настройка


Прежде всего, в домене необходимо создать учетную запись пользователя, под которой будут работать службы SQL Server Agent и MSSQLServer. Затем необходимо будет внести этого пользователя в группу администраторов ПК, на котором работает SQL Server, и создать для него локальный профиль. Для создания профиля достаточно зайти под именем этого пользователя в операционную систему. Затем необходимо настроить службы SQL Server Agent и MSSQLServer. Запустив оснастку Services, найдем в ней (воспользовавшись меню Start > Programs > Administrative Tools > Services) службы SQLSERVERAGENT и MSSQLSERVER. В свойствах этих служб установим вид запуска (Startup type) как автоматический (Automatic) на закладке General, а на закладке Вход (Logon) укажем использование учетной записи вновь созданного пользователя (в нашем случае - PPDMN\vfc - рис. 3).

Для успешной работы с электронной почтой в SQL Server, необходимо использование почтового клиента и сервера, умеющих работать по протоколу MAPI. В нашем случае сервером будет MS Exchange, а клиентом - MS Outlook, входящий в состав MS Office (не путать с Outlook Express). На сервере MS Exchange необходимо создать почтовый ящик для учетной записи нового пользователя (PPDMN\vfc), а на клиенте (то есть на ПК, где работает SQL Server) установить MS Outlook и создать почтовый профиль этого пользователя. Для создания почтового профиля необходимо зайти, используя новый логин, в ОС и открыть окно свойств MS Outlook, кликнув для этого правой кнопкой мыши по иконке на рабочем столе. Появится окно, изображенное на рис. 4.



Кликнем на кнопке Добавить и увидим следующее окно (рис. 5), где выберем автоматическое создание конфигурации для MS Exchange Server. Далее укажем NetBIOS имя (или IP-адрес) сервера MS Exchange и имя почтового ящика (рис. 6).

Если все было сделано правильно, мастер установки MS Outlook успешно завершит создание профиля. Теперь, открыв окно свойств Outlook, увидим, что появилась новая конфигурация для работы с почтой (рис. 7).






С настройкой почтового профиля закончили - пора настроить почту для почтовых сеансов SQLAgentMail и SQLMail. Откроем окно свойств SQLMail и введем имя профиля - после нажатия на кнопку "Test" система должна отрапортовать об успешном старте и останове почтового сеанса MAPI (рис. 8).




Теперь очередь SQL Server Agent. Откроем окно его свойств и на вкладке Общие (General) введем то же имя профиля, если мы используем одну и ту же учетную запись для обеих служб.,После нажатия на кнопку "Test" происходит отправка тестового письма и появляется сообщение об успешном тестировании (рис. 9).




Настройка переменных.


Если запустить mysqladmin -variables, то можно увидеть примерно такую картину.

Variable_name Value

back_log 5
connect_timeout 5
basedir/usr/local/
datadir/home/www/data/
delayed_insert_limit100
delayed_insert_timeout300
delayed_queue_size1000
join_buffer 131072
flush_time0
key_buffer8388600
language/usr/local/share/mysql/english/
logOFF
log_updateOFF
long_query_time10
low_priority_updatesOFF
max_allowed_packet1048576
max_connections100
max_connect_errors10
max_delayed_insert_threads20
max_join_size4294967295
max_sort_length1024
net_buffer_length16384
pid_file/usr/local/var/mysqld.pid
port3306
protocol_version10
record_buffer131072
skip_lockingON
skip_networkingOFF
socket/tmp/mysql.sock
sort_buffer2097144
table_cache64
thread_stack65536
tmp_table_size1048576
tmpdir/tmp/
version3.22.27
wait_timeout28800

От настройки этих переменных сильно зависит производительность сервера. Надо сказать, что не существует наилучших значений для всех случаев. Для каждого конкретного сервера и поставленных задач нужно выбирать свои значения.

Рассмотрим подробнее эти переменные (......выделены наиболее важные из них ).

back_log - этот параметр показывает, сколько одновременно может быть невыполненных запросов на соединение (connection requests). Параметр имеет большое значение в тех случаях, когда к MySQL поступает ОЧЕНЬ много запросов на соединение в малый промежуток времени.

Когда к MySQL поступает connect-запрос, производятся следующие действия - проверяется, разрешен ли доступ к серверу, и если разрешен, то порождается новый процесс. Все это занимает достаточно мало времени. Однако если за это время поступит еще один connect-запрос, то он заносится в очередь. Параметр back_log определяет длину этой очереди. Если количество запросов превысит данное значение, то все непомещающиеся запросы будут игнорироваться. По умолчанию значение back_log равно 5, что вполне достаточно для большинства серверов.

Максимально значение back_log ограничено операционной системой.


connect_timeout - количество секунд, которое сервер ждет connect-пакета, по истечении этого времени будет выдан пакет " соединение ". Для более детальных разъяснений см. описание TCP/IP протокола.

delayed_insert_timeout - как долго поток INSERT DELAYED будет ожидать данных для INSERT. Более подробно значение слова DELAYED расписано в описании INSERT запроса.

delayed_insert_limit - INSERT DELAYED вставив количество записей, равное delayed_insert_limit, проверяет, есть ли SELECT-запрос к этой же таблице. Если есть, то выполняется SELECT, и только после этого продолжается INSERT.

delayed_queue_size - Для выполнения INSERT DELAYED будет выделятся очередь длиной в delayed_queue_size строк. Когда очередь заполниться все остальные конкурирующие INSERT DELAYED запросы будут ждать, пока не освободиться место в этой очереди.

flush_time - Если значение больше нуля, то каждые flush_time секунд все таблицы будут закрываться. Это позволит освобождать неиспользуемые ресурсы и синхронизировать данные на диске.

join_buffer - Величина буфера, который используется для полных JOIN запросов (.. для полного объединения двух таблиц без использования индексов ). Память под такой буфер выделяется один раз для каждого запроса. Увеличение параметра ускорит выполнение таких запросов. Более естественный путь ускорить полные JOIN запросы - использовать индексы.

key_buffer - Величина буфера ( байтах ), который используется для индексов. Этот буфер общий для всех потоков. Если используется много DELETE или INSERT запросов к таблицам с большим кол - индексов, то увеличение значения повысит скорость выполнения таких запросов. Для достижения еще большей скорости нужно использовать LOCK TABLES.

long_query_time - Если время выполнения запроса превысит данное значение ( сек.), то внутренний счетчик slow_queries будет увеличен на 1. Посмотреть значение счетчика можно командой mysql>status.

max_allowed_packet - Максимальный размер пакета для передачи данных. Данные между клиентом и сервером передаются пакетами.


В начале создается пакет длиной net_buffer_length затем, если размер данных больше, то размер пакета увеличивается до необходимого значения, при этом его длина не может превысить значение max_allowed_packet. Если используются поля BLOB большого размера, то рекомендуется увеличить значение этого параметра. В идеале нужно присвоить этой переменной значение размера самого большого BLOB поля.

max_connections - Максимальное количество открытых соединений. Определяет, сколько клиентов одновременно могут работать с сервером. Увеличение параметра увеличивает количество используемых дескрипторов файла.

max_connect_errors - Если в процессе общения с клиентом произошел обрыв соединения (interrupt connection), то счетчик ошибок для хоста клиента увеличивается на 1. Когда значение этого счетчика достигнет max_connect_errors, то все последующие соединения с данного хоста будут игнорироваться. Для обнуления счетчиков использовать команду FLUSH HOSTS.

max_delayed_threads - Максимальное количество потоков, которые выполняют INSERT DELAYED. Если будет вызван запрос INSERT DELAYED, а при этом достигнуто значение max_delayed_threads, то такой запрос будет выполнен как обычный INSERT ( опции DELAYED).

max_join_size - Максимальное количество записей, которое может быть возвращено полным JOIN запросом. Если в JOIN запросе кол - записей превысит это значение, то будет возвращена ошибка. Увеличение значения этого параметра позволит выполнять большие запросы, но при этом следует учитывать, то такие запросы съедают много процессорного времени и могут содержать миллионы записей.

max_sort_length - При сортировке BLOB или TEXT полей из каждого поля берутся только первые max_sort_length байт, а остальные отбрасываются и при сортировке не учитываются.

max_tmp_tables - Максимальное количество временных таблиц, которые клиент может сохранять открытыми одновременно. На самом деле в версии 3.22 это поле ни на что не влияет.

net_buffer_length - Размер пакета для передачи данных (. max_allowed_packet) Обычно этот параметр не нужно изменять, но если у вас очень мало памяти, то его можно уменьшить до ожидаемого размера результата запроса.



record_buffer - Каждый поток, который осуществляет последовательное сканирование таблиц ( это происходит в SELECT запросах ), для каждой таблицы, участвующей в сканировании выделяет память размером record_buffer. Если будет много запросов, требующих последовательно сканировать таблицы, то значение этого параметра рекомендуется увеличить.

sort_buffer - Каждый поток, который осуществляет сортировку данных (ORDER BY или GROUP BY), выделяет память размером sort_buffer. Для повышения быстродействия запросов с ORDER BY или GROUP BY это значение необходимо увеличить.

table_cache - Количество открытых таблиц для ВСЕХ потоков. Увеличение значения приведет к увеличению количества используемых дескрипторов файла. MySQL необходимо 2 дескриптора для каждой открытой таблицы.

tmp_table_size - Максимальный размер временных таблиц. При превышении этого размера возвращается ошибка table tbl_name is full. При использовании сложных GROUP BY запросов значение нужно увеличить.

thread_stack - Размер стека для каждого потока. Обычно значение по умолчанию является достаточным.

wait_timeout - Время, которое поток ждет повторного обращения. Если за это время к потоку не было ни одного обращения, то поток убивается.

Параметры table_cache, max_connections и max_tmp_tables определяют, как много файлов сервер будет держать открытыми. Максимально количество открытых файлов для каждого процесса ограничивается операционной системой. На многих ОП это количество можно увеличить. Для более детальной информации см. руководство по вашей ОП.

table_cache зависит от max_connections. Например, если у вас 200 открытых соединений, то вам может понадобиться до 200*n открытых таблиц, где n - количество таблиц, участвующих в запросах.

MySQL при работе с таблицами использует хорошо масштабируемые алгоритмы, так что MySQL может работать даже при малых объемах памяти. Естественно для лучшей производительности нужно больше оперативной памяти.

Изменить значение настроек можно при запуске сервера опцией -O, например,

>safe_mysqld -O key_buffer=1 6M ( значениях, которые измеряются в байтах, для сокращения, можно использовать буквы К и М ).

Если у вас много памяти и много таблиц, то для увеличения производительности, при запуске сервера можно использовать такие значения. >safe_mysqld -O key_buffer=16M -O table_cache=128 \ -O sort_buffer=4M -O record_buffer=1M &

Если у вас мало памяти и ожидается мало соединений, то лучше сервер запускать с такими опциями >safe_mysqld -O key_buffer=512k -O sort_buffer=100k \ -O record_buffer=100k &

или даже > safe_mysqld -O key_buffer=512k -O sort_buffer=16k \ -O table_cache=32 -O record_buffer=8k -O net_buffer=1K &

Необходимо принимать во внимание, что, если сервер сконфигурировать для использования малого объема памяти, то в случае большого числа соединений может возникнуть " своппинга ", которая сильно затормозит сервер.