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

Рис. 65

Теперь, когда мы определили общую связь между двумя полями в таблице invoices и в таблице customers, стоит более внимательно разобрать, как писать запросы с соединениями.

<p id="_9_xhtml_2523toc_marker_9_3"><strong>Псевдонимы соединяемых таблиц</strong></p>

Из первого примера видно, что при обращении к полям соединения JOIN имеют особый синтаксис. Поскольку две таблицы в любой базе данных могут содержать поля с одинаковыми именами, при создании соединений необходимо для указания определенного поля задать имя таблицы, чтобы браузер SQL точно знал, какое поле имеется в виду. По правилам синтаксиса необходимо сначала указать имя таблицы, а затем через точку — имя поля. Чтобы уменьшить объем текста и повысить удобочитаемость, в соединениях часто используются псевдонимы. Следующие два соединения идентичны по функциям.

SELECT

*

FROM

invoices

INNER JOIN

customers

ON

invoices.CustomerId = customers.CustomerId

-----------------------

SELECT

*

FROM

invoices AS i

INNER JOIN

customers AS c

ON

i. CustomerId = c.CustomerId

Примечание

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

Чтобы продемонстрировать необходимость использования псевдонимов при работе с соединениями, давайте рассмотрим наш первоначальный сценарий. Руководству sTunes необходим список с указанием имен клиентов и счетов, выставленных каждому клиенту. Когда в этой главе мы писали наше первое соединение, для выбора всех полей из каждой таблицы был использован символ *. Результатом данного запроса стал массивный набор результатов из двадцати двух полей. Однако нам требуются только имена клиентов и информация о счете. Также, когда мы используем символ *, мы не можем контролировать порядок отображения полей. Предположим, что руководству sTunes необходимо в списке клиентов сначала отображать фамилию. Чтобы определить порядок вывода, следует в операторе SELECT вместо символа * указать имена полей. Давайте создадим аналогичное приведенному выше соединение, но на этот раз в запросе укажем, что из таблицы customers необходимо отобразить поля LastName и FirstName, а из таблицы invoices — поля InvoiceId, CustomerId, InvoiceDate и Total. Поскольку мы работаем с двумя таблицами, содержащими отдельные поля с одинаковыми именами, в условии SELECT следует использовать обозначение tablename.FieldName, как и в условии ON наших соединений, но с одним изменением: вместо полного имени таблицы мы зададим псевдоним, состоящий из первой буквы таблицы, за которой следует точка, а затем имя поля. Наконец, необходимо отсортировать результаты по фамилии клиента. В результате запрос будет выглядеть следующим образом:

SELECT

c. LastName,

c. FirstName,

i. InvoiceId,

i. CustomerId,

i. InvoiceDate,

i. Total

FROM

invoices AS i

INNER JOIN

customers AS c

ON

i. CustomerId = c.CustomerId

ORDER BY

c. LastName

Рис. 66

Примечание

Кажется странным, что мы ссылаемся на псевдонимы (в условии SELECT), прежде чем определим их (в условиях FROM и INNER JOIN). Но следует помнить, что браузер SQL обрабатывает запросы не в той очередности, как их прочел бы человек.

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

Примечание

В большинстве случаев в условии SELECT рекомендуется указывать отдельные имена полей и избегать использования символа *. В этой главе мы будем использовать символ * только в демонстрационных целях для объяснения структуры JOIN.

<p id="_9_xhtml_2523toc_marker_9_4"><strong>Типы соединений</strong></p>

Существует несколько различных типов соединений. До сих пор мы использовали соединения, чтобы предоставить доступ к полям из нескольких таблиц. Мы определили первичный ключ таблицы customers, определили аналогичный внешний ключ в таблице invoices и использовали ключевое слово ON, чтобы связать две таблицы вместе.

Вопрос. Что произойдет, если данные из таблиц, которые мы объединяем, не полностью совпадают?

Перейти на страницу:

Все книги серии Библиотека программиста

Похожие книги