Программирование >>  Oracle 

1 ... 81 82 83 [ 84 ] 85 86 87 ... 469


17 18

19 20 21 22

(x$ename,x$rid) values (upper(:new.ename), :new.rowid);

elsif (deleting)

then

delete from upper ename where x$ename = upper(:old.ename) and x$rid = lold.rowid;

end if;

end;

Trigger created.

tkyte@TKYTE816> update emp set ename - initcap(ename); 14 rows updated. tkyte@TKYTE816> commit; Commit complete.

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

tkyte@TKYTE816> update

2 3 4 5 6 7 8 9 10

select ename, from emp

where emp.rowid

in (select upper ename.x$rid from upper ename where x$ename = KING)

1234

1 row updated.

tkyte@TKYTE816> select ename, empno, sal

2 from emp, upper ename

3 where emp.rowid = upper ename.x$rid

4 and upper ename.x$ename = KING

ENAME

EMPNO

King

7839

tkyte@TKYTE816> delete from

3 select ename, empno

4 from emp



5 where emp.rowid in (select uppex ename.x$rid

6 from upper ename

7 where x$ename = KINS}

1 row deleted.

При выборе можно использовать подзапрос с IN либо соединение (JOIN). Из-за правил сохранения ключей при изменении или удалении строки надо использовать только подзапрос с IN. Примечание об этом методе, требующем сохранения идентификаторов строк: организованную по индексу таблицу, как и любой другой индекс, необходимо перестраивать, если в результате выполненных действий, таких как экспорт и импорт или применение оператора ALTER TABLE MOVE, изменились идентификаторы строк в таблице ЕМР.

Наконец, если необходимо обеспечить совместное размещение данных или физически хранить данные в определенном порядке, индексная организация таблицы тоже подойдет. Пользователи СУБД Sybase и SQL Server в этом случае использовали бы кластерный индекс, но организация таблицы по индексу намного лучше. В случае кластерного индекса в этих СУБД может дополнительно расходоваться до 110 процентов пространства (аналогично моей таблице KEYWORDS в представленном ранее примере). Здесь же дополнительных расходов вообще нет, поскольку данные хранятся только в одном месте. Классический пример желательности совместного размещения взаимосвязанных данных представляет собой отношение главный/подчиненный. Пусть у таблицы ЕМР имеется подчиненная таблица:

tkyte@TKYTE816> create table addresses

2 (empno number(4) references emp(empno) on delete cascade,

3 addr type varchar2(10) ,

4 street varchar2(20) ,

5 city varchar2(20) ,

6 state varchar2(2),

7 zip number,

8 primary key (empno,addr type)

10 ORGANIZATION INDEX

11 /

Table created.

Физически близкое размещение всех адресов сотрудника (домашнего адреса, адреса места работы, адреса школы, прежнего адреса и т.д.) уменьшит объем ввода/вывода при соединении таблиц ЕМР и ADDRESSES. Объем логического ввода/вывода будет тем же, но физического ввода/вывода потребуется существенно меньше. В обычной таблице каждый адрес сотрудника может физически находиться в другом блоке по отношению к другим адресам того же сотрудника. Сортируя адреса по столбцам EMPNO и ADDRTYPE, мы гарантируем, что все адреса данного сотрудника хранятся рядом .



Это применимо и в случае частого использования запросов с конструкцией BETWEEN по первичному или уникальному ключу. Хранение отсортированных данных повысит производительность и этих запросов. Например, в моей базе данных имеется таблица котировок акций. Каждый день в нее собирается информация о символах акций, дате, конечной цене, колебаниях курса в течение дня, количестве проданных акций и т.д. Это делается для акций сотен компаний. Соответствующая таблица имеет такой вид:

tkyte@TKYTE816> create table stocks

(ticker

varchar2(10),

date,

value

number,

change

number,

high

number,

number,

number,

primary key(ticker,day)

organization index

Table created.

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

Select * from stocks where ticker = ORCL

and day between sysdate and sysdate - 100;

сервер Oracle прочитает индекс, а затем обратится к таблице за остальными данными строки по идентификатору строки. Каждая из 100 выбираемых строк окажется в другом блоке базы данных из-за принятого способа загрузки данных в таблицу, и каждая, вероятно, потребует выполнения операции физического ввода/вывода. Теперь предположим, что такая таблица организована по индексу. При выполнении этого же запроса придется прочитать только соответствующие блоки индекса, и все необходимые данные будут получены. Не только нет необходимости обращаться к таблице, но и все строки для акций ORCL в заданном диапазоне дат физически хранятся рядом друг с другом. Требуется меньше логического и физического ввода/вывода.

Теперь понятно, когда следует использовать таблицы, организованные по индексу, и как это делать. Осталось разобраться, какие опции можно использовать при создании таких таблиц? Есть ли потенциальные проблемы при их использовании? Опции те же, что задаются для таблиц, организованных в виде кучи. Еще раз воспользуемся утилита-



1 ... 81 82 83 [ 84 ] 85 86 87 ... 469

© 2006 - 2024 pmbk.ru. Генерация страницы: 0.002
При копировании материалов приветствуются ссылки.
Яндекс.Метрика