|
Программирование >> Проектирование баз данных
скрипты могут понадобиться опять! Из приведенного ниже текста триггера видно, насколько просто реализовать в виде триггеров базы данных правила, перечисленные в табл. 4.1. CREATE OR REPLACE TRIGGER oit bir BEFOR INSERT ON order items FOR EACH ROW l itein price ORDER ITEMS. ITEM PRICE%TYPE; l ord order ORDER ITEMS.ORD ORDER#%TYPE; BEGIN l itein price := : new. item price ; l ord order := :new.ord order#; UPDATE orders ord SET ord. order price = ord. order price + l itein price WHERE ord.order! = l ord order; END; CREATE OR REPLACE TRIGGER oit bdr BEFOR DELETE ON order items FOR EACH ROW l item price ORDER ITEMS. ITEM PRICE%TYPE; l ord order ORDER ITEMS.ORD ORDER#%TYPE; BEGIN l itein price := : old. item price ; l ord order := ;old.ord order#; I I UPDATE orders ord SET ord. order price = ord. order price - l itera price ] WHERE ord.order! = l ord order; END; CREATE OR REPLACE TRIGGER oit bur BEFOR UPDATE OF tot price ON order items FOR EACH ROW l old ii;era price ORDER ITEMS . ITEM PRICE%TYPE; l new itera price ORDER ITEMS.ITEM PRICE%TYPE; l ord order ORDER ITEMS.ORD ORDER#%TYPE; BEGIN l new itein price := : new. itein price; l old itein pr ice := : old. itera price; l ord order := :new.ord order#; UPDATE orders ord SET ord.order price = ord.order price - l old item price + l new item price WHERE ord.order# = l ord order; END; Поддержка денормализованных столбцов посредством триггеров кажется надежным и элегантным решением. Неужели оно лишено недостатков PC сожалению, существует скрытая проблема, которая в определенных условиях может снизить производительность. Допустим, заказы в среднем имеют по fHoro позиций (скажем, 1000). Мы периодически удаляем заказы и, из-за ограничений ссылочной целостности, сначала должны удалять позиции заказов. Рассмотрим безобидный, на первый взгляд, оператор: DELETE order iteras oit WHERE oit.ord id = :x; Такое удаление повлечет за собой повыщение уровня активности в базе данных. Обратившись к определению триггеров, мы видим, что они работают для каждой строки. Это означает, что если удаляемый заказ имеет 1000 позиций, то триггер oit bdr сработает 1000 раз. Наше разочарование усиливается тем, что мы заранее знаем конечный результат - цена заказа будет равна нулю! Однако не стоит из-за этого недостатка отказываться от использования триггеров для поддержки денормализации - если эту проблему своевременно выявить, то ее можно обойти. Мы даем триггеру сигнал ничего не делать, устанавливая перед удалением глобальную переменную пакета, которая будет индикатором нашего намерения. Данную переменную можно установить и в триггере DELETE на таблице ORDERS в сочетании с ограничением каскадного удаления. Это вызовет автоматическое удаление связанных с заказом строк в таблице ORDER ITEMS. Даже в этом случае наш триггер сработает 1000 раз, но он не будет каждый раз выполнять обновление. Фактически он вообще не выполнит никакой обработки, а только проверит вышеупомянутую переменную и завершит работу. Более подробно использование глобальных переменных пакетов для управления режимами работы триггеров освещено в приложении Б. Другие способы осуществления денормализации в этом разделе рассматриваются еще некоторые способы осуществления денормализации - внутритабличная, методом разделяй и властвуй и Методом объединения таблиц. внутритабличная денормализация Внутритабличная денормализация выполняется в пределах одной таблицы. Чем же может быть вызвана необходимость хранения в строке значения, которое образуется из других данных этой же строки? Единственная веская причина этого - необходимость запроса строки по производному значению. Например, если строка содержит два числовых столбца, X и Y, то значение равное произведению ХиУ(2 = ХхУ), легко вычислить во время выполнения. Однако предположим, что есть запросы, в которых необходимо осуществлять поиск по Z (например, Z, принадлежащему диапазону от 10 до 20) Сохранив избыточные значения Z в столбце, можно построить индекс по Z, и запросы будут использовать этот индекс. Если индекс по Z строить не надо, то рещение о его хранении в отдельном столбце зависит от того, что является более приемлемым в данной ситуации - увеличение времени загрузки, вызванное необходимостью постоянно пересчитывать Z, или увеличение времени сканирования, обусловленное удлинением строк за счет его хранения. Еще один часто встречающийся пример внутритабличной нормализации проиллюстрирован на рис. 4.4. Здесь одинаковый текст хранится в двух видах с символами в верхнем и нижнем регистре - для отображения и ввода данных и с символами в верхнем регистре - для обеспечения работы ускоренных запросов без учета регистра. ecords others in Arms MOTHERS IN ARI. 3 RE STRAITS Пользователь SELECT FROM WHERE iPPER(a) Будет использовать индекс по UC TITLE Рис 4 4 Оптимизация запроса с помощью производного столбца Примечание Oracle заявила о намерении поддерживать в одной из будущих версий своей СУБД индексы для выражений. Это будет особенно полезно для поддержки поиска без учета регистра. Денормализации этим способом можно избежать, используя прием, который, по нащим данным, дает достойную производительность в таблицах умеренного размера, не влияя ни на размер таблиц, ни на производительность
|
© 2006 - 2025 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |