|
Программирование >> Проектирование баз данных
, cc2.name , so f.name , cus.name FROM orders ord , currencies ccl , currencies cc2 , sales offs sof t customers cus WHERE ord.cus id = cus.id AND ord.se cur = ccl.code AND ord.qu cur = cc2.code(+) AND ord.sof id = sof.id(+); Соединение no схеме называется так потому, что для него очевид- на аналогия с соответствующей топологией локальной сети. В следующем примере приводится запрос к представлению V ORDERS, в котором используется такое соединение. SELECT id , customer name FROM v orders WHERE se cur = UK Pounds AND qu cur = US Dollars AND sof id = North America; У нас есть условия для выбора данных из трех таблиц; каждая из этих таблиц соединяется с таблицей ORDERS, но связей с другими таблицами не имеет. Таким образом, таблица ORDERS находится в центре звезды . Лучше всего при выполнении этой операции использовать следующую стратегию: 1. Произвести запросы к таблицам валют (дважды) и таблице отдела сбыта. 2. Получить декартово произведение результатов этих запросов (в этом случае декартово произведение будет состоять всего из одной строки). 3. Используя это декартово произведение, выполнить соединение с таблицей ORDERS. 4. Выполнить соединение таблицы ORDERS с таблицей CUSTOMERS. Шаги 1, 2 и 3 - это соединение по схеме звезда , а версии до 7.3 вьщают неудачные планы выполнения запросов, использующих такое соединение. К сожалению, не особенно помогают в этом случае даже подсказки. Причин этому две. Во-первых, механизмы выполнения запросов в ранних редакциях не располагают нормальной стратегией для реализации подсказки. Во-вторых, в большинстве Рогшз-приложений трудно предсказать, какие из допустимых аргументов будут указаны (потому что они вводятся как критерии запроса), а от этого зависит план. Например, нельзя использовать ту же последовательность табличных ссылок, если заданы два наименования валют и имя покупателя (а не Sales Office). При отсутствии поддержки для соединений по схеме звезда в механизме выполнения запросов самый лучший подход к такому соединению - кодировать его при помощи процедур. Проблема с внешними соединениями состоит в том, что оптимизатор запросов Oracle никогда не выдаст план запроса, который выполняется неверно по внешнему соединению. Это имеет место даже в случае, если имеется условие, показываюшее, что для выбираемых данных не нужно создавать внешнее соединение вообше. Следовательно, наличие внешних соединений в этом примере означает, что запросы с соединением по схеме звезда фактически использовать нельзя. Поэтому порядок соединения будет таким: 1. Произвести запрос к таблице CURRENCIES для получения кода валюты, в которой указана стоимость заказа. 2. Используя этот код, выполнить соединение с таблицей ORDERS. 3. Произвести соединение таблицы ORDERS с таблицей CUSTOMERS, таблицей CURRENCIES и таблицей SALES OFFS, применяя после этих соединений фильтры для второй и третьей таблиц. Если лишь очень немногие заказы регистрируются в долларах США, а оплачиваются в английских фунтах (а это весьма вероятно), то этот план выполнения запросов будет крайне неэффективным. Решение, как всегда, заключается в осуществлении процедурного констроля за соединением. Это можно сделать на клиенгге или на сервере. Если реализовать процедурное решенгие на клиенте, то этим мы увеличим трафик сообщений - а ведь главным мотивом построения блока на представлении было снижение числа сообщений в сети. Если построить блок на представлении, но при этом предотвратить использование этого представления, добавив триггеры ON-SELECT, ON-FETCH и ON-LOCK, вызывающие процедуры PL/SQL на стороне сервера, то таким образом мы полностыо инкапсулируем логику запросов на сервере. При этом число пар сообщений будет таким: одна - для инициирования обработки и одна - на каждую строку. Этот метод подходит для блока, содержащего одну строку. Если же речь идет о многострочном блоке, то, чем больше строк нужно в нем заполнить, тем менее приемлемым он становится. Однако этот метод все равно обеспечивает значительное сокращение числа сообщенгий по сравнению с другим вариантом, который заключается в поиске с помощью нескольких триггеров уровня поля. Кроме того, он позволяет справиться со сложностью запросов к небазовым таблицам силами логики на стороне сервера, а не на стороне клиента. Необходимы три процедуры, и они должны находиться в пакете, который пользуется глобальным пакетным курсором. В нашем примере эти процедуры можно объявить так: CREATE OR REPLACE PACKAGE order query IS PPROCEDURE params ( ord id IN NUMBER , settlement currency IN VARCHAR2 , quotation currency IN VARCHAR2 sales office customer name IN varchar2 IN varchar2 FUNCTION fetch row ( row id OUT VARCHAR2 , ord id OUT NUMBER , settlement currency OUT VARCHAR2 , quotation currency OUT VARCHAR2 , sales office OUT VARCHAR2 , customer name OUT VARCHAR2 )RENURN BOOLEAN; FUNCTION lock row (row id IN VARCHAR2 )RENURN BOOLEAN; END order query; Стоимость реализации такой полной инкапсуляции высока, поскольку процедура на стороне сервера должна использовать динамический SQL для построения запросов, необходимых для каждого сочетания заданных значений полей. Однако эти приемы хорошо описаны, и в большинстве случаев позволяют добиться приемлемого сокращения трафика сообщений. Кроме того, такой подход позволяет уменьшить затраты на выполнение запросов. Мы рекомендуем рассмотреть возможность применения этой методики для всех интенсивно используемых клиентских приложений, где на первый план выходит проблема с числом операций обмена и необходимо поддерживать запросы к небазовым таблицам. Если у всех запросов в качестве параметров указаны поля базовой таблицы, то, вероятно, эффективным окажется более простой вариант - строить формы на базе представления, содержащего соединение. Нам известен один проект, в котором проектировщики собираются уменьшить трафик сообщений, заставив функцию FETCH ROW возвращать несколько строк таблицы. Это делается за счет того, что каждая переданная обратно переменная будет содержать список значений, упакованный в одну строку. Для этого потребуется создать дополнительный код и на стороне сервера, и на стороне клиента. Хотя этот метод недостаточно изящен и потребляет много ресурсов центрального процессора, он все же может сократить число операций обмена до того же уровня, что и представления (до одной для заполнения экранной формы). Проверка данных в среде клиент/сервер В дни Огас1е6 у разработчиков вошло в привычку реализовывать все бизнес-правила и ограничения в приложениях, потому что больше девать их было некуда. В больщинстве случаев один и тот же код приходилось Повторять в нескольких приложениях, в результате чего возникали проблемы с сопровождением и согласованностью. I 1 гг.,----
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |