Метод черного ящика - разработка эффективных программ под Oracle

Продолжаем разговор о подходах и методах разработки эффективных, производительных программ по СУБД Oracle. Вот, что по этому поводу думает эксперт в данной области Том Кайт.

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

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

Единственная наиболее часто встречающаяся причина неудачи связана с недостаточными практическими знаниями самой базы данных, т.е. отсутствие общего представления об основном инструменте, который применяется. Метод черного ящика предполагает намеренное абстрагирование разработчиков от базы данных; фактически он поощряет отсутствие вообще каких-либо знаний о базе данных! Во многих случаях этот метод препятствует ее использованию. Похоже, что такой подход был порожден страхом, неуверенностью и сомнениями. Было принято считать, что базы данных, SQL, транзакции и целостность данных "трудны" для понимания. Итогом стало решение никого не заставлять делать что-то "трудное". В результате исповедующие такую философию разработчики относятся к базе данных как к черному ящику и поручают генерацию всего необходимого кода какому-то программному средству. Они стараются отгородиться множеством защитных уровней, чтобы даже не касаться этой "трудной" базы данных.

Я никогда не мог понять такой подход к разработке базы данных, частично по-тому, что лично мне изучение Java и С далось значительно труднее, чем изучение концепций, лежащих в основе баз данных. Теперь я знаю языки Java и С довольно хорошо, но для овладения практическими навыками их применения мне понадобилось намного больше времени, чем это было при освоении баз данных. В случае базы данных нужно иметь представление о ее работе, но вовсе не обязательно знать абсолютно все ее внутренние и внешние особенности. При программировании на С или JavajJ2EE необходимо знать все внутренние и внешние функций, количество которых в этих языках поистине огромно.

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

Типичный сценарий мог бы выглядеть следующим образом.

  • Разработчики полностью овладели инструментом ля построения графических пользовательских интерфейсов или языком, который они используют для создания такого интерфейса (таким как Java). Во многих случаях за их плечами были долгие недели, если не месяцы, обучения.
  • В команде потратили ноль часов на обучение Oracle и ноль часов на обретение опыта работы с Oracle. Большинство членов команды вообще не имеют опыта взаимодействия с базами данных. Они также получили указание быть "независимыми от базы данных" - указание (выданное руководством или выведенное из теоретического свода правил), следовать которому у них мало шансов по многим причинам. Самой очевидной причиной является отсутствие у членов команды достаточных знаний о том, что собой представляют базы данных или что они делают, которые позволили бы прийти к наименьшему общему знаменателю среди баз данных.
  • Разработчики сталкиваются с многочисленными проблемами, которые касаются производительности, целостности данных, зависания приложения и т.п. (но зато им удается создавать очень привлекательные окна).

В результате неизбежного возникновения проблем с производительностью ко мне обращались за помощью в их решении (в прошлом, как обучающийся разработчик, я часто сам был причиной таких проблем). В одном конкретном случае я не сумел вспомнить точный синтаксис новой команды, которой нужно было воспользоваться. Попросив принести справочное руководство по SQL, я получил в руки документ для версии Oracle 6.0. Сама разработка велась на основе версии 7.3 - по прошествии пяти лет после выхода версии 6.0! Этот документ был единственным, с чем имели дело разработчики, но было похоже на то, что данный факт их совершенно не смущал. Они даже не думали о том, что средства, которые они должны были знать для успешного проведения трассировки и настройки, в версии 6 в действительности не существовали. Их не волновало, что за те пять лет, которые прошли с момента написания имеющейся в их распоряжении документации, появились новые функциональные возможности, такие как триггеры, хранимые процедуры и многие сотни других. Понять, почему им потребовалась помощь, не составило труда - чего нельзя было сказать о решении возникших у них проблем.

Важно! Даже в наши дни я часто обнаруживаю, что разработчики приложений баз данных совершенно не уделяют время чтению документации. На своем веб-сайте asktom.oracle.com я часто встречаю вопросы вроде "как выглядит синтаксис для ... " в сочетании с заявлениями "у нас нет документации, поэтому, пожалуйста, просто расскажите нам". Я отказываюсь давать прямые ответы на многие из таких вопросов, а вместо этого отправляю спрашивающих к сетевой документации, доступной любому пользователю где угодно в мире. За последние 15 лет оправдания типа "у нас нет документации" или "у нас нет доступа к ресурсам" практически утратили свою актуальность. Распространение Интернета и появление таких сайтов, как otn.oracle.com (Oracle Techпology Network -сеть технологии Oracle), делает отсутствие под рукой полного набора документации совершенно непростительным! Сегодня каждый имеет доступ ко всей документации; нужно просто читать ее, или - что еще проще - искать в ней ответы на вопросы.

Сама идея о том, что разработчики, которые строят приложение базы данных, должны быть изолированы от базы данных, представляется мне странной, но такая позиция существует. Многие продолжают верить, что разработчики не могут тратить время на освоение базы данных и в целом вовсе не обязаны что-либо знать о базе данных. Почему? Не единожды мне доводилось слышать утверждение наподобие " ... ведь Oracle является наиболее масштабируемой базой данных в мире, поэтому моему персоналу не нужно ее изучать; она просто работает". Действительно, Oracle - самая масштабируемая база данных в мире. Однако в среде Oracle наряду с эффективным и масштабируемым кодом достаточно легко написать неудачный и не поддающийся масштабированию код. Замените слово "Oracle" названием любого другого программного обеспечения, и утверждение останется справедливым. Не подлежит сомнению: приложение, которое работает плохо, написать значительно проще, чем приложение, которое работает хорошо. Даже в самой масштабируемой в мире базе данных иногда очень легко получить в итоге однопользовательскую систему, если вы не знаете, что делаете. База данных - это инструмент, а неправильное применение любого инструмента может приводить к проблемам. Стали бы вы разбивать грецкие орехи щипцами для колки орехов так, как если бы это быть молоток? Конечно, щипцы можно было бы использовать и так, но подобное применение этого инструмента является неподходящим, и дало бы в результате месиво (а возможно и несколько ушибленных пальцев). Игнорирование особенностей базы данных может привести к аналогичным последствиям.

Как-то меня пригласили принять участие в одном проекте, который зашел в тупик. Разработчики столкнулись с крупными проблемами, касающимися производительности; создавалось впечатление, что их система выполняла многие транзакции последовательно. Вместо того чтобы множество пользователей могли работать параллельно, каждый из них помещался в длинную очередь и был вынужден дожидаться, пока завершит работу пользователь, стоящий перед ним. Архитекторы системы ознакомили меня со своим творением - классической трехзвенной моделью. В этой системе веб-браузер должен быть обмениваться данными с сервером приложений среднего звена, на котором функционировали страницы JSP (JavaServeг Pages). В свою очередь, JSР-страницы должны были использовать еще один уровень, бины Enterprise JavaBeans (EJB), который выполнял все SQL-запросы. Код SQL в бинах EJB генерировался инструментом третьей стороны в независимой от базы данных манере.

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

Таким образом, мы столкнулись с попыткой диагностирования проблем производительности, располагая лишь теми сведениями, которые можно было почерпнуть из самой базы данных. К счастью, в этом случае решение было довольно простым. Просмотр таблиц V$ (эти таблицы являются одним из способов предоставления доступа к инструментарию и статистической информации Oracle) показал, что основное соперничество велось за единственную таблицу - таблицу очереди на обработку. Приложение должно было помещать записи в эту таблицу, а другой набор процессов - извлекать записи из нее и обрабатывать. Исследовав эту таблицу более внимательно, мы обнаружили битовый индекс на одном из столбцов. Причина такого выбора состояла в том, что этот столбец - флаг обработки - мог содержать только два значения: У и N. Записи, вставленные в таблицу, должны были иметь в этом столбце значение N (не обработана).

После считывания и обработки записи другими процессами эти процессы должны были изменять значение в столбце с N на У, указывая на то, что запись обработана. Разработчикам нужно было быстро находить записи со значением N, поэтому столбец был проиндексирован. Они где-то прочитали, что битовые индексы предназначены для столбцов с низким кардинальным числом (столбцов, содержащих небольшое количество отличающихся значений), поэтому сочли такой вид индекса вполне естественным. (Попробуйте поискать в Google строку "when to use Ьitmap in-dexes" (когда использовать битовые индексы); словосочетание "low-cardinality" (низ-кое кардинальное число) будет встречаться повсеместно. К счастью, сейчас имеется также много статей, опровергающих эту излишне упрощенную концепцию.)

Именно битовый индекс был причиной всех проблем. В битовом индексе единственная запись ключа указывает на множество строк - сотни и более. Когда ключ битового индекса обновляется (и тем самым блокируется), то сотни записей, на которые он указывает, также блокируются. Таким образом, вставка новой записи со значением N приводит к блокированию записей N в битовом индексе, по существу блокируя также и сотни других записей со значением N. Между тем процесс, который читает эту таблицу и обрабатывает записи, не имеет возможности изменить значение какой-либо записи с N на У, т.к. для этого ему пришлось бы заблокировать тот же самый ключ битового индекса. Фактически другие сеансы, которые пытаются всего лишь вставить новую запись в эту таблицу, также должны блокироваться, поскольку они предпринимают попытку заблокировать ту же самую запись битового ключа. Короче говоря, разработчики создали таблицу, вставлять и обновлять записи в которой мог только один пользователь за раз! 

Продолжим рассмотрение данной темы в следующей заметке. Жду ваших комментариев.

Вас заинтересует / Intresting for you:

Oracle IDE: JDeveloper, SQL De...
Oracle IDE: JDeveloper, SQL De... 4521 просмотров Ольга Потемкина Tue, 21 Nov 2017, 13:18:46
Oracle и Java: использование P...
Oracle и Java: использование P... 5749 просмотров sepia Tue, 08 May 2018, 08:52:34
Язык PL/SQL Oracle для програм...
Язык PL/SQL Oracle для програм... 2630 просмотров Илья Дергунов Tue, 21 Nov 2017, 13:28:01
Деятельность Oracle в XML-инду...
Деятельность Oracle в XML-инду... 7950 просмотров Дэн Tue, 21 Nov 2017, 13:33:37
Войдите чтобы комментировать