Основы проектирования реляционных баз данных

         

Специальные реляционные операторы


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

  • Проекция (Projection).

    Операция проекции ограничивает число колонок таблицы, на которые ссылаются в команде SQL.

  • Выбор (Selection or restriction).

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

  • Соединение (Join).

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

Поскольку эти специальные реляционные операции играют центральную роль в командах SQL, то рассмотрим их более подробно.

Проекция. Когда SELECT специфицирует определенные колонки из одной или более таблиц, то выводятся только значения этих колонок:

SELECT NAME, PHONE FROM CUSTOMER;

Альтернативой к выполнению проекции является использование символа "*", который приводит к выводу всех колонок таблицы:

SELECT * FROM CUSTOMER;

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

Селекция. Селекция является строковым эквивалентом операции проекции на колонки. В SQL предложение WHERE специфицирует выбор указания имен колонок в выражениях сравнения либо с константами (однозначными или многозначными), либо с выражениями, которые вычисляют одно или несколько значений. Можно привести следующие примеры операции селекции:

SELECT * FROM CUSTOMER WHERE NAME = 'JONES'; SELECT * FROM PRODUCT WHERE STOCK_QTY <= REORDER_QTY; SELECT * FROM ORDER WHERE (STАTUS IN ('C','P','S')) AND (TOTAL_AMT > 1000);


Каждое сравнение, содержащееся в предложении WHERE, называется предикатом (predicate). Некоторые команды SQL, подобно последней в приведенных примерах, содержат более одного предиката. Когда операция, указанная в предикате, выполняется на строке, то это называется взятием предиката (applying the predicate). Если предикат вычисляется как TRUE, то говорят, что условие выбора удовлетворено, в противном случае - не удовлетворено. Когда утверждение имеет более чем один предикат, они должны быть связаны одним или боле логическими операторами AND или OR. Когда все предикаты связаны операцией AND, то говорят, что это конъюнкция (conjunctive), когда OR, то говорят, что это дизъюнкция (disjunctive). Эта терминология предикатов играет важную роль в том, как они используются оптимизатором запросов.

Заметим, что форма предложения WHERE, которая сравнивает колонки из различных таблиц, не является операцией селекции, но является спецификацией для операции соединения.

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

Для того чтобы выполнить соединение, используются предложения FROM и WHERE команды SELECT. Предложение FROM должно именовать каждую входную таблицу соединения. Предложение WHERE специфицирует критерий соединения посредством сравнения одной или более колонок одной таблицы с одной или более колонками другой.




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

SELECT NAME, AMOUNT FROM CUSTOMER, RECEIVABLE WHERE CUSTOMER.CUST_NO = RECEIVABLE. CUST_NO; SELECT NAME, QTY, DESC FROM CUSTOMER C, ORDER O, PRODUCT P WHERE ( C.CUST_NO = O. CUST_NO ) AND (P.CUST_NO = O. CUST_NO );

Во втором примере буквы С, О, Р позволяют вам квалифицировать имена колонок соответствующих таблиц без указания их полных имен. В SQL это называется корреляционными переменными (correlation variables). Так как большинство имен колонок должны быть квалифицируемыми, то они часто используются в соединениях благодаря представлению нескольких имен таблиц в предложении FROM.

Две важнейших характеристики операции соединения состоят в том, что она является коммутативной и ассоциативной:

A JOIN B = B JOIN A; (коммутативность) A JOIN (B JOIN C) = (A JOIN B) JOIN C; (ассоциативность) (A JOIN B) JOIN C = B JOIN (A JOIN C).

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

Тип операции сравнения часто используется для классификации операций соединения.

Эквисоединение (Equijoin). Наиболее общим примером соединения является эквисоединение, которое использует оператор сравнения "=". Эта версия операции соединения применяется, когда взаимосвязь между объектами предметной области требует комбинации информации из двух таблиц по равенству значений в соответствующих колонках. Такие соединения реализуются установкой первичного ключа родительской таблицы равным внешнему ключу таблицы-потомка.

SELECT C.CUST_NO, C.CUST_NAME, O.ITEM_NO, I.DESC FROM CUST C, ORDER O, ITEM I WHERE (C.CUST_NO = O.CUST_NO) AND (O.ITEM_NO = I.ITEM_NO);



SELECT C.CUST_NO, C.CUST_NAME, O.ITEM_NO, I. DESC FROM CUST C, ORDER O, ITEM I WHERE (C.CUST_NO = O.CUST_NO) AND (O.ITEM_NO = I.ITEM_NO);

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

Полусоединение (Semijoin). Операция полусоединения эквивалентна эквисоединению с последовательной проекцией, которая включает колонки одной из таблиц соединения. Это полезно, когда нужны строки таблицы, которые включены в критерий поиска и определяются в терминах принадлежности к колонке внешнего ключа другой таблицы. Примером могло бы быть множество всех продуктов, которые были проданы в течение января 1995 года:

SELECT P.PROD_NO, P.PROD_DESC FROM PRODUCT P, ORDER O WHERE (O.PROD_NO = P.PROD_NO) AND (O.ORD_DATE BETWEEN JAN-1-1995 AND JAN-31-1995);

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

Внешнее соединение (Outerjoin). Внешнее соединение позволяет включать в результирующие множество незадействованные строки (non-participating rows) одной из таблиц, которые не соответствуют условиям соединения. Причина, по которой эти строки называются незадействованными, состоит в том, что они содержат значения ключей, которые не ссылаются на какую-либо строку другой таблицы. Например, строка в множестве товары содержит номер продукта, который никогда не будет учитываться каким-либо производителем, - такая строка была бы незадействованной в соединении таблицы "товары" и таблицы "счета". В SQLBase эти строки могут быть включены в результирующее множество посредством указания оператора внешнего соединения "+", на ключе таблице ORDER, как показано в примере.



SELECT * FROM PRODUCT P, ORDER O WHERE P.PROD_NO = O.PROD_NO(+);

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

SELECET E.NAME, M.NAME FROM EMPLOYEE E, EMPLOYEE M WHERE E.MNGR_NO = M. EMPLOYEE_NO;

Агрегация (Aggregation). Хотя агрегация не была первоначально специфицирована как реляционная операция, ее включение как стандартной возможности SQL сделало ее общераспространенной операцией. Цель агрегации состоит в том, чтобы предоставить для таблицы выведенную статистическую информацию, такую как сумма или среднее множества чисел.

SQL поддерживает два типа агрегации, простейший из которых есть скалярная агрегация, которая производит единственный вывод для колонки отношения. Скалярная агрегация в SQL выполняется посредством включения функций агрегирования в запрос, который не имеет какого-либо предложения GROUP BY. Например:

SELECT SUM(SALARY) FROM EMPLOYEE; SELECT COUNT(*) FROM EMPLOYEE WHERE NAME = 'DAVE';

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

Второй тип агрегации, поддерживаемый SQL, есть функция агрегации. Этот тип агрегации использует такие же агрегатные функции, что и скалярная агрегация. Разница между ними состоит в том, что функция агрегации всегда создает другую таблицу как вывод. Это противоположно скалярной агрегации, которая просто возвращает единственное значение как вывод.

Синтаксис SQL для выполнения функции агрегации всегда включает предложение GROUP BY.Колонки, названные в предложении GROUP BY, становятся в действительности ключом к некоторой новой таблице, которая выводится этим утверждением. Например, функцией агрегирования является

SELECT DEPT, AVG(SALARY) FROM EMPLOYEE GROUP BY DEPT; SELECT @MONTH(BIRTH_DAY), COUNT(*) FROM EMPLOYEE GROUP BY :1;

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


Содержание раздела