.
Ольга Карбасова
Набор продуктов Oracle9i состоит из трех основных компонентов – Oracle9iDatabase (сервер базы данных), Oracle9iApplicationServer (сервер приложений) и Oracle9iDeveloperSuite (средства разработки). В этой статье речь пойдет о нововведениях Oracle9i Database.
Новые возможности Oracle9i Database можно с некоторой долей условности разделить на две группы – предназначенные для разработчиков приложений и для администраторов баз данных. Под разработкой будем подразумевать создание серверной части приложений.
Исторически сложилось, что при знакомстве с новым продуктом в первую очередь обычно интересуются тем, появились ли какие-то принципиально новые средства и технологии разработки. В Oracle8i такой «революцией» было появление на сервере языка Java как альтернативы PL/SQL. В Oracle9i настолько новых средств разработки серверной части приложений не появилось. Но и новых возможностей старых добрых Java и PL/SQL вполне достаточно, чтобы облегчить процесс создания приложений, а в некоторых случаях изменить технологию разработки.
Сначала рассмотрим новые возможности именно для разработки приложений. Но будем помнить о том, что хорошего разработчика интересуют не только средства разработки («как сделать…»), но и средства оптимизации («…чтобы хорошо работало!»). Кроме того, при установке тиражируемой системы заказчику часто выясняется, что количество пользователей значительно превышает запланированное. Поэтому важно иметь возможность масштабирования системы.
Развитие SQL главным образом движется в сторону соответствия стандартам. SQL в Oracle9i соответствует требованиям стандарта ISO SQL1999. Для удовлетворения этих требований в язык введено много новых синтаксических конструкций. Это, например, оператор CASE, перекрывающий функциональность старой доброй функции DECODE (в примерах по традиции используются всем известные таблицы Emp и Dept):
SELECT ename "Фамилия", (CASE WHEN sal<1000 THEN 'Низкая' WHEN sal>4000 THEN 'Высокая' ELSE 'Средняя' END) "Зарплата" FROM emp; |
Изменился и синтаксис соединений. Теперь и в Oracle есть понятия правого/левого/полного внешнего соединения (outer join), например, запрос
select ename, dname from emp right outer join dept on (emp.deptno=dept.deptno); |
возвращает тот же результат, что и
select ename, dname from emp, deptwhere emp.deptno(+)=dept.deptno; |
А вот запрос
select ename, dname from emp full outer join dept on (emp.deptno=dept.deptno); |
в старом синтаксисе аналога не имеет.
Эти в большинстве своем формально-синтаксические нововведения будут очень полезны при переносе приложений на Oracle с других СУБД. Например, разработчикам легче будет перейти, скажем, с MS SQL на Oracle.
Нововведения в PL/SQL более революционны, они носят гораздо более кардинальный характер. Приверженцам объектной технологии приятно будет узнать, что в объектных типах появилось наследование, принципы которого удовлетворяют стандарту ANSI SQL99. Наследование в Oracle9i строго иерархическое, множественное наследование не допускается. Типы-потомки наследуют у своего родителя атрибуты и методы. Естественно, потомки могут добавлять свои атрибуты и методы, а также и переопределять методы родителя. Пример типа-родителя:
CREATE TYPE Person AS OBJECT( person_id NUMBER, date_of_birth DATE, name VARCHAR2(30), address VARCHAR2(100), MEMBER PROCEDURE Hire, -- можетпереопределяться FINAL MEMBER FUNCTION Age RETURN NUMBER -- непереопределяется) NOT FINAL; -- может иметь подтипы |
Возможные подтипы:
CREATE TYPE Student UNDER Person (deptid NUMBER, major VARCHAR2(30)); -- добавлениеатрибутовCREATE TYPE Employee UNDER Person (empid NUMBER, mgr VARCHAR2(30)) NOT FINAL;CREATE TYPE PartTimeEmployee UNDER Employee(numhours NUMBER); |
Вводится и понятие абстрактных (not-instantiable) типов и методов. Разработчик может создавать подтипы таких типов, но не может создавать экземпляры таких типов.
PL/SQL-пакеты можно компилировать в виде разделяемых библиотек. Это устраняет накладные расходы на интерпретацию PL/SQL-кода, что может привести к ускорению выполнения в 2-10 раз. Так что теперь желающие смогут писать функции вычисления интегралов на PL/SQL, не жертвуя при этом производительностью. Конечно, если PL/SQL-программы интенсивно работают с базой данных, значительного выигрыша от компиляции PL/SQL получить не удастся.
В SQL и PL/SQL появились новые типы данных. Особенно оригинален тип AnyData. В столбце этого типа в каждой строке могут храниться данные разных типов (в одной строке – символьные, в другой – числовые, в третьей – структура из двух бинарных и трех числовых полей). Описание типа данных в поле каждой конкретной строки хранится в самом поле. Доступ к данным такого типа пока возможен только через OCI.
Менее оригинальны, но не менее полезны новые типы для даты и времени. Во-первых, тип TimeStamp дает возможность хранить в базе данных дату с точностью до долей секунды (до 9 знаков после запятой). Во-вторых, тип TimeStamp with Time Zone вместе с датой хранит код часового пояса. Сравнение данных этого типа осуществляется с учетом часового пояса. Это очень облегчает работу с распределенными системами и репликацией. Кстати, список стандартных часовых поясов в Oracle9i охватывает весь земной шар. Введены и два принципиально новых типа данных для хранения интервалов времени, не привязанных к конкретной дате – INTERVAL DAY TO SECOND и INTERVAL YEAR TO MONTH. Используя эти типы, удобно задавать, например, продолжительность испытательного срока при приеме на работу:
Create table Jobs(job varchar2(9), trial_period INTERVAL YEAR TO MONTH);insert into Jobs -- испытательный срок values ('MANAGER','1-6') -- для менеджера – полтора года;select ename, hiredate, hiredate + trial_period -- икогдажеонзакончится? from emp -- а вот еще один пример нового natural join jobs; -- синтаксиса соединений |
Поддержка Java интенсивно развивается в направлении соответствия все более новым стандартам. В Oracle9i поддерживаются стандарты Servlet 2.2, JavaServer Pages 1.1, JDBC 2.0.
Отдельно стоит упомянуть и поддержку XML. Введен новый тип данных XMLType, реализованный как LOB, и работа с данными этого типа поддерживается через SQL, PL/SQL и Java.
Идея глобализации нашла свое применение в развитии поддержки многоязыковых баз данных и средств работы с ними, что отражено и в терминологии: термин National Language Support заменен в Oracle9i на Globalization. Среди нововведений в этой области можно выделить новую кодировку для двухбайтного Unicode (UTF16), Unicode на основе кодировки EBCDIC (UTFE) и многоязыковые сортировки. Для облегчения перевода базы данных на новую кодировку предлагается утилита Character Set Scanner. Она сканирует базу данных и определяет, какие столбцы каких таблиц потребуется расширить, и какие символы будут потеряны при переходе. Утилита Locale Builder позволяет модифицировать языковые, территориальные и лингвистические установки (правила сортировки, названия дней и месяцев, правила перевода между верхним и нижним регистрами, форматы даты и т.п.), а также и таблицы кодировки.
Принципиальное новшество, не имеющее аналогов в предыдущих версиях Oracle – рабочие области (workspaces). Введение рабочих областей можно рассматривать как появление в базе данных еще одного уровня версионности.
Известно, что поддержка целостности чтения (read consistency) в Oracle реализована через многоверсионность. Если сессия изменила данные и не зафиксировала (commit) транзакцию, то другие сессии получают старую версию данных. После фиксации транзакции отмена её изменений уже невозможна, а все другие сессии начинают видеть изменённое состояние данных. Поэтому практически невозможно проверить, правильно ли работает какое-нибудь большое пакетное задание типа выставления счетов всем клиентам. Без фиксации транзакций такого рода вещи обычно не обходятся, и если вы обнаружили, что счета выставлены неправильно, отменить уже ничего нельзя, и данные испорчены.
Теперь для подобных тестов можно создать рабочую область и работать в ней. Внутри рабочей области действуют стандартные правила и стандартные алгоритмы поддержания целостности чтения. Пользователь, работающий в своей рабочей области, может делать запросы, изменения данных и фиксировать транзакции. Эти изменения, даже зафиксированные, видны только пользователям, действующим в той же самой рабочей области. После окончания работы с рабочей областью её можно уничтожить, потеряв все изменения в ней, или соединить с основным содержимым базы данных. Так что вышеописанная задача тестирования решается так: создаём рабочую область, переходим в неё, запускаем процедуру, смотрим результат. Если всё правильно – соединяем с основными данными, если нет – уничтожаем рабочую область и ищем ошибку…
К сожалению, в рамках этой статьи невозможно описать все нововведения стоимостного оптимизатора. Стоит упомянуть о том, что оптимизатор при выборе плана выполнения учитывает процессорное время сервера, использование временного пространства, а также (чего раньше не было) текущую статистику экземпляра Oracle. Появилась возможность редактировать хранимые каркасные планы (stored outlines).
Невозможно оставить без внимания ещё одно оригинальное новшество – битовые индексы соединения (bitmap join indexes, BJI). Это обычные битовые индексы, но построенные по столбцам, которых в индексируемой таблице нет. Например, в таблице продаж (назовем её по традиции Sales) есть код региона продажи, но нет его названия. Название есть в справочнике регионов (Regions). В то же время запрос, выбирающий все продажи по региону с заданным названием, довольно типичен. При его выполнении каждый раз требуется соединение (join) таблиц Sales и Regions. Рассмотрим пример.
Создадим таблицы:
create table Regions ( region_id number primary key, -- первичныйключобязателендлясоздания BJI region_name varchar2(200));create table Sales ( id number primary key, region_id number, -- опустимограничениявнешнегоключа product_id number, amount number, sal_date date); |
Выполним запрос: