SQLГлава 1. Реляционные базы данных. ВведениеВведениеSQL (произносится обычно "СЭКВЭЛ" (или, более англообразно — СКЬЮЭЛ)) означает Структурированный Язык Запросов. Это язык, который дает возможность создавать реляционные базы данных (и работать с ними), которые представляют собой наборы связанной информации, сохраняемой в таблицах. Мир БД становится всё более единым, что привело к необходимости создания стандартного языка, который мог бы использоваться для функционирования в большом количестве различных видов компьютерных сред. Стандартный язык даст возможность пользователям, знающим один набор команд, использовать их, чтобы создавать, отыскивать, изменять и передавать информацию, независимо от того, где идёт работа: на персональном компьютере, сетевой рабочей станции или на универсальной ЭВМ. В нашем, всё более и более взаимосвязанном компьютерном мире, пользователь, снабжённый таким языком, имеет огромное преимущество в использовании и обобщении информации из ряда источников с помощью большого количества способов. Элегантность и независимость от специфики компьютерных технологий, а также его поддержка лидерами промышленности в области технологии РБД, сделали SQL (и, вероятно, в течение обозримого будущего, оставят его) основным стандартным языком БД. По этой причине любой, кто хочет работать с базами данных 90-х годов (прошлого века), должен знать SQL. Стандарт SQL определяется ANSI (Американским Национальным
Институтом Стандартов) и в данное время также принимается ISO
(Международной организацией по стандартизации). Однако большинство
коммерческих программ БД расширяют SQL без уведомления ANSI,
добавляя разные особенности в этот язык, которые, как они считают, будут весьма полезны. В этой книге мы будем в основном следовать стандарту ANSI, но одновременно иногда будем давать и некоторые наиболее распространённые отклонения от его стандарта. Вы должны проконсультироваться в документации вашего пакета программ, который будете использовать, чтобы знать, где в нём этот стандарт видоизменен. ПРЕЖДЕ ЧЕМ ВЫ СМОЖЕТЕ ИСПОЛЬЗОВАТЬ SQL, вы должны понять, что такое реляционные базы данных. В этой главе мы объясним и покажем, насколько РБД полезны. Мы не будем обсуждать SQL именно здесь, и, если вы уже знаете эти понятия достаточно хорошо, вы можете просто пропустить эту главу. В любом случае вы должны просмотреть три таблицы, которые предоставляются и объясняются в конце главы; они станут основой наших примеров в этой книге. Вторая копия этих таблиц находится в Приложении E, и мы рекомендуем скопировать их для удобства ссылки к ним. Понятие реляционной базы данныхБаза данных — это структурированный набор постоянно хранимых данных. Постоянность означает, что данные не уничтожаются по завершении программы или пользовательского сеанса, в котором они были созданы. В реляционной базе данных информация хранится в виде двухмерных таблиц. Возможно использование и других структур — когда-то базы данных имели иерархическую или сетевую организацию. Однако реляционный подход доказал свои преимущества для большинства применений и в настоящее время является промышленным стандартом. Реляционная модель была предложена в 1970-е гг. Тедом Коддом, работавшим тогда в IBM. В качестве наглядной иллюстрации реляционной базы данных рассмотрим адресную книгу. Она содержит множество записей, соответствующих отдельным лицым. Для каждого из них может быть определено несколько независимых блоков данных: имя, номер телефона, адрес. Предположим, что адресная книга отформатирована в виде таблицы со строками и столбцами. Каждая строка соответствует определенному лицу, а столбцы содержат данные одного из типов: имя, номер телефоны и адрес. Пример адресной книги, хранящей данные о клиентах, приведен в таблице 1.1. Таблица 1.1
С адресной книгой может возникнуть одна проблема. Как быть, если есть два клиента с именем Celia Brock? Среди ваших близких друзей подобная ситуация маловероятна, но базы данных часто содержат тысячи и миллионы записей, так что эта проблема вполне реальна. Можно предположить, что для решения данной проблемы достаточно ссылаться на строки по их номеру в таблице. Но в каком порядке они должны располагаться? В порядке ввода? В порядке хранения в файловой системе компьютера? В обоих случаях размещение строк будет случайным. Лучше не зависеть от порядка строк, и такая независимость является одной из сильных сторон реляционного подхода. Для обеспечения максимальной гибкости строки в таблице по определению не упорядочены. В этом отношении база данных отличается от традиционной адресной книги. Записи в адресной книге обычно размещаются по алфавиту. В системах управления реляционными базами данных пользователи могут упорядочивать извлекаемую информацию так, как им нужно. Для реализации данной возможности необходимо присвоить каждому лицу уникальный идентификатор, который почти всегда представляет собой число. Это может быть либо уже ассоциированное с лицом число (например, номер страховки), либо число, присвоенное вами. Такое значение, которое должно быть уникальным для каждого лица в базе данных, называется первичным ключом (primary key). Каждая создаваемая таблица базы данных должна иметь первичный ключ, он служит для логической идентификации отдельных строк. В таблице 1.2 приведена таблица Clients, в которую добыавлен столбец для первичного ключа. Таким образом, первичный ключ представляет собой уникальный идентификационный номер, присваиваемый каждому клиенту. Таблица 1.2
Итак, у нас есть основа реляционной базы данных — двухмерная (строки и столбцы) таблица с информацией. Однако реляционные базы данных редко состоят из одной таблицы, в таких случаях они мало чем отличаются от картотеки. Создав несколько таблиц с взаимосвязанной информацией, вы можете выполнять над своими данными гораздо более сложные операции. Мощь базы данных заключается главным образом в связях, которые могут быть установлены между данными, а не в самих данных. Необходимость второй таблицыРассмотрим случай, когда столбец логически может содержать несколько значений для одной и той же строки. Предположим, что требуется добавить к таблице Clients столбец с номерами телефонов. Большинство людей имеют как минимум два телефонных номера — домашний и рабочий, а ведь их может быть и больше: факс, сотовый телефон, пейджер, голосовая почта и т.д. Одним из основных свойств реляционной модели является атомарность значений столбцов — в одной строке только одно значение. При вводе нескольких значений СУБД будет рассматривать их как одно. Решением является построение другой таблицы (назовем ее Client_Phone), в которой первый столбец будет содержать номер телефона, а второй — описание типа номера (домашний, рабочий, факс и т.д.). Разумеется, при этом требуется сопоставить номер телефона его владельцу, представленному в первой таблице, поэтому необходимо найти способ установки связи между таблицами. Для этого можно поместить в таблицу Client_Phone первичный ключ из таблицы Clients. Эти номера уникальны, поэтому мы всегда будем знать, какому клиенту ссответствует данный номер. Столбуц id_num в таблице Client_Phone называется внешним ключом (foreign key). Говорят, что он ссылается на первичный ключ таблицы Clients. Данное отношение показано в таблице 1.3. Если все значения внешнего ключа таблицы Client_Phone ссылаются на значения, которые действительно присутствуют в таблице Clients, то система обладает ссылочной целостностью (referential integrity). В противном случае имеется повод для беспокойства, т.к. база данных содержит телефонные номера клиентов, которые не существуют или не могут быть идентифицированы. Таблица 1.3
Для таблицы Client_Phone также необходим первичный ключ — его должна иметь каждая таблица. Мы не можем использовать id_num, поскольку он не является уникальным (повторяется для телефонных номеров одного клиента). А что если применить сами телефонные номера? Это лучше, но возможна ситуация, когда в одном доме или офисе есть два клиента — их телефонные номера нужно будет хранить отдельно. При использовании номера телефона в качестве первичного ключа мы смогли бы задействовать его только в одной строке таблицы Client_Phone, а, следовательно, ассоциировать только с одним id_num. Первичный или внешний ключ необязательно должен состоять из одного столбца. Можно скомбинировать столбцы id_num и phone. Такая комбинация будет уникальной, поскольку при повторном указании того же номера для какого-либо клиента мы получим две одинаковые записи, одну из которых в любом случае придется удалить. Итак, комбинация id_num и phone является логическим первичным ключом для таблицы Client_Phone. Ключ, состоящий более чем из одного столбца, называется составным (composite) или многоколоночным (multicolumn).
Соединение таблицТеперь нужно связать вторую таблицу с первой так, чтобы номерам телефонов соответствовала информация о клиентах. Обе таблицы остаются разными объектами базы данных, но при извлечении хранящейся в них информации можно связать с каждым значением внещнего ключа родительский ключ, а также любые другие столбцы этих таблиц. Определять какую-либо иную связь между двумя таблицами не требуется. Наличие в одной из них внешнего ключа, значения которого совпадают со значениями первичного ключа другой таблицы, является достаточным условием для определения того, какие строки таблиц связаны (т.е. относятся к одному клиенту). Операция извлечения информации из базы данных называется запросом (query). В SQL запросы реализуются с помощью оператора SELECT. Запрос, который одновременно извлекает данные из более чем одной таблицы путем сопоставления столбцов одной таблицы столбцам других таблиц, называется соединением (join). Соединение собирает вместе все то, что мы расположили в разных таблицах в соответствии с реляционной моделью. С помощью соединения можно получить полную информацию о каждом клиенте: имя, адрес, телефон и т.д. Имя, номер и тип столбца
В отличие от строк, столбцы таблицы (называемые также полями) упорядочиваются и именуются. Так, в таблице Clients (см. таблицу 1.2) третий столбец слева содержит адрес. Во избежание неоднозначности все столбцы таблицы должны иметь разные имена. Имена следует выбирать так, чтобы они отражали содержимое столбца. В наших примерах мы будем использовать в качестве имен столбцов аббревиатуры, такие, как Каждый столбец имеет определенный тип данных (datatype). Все данные конкретного столбца относятся к одному типу: текст, число, дата и т.п. Это следует из логического предположения, что столбец содержит однотипную информацию для всех строк. Работа с реляционной базой данныхТеперь познакомимся с тем, как организуется работа с составными частями реляционной базы данных. В связи с этим следует расмотреть два основных вопроса. Первый из них относится к группированию таблиц. Должны ли все таблицы в базе данных быть связаны между собой? Нет. Группа взаимосвязанных таблиц называется схемой (schema). База данных может содержать любое количество схем. Первоначально (в SQL89) все таблицы, подконтрольные одному пользователю, автоматически входили в одну схему. Стандарт SQL92 изменил эту ситуацию, но вы по прежнему можете встретиться со старой практикой. Второй вопрос касается пользователей. Операционная система, предназначенная для работы только на автономном персональном компьютере, может как различать, так и не различать отдельных пользователей, тогда как система, предназначенная для более широкого применения, является многопользовательской. Аналогично этому, все СУБД, которые могут функционировать где-либо еще, кроме автономных персональных компьютеров, различают пользователей. Однако пользователь базы данных и пользователь операционной системы не обязательно должны быть одним и тем же лицом. Многие пользователи ОС могут работать с БД без дополнительной идентификации, а некоторые могут устанавливать с ней отдельное соединение. Пользователи БД имеют следующие отличия от обычных пользователей ОС:
Простая схема базы данныхТаблицы 1.4, 1.5 и 1.6 образуют простую реляционную базу данных. Она мала, так что с ней легко работать, но в то же время содержит все необходимые компоненты для иллюстрации основных принципов и приемов применения SQL. Эти таблицы вы найдете также в Приложении E. Первый столбец каждой таблицы содержит номера, разные для каждой строки. Это первичные ключи таблиц. Некоторые из номеров встречаются в других столбцах таблиц. Это внешние ключи, которые ссылаются на первичные ключи. Внешние ключи не обязаны иметь те же имена, что и соответствующие им первичные ключи, однако мы используем это соглашение для большей ясности. Таблица 1.4 Salespeople (Продавцы) ---------------------------------------------- SNUM | SNAME | CITY | COMM --------|-----------|--------------|---------- 1001 | Peel | London | .12 1002 | Serres | San Jose | .13 1004 | Motika | London | .11 1007 | Rifkin | Barcelona | .15 1003 | Axelrod | New York | .10 ---------------------------------------------- Таблица 1.5 Customers (Покупатели) ---------------------------------------------- CNUM | CNAME | CITY | RATING | SNUM -------|------------|---------|--------|------ 2001 | Hoffman | London | 100 | 1001 2002 | Giovanni | Rome | 200 | 1003 2003 | Liu | SanJose | 200 | 1002 2004 | Grass | Berlin | 300 | 1002 2006 | Clemens | London | 100 | 1001 2008 | Cisneros | SanJose | 300 | 1007 2007 | Pereira | Rome | 100 | 1004 ---------------------------------------------- Таблица 1.6 Orders (Заказы) ----------------------------------------------- ONUM | AMT | ODATE | CNUM | SNUM -------|-----------|-------------|------|------ 3001 | 18.69 | 10/03/1990 | 2008 | 1007 3003 | 767.19 | 10/03/1990 | 2001 | 1001 3002 | 1900.10 | 10/03/1990 | 2007 | 1004 3005 | 5160.45 | 10/03/1990 | 2003 | 1002 3006 | 1098.16 | 10/03/1990 | 2008 | 1007 3009 | 1713.23 | 10/04/1990 | 2002 | 1003 3007 | 75.75 | 10/04/1990 | 2004 | 1002 3008 | 4723.00 | 10/05/1990 | 2006 | 1001 3010 | 1309.95 | 10/06/1990 | 2004 | 1002 3011 | 9891.88 | 10/06/1990 | 2006 | 1001 -----------------------------------------------
Поле Приведенные таблицы соответствуют реальной ситуации, когда SQL используется для сбора информации о продавцах, покупателях и их заказах. Конечно, таблицы сильно упрощены — в действительности нужно следить за гораздо большим количеством вещей. Теперь выясним, что означают различные столбцы. Столбцы таблицы SalespeopleСТОЛБЕЦ СОДЕРЖАНИЕ --------- --------------------------------------------------- snum уникальный номер назначенный каждому продавцу ("номер служащего"). sname имя продавца. city местонахождение продавца (город). comm комиссионные продавцов в десятичной форме. Столбцы таблицы CustomersСТОЛБЕЦ СОДЕРЖАНИЕ --------- --------------------------------------------------- cnum уникальный номер, назначенный каждому покупателю. cname имя заказчика. city местонахождение покупателя (город). rating код, указывающий уровень предпочтения данного покупателя перед другими. Более высокий номер указывают на большее предпочтение (рейтинг). snum номер продавца, назначенного этому покупателю (из таблицы Продавцов). Столбцы таблицы OrdersСТОЛБЕЦ СОДЕРЖАНИЕ --------- --------------------------------------------------- onum уникальный номер, данный каждой покупке. amt сумма покупки. odate дата покупки. cnum номер покупателя, делающего покупку (из таблицы Покупателей). snum номер продавца, совершившего продажу (из таблицы Продавцов). Работа с SQL
(См. ответы в Приложении A.) |
||||||||||||||||||||||||||||||||||||||||||