Структура запросов с использованием нескольких таблиц

 

Как известно, базы данных – это множество взаимосвязанных сущностей или отношений (таблиц) в терминологии реляционных СУБД. При проектировании стремятся создавать таблицы, в каждой из которых содержалась бы информация об одном и только об одном типе сущностей. Это облегчает модификацию базы данных и поддержание ее целостности. Даже при отсутствии средств одновременного доступа ко многим таблицам нежелателен проект, в котором информация о многих типах сущностей перемешана в одной таблице. SQL же обладает механизмом для одновременной или последовательной обработки данных из нескольких взаимосвязанных таблиц. В нем реализованы возможности “соединять” или “объединять” несколько таблиц и так называемые “вложенные подзапросы”.

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

Существует три типа объединений, используемых в предложении FROM: левое внешнее (LEFT JOIN), правое внешнее (RIGHT JOIN) и внутреннее (INNER JOIN).

 

Ниже перечислены аргументы операций LEFT JOIN, RIGHT JOIN, INNER JOIN:

таблица_1, таблица_2 – имена таблиц, записи которых подлежат объединению;

поле_1, поле_2 – имена объединяемых полей. Поля должны иметь одинаковый тип данных и содержать данные одного рода, однако могут иметь разные имена;

оператор – любой оператор сравнения: “=,” “<,” “>,” “<=,” “>=,” или “<>”;

ON – определяет критерии объединения.

В левом внешнем объединении всем записям в таблице_1 поставлены в соответствие записи из таблицы_2, отвечающие заданным критериям. Записи из таблицы_1 включаются даже тогда, если для них нет соответствующих записей в таблице_2.

Правое внешнее объединение аналогично левому, но в данном случае отображаются все записи таблицы_2 и соответствующие критерию записи таблицы_1.

Внутреннее объединение возвращает строки обеих таблиц, включаемых в операцию, которые соответствуют заданным критериям.

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

 

SELECT * FROM таблица_1 WHERE поле_1 = (SELECT поля_2 FROM таблица_1 WHERE условие);

 

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

 

Оптимизация запросов

 

Язык SQL часто называют непроцедурным, так как пользователь указывает, что делать, а не как делать, т.е. пользователь говорит, что ему нужно, без указания процедуры получения результата. Процесс навигации по хранимой базе данных для удовлетворения пользовательского запроса выполняется СУБД автоматически, а не пользователем вручную. Поэтому реляционные системы иногда называют системами автоматической навигации.

Ответственность за то, как выполняется автоматическая навигация, несет очень важный компонент СУБД – оптимизатор. Другими словами, работа оптимизатора заключается в том, чтобы для каждого запроса пользователя выбрать самый эффективный способ выполнения этого запроса. Например, при поиске записи существует, по крайней мере, два способа выполнения запроса:

1) последовательный физический просмотр таблицы (хранимой версии), пока не будет найдена требуемая запись;

2) если есть индекс для столбца таблицы, содержащего запись, то переход с помощью этого индекса непосредственно к записи.

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

– на какие таблицы есть ссылки в запросе (может быть несколько ссылок, если, например, используются какие-нибудь соединения);

– насколько велики эти таблицы;

– какие индексы созданы;

– как выбраны эти индексы;

– как физически группируются данные на диске и т.д.

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