федеральное агентство по образованию
государственноеобразовательное учреждение высшего профессионального образования
Российский государственный гуманитарныйуниверситет
институт ИНФОРМАЦИОННЫХ НАУКИ ТЕХНОЛОГИЙ БЕЗОПАСНОСТИ
Факультет информатики
Специальность: прикладная информатика Математическая логикаЯзык SQL
Выполнил
Романов А.Н.
Москва 2007
Содержание
Язык запросов SQL 3
Основные инструменты 9
Оператор SELECT 11
Использование имён и вложенныхзапросов 12
Объединения и внешние соединения 13
Математические функции и средстваработы с датами 15
Группы и агрегатные функции 17
Оператор CASE 18
Создание таблиц и манипуляции сданными 20
Язык запросов SQL
Первыми попытками уйти от построения баз данных (БД) на основе физическойструктуры их размещения на носителях являлисьиндексные файлы. Они обеспечивали доступ кзаписанной в них информации посредством индексных ключей, то есть для поисканеких конкретных записей в файлеиспользовалась совокупность указателей. К недостаткам такого подхода можно отнести, в частности, неоптимальноехранение информации (дублирование, недостаточное структурирование) и значительное время поиска вбольших файлах, не говоря уже о существенныхтребованиях, предъявляемых каппаратному обеспечению.
Одним из решений упомянутых проблем стали иерархические БД. В таких базах элементы строго упорядочены, причем так, что данные одного уровня подчиняются (являетсяподмножеством) данным другого,вышестоящего уровня. В такой модели связи могут быть отражены в виде дерева, причем допускаются только односторонние — от старших уровней к младшим. Подобная структура все еще напоминает древовидную файловую систему, где директорииявляются верхними уровнями, а файлы —нижними. Несмотря на то что по сравнениюс индексными файлами это был существенный шаг вперед, иерархические БДнаследовали многочисленные недостаткипредыдущих систем, заключавшиеся всложности алгоритмов доступа к даннымнижних уровней и повышенных аппаратныхтребованиях.
Иерархические БД не получили широкогораспространения, уступив место новой концепциихранения данных (реляционные БД). Оназаключалась в использовании табличногометода хранения и доступа к конкретным записям, который используются и в настоящее время.
Прогресс в области сетевых технологий поспособствовал возникновению проблеморганизации доступа к данным, расположенным на серверах, с удаленных компьютеров— участников сети. Для оптимизации этого процесса и снижения сетевого трафикаМеждународной организацией по стандартизации(ISO) был разработан и внедрен структурированныйязык запросов SQL.
Сразвитием Глобальной сети и ростом объемов обращающейся в ней информации задачи предоставления доступа к последней практически повсеместно сталирешаться с помощью технологий БД в общем и SQLв частности. В настоящее время рядовой пользователь,сам того не зная, активно работает с базами данных, даже просто просматривая веб-странички и форумы, или пользуясь сервисами электронной почты и ICQ.
Несмотря на то что иерархические БД еще не канули в лету окончательно, они, какупоминалось выше, используются крайне редко — в основном при решении неких специализированных задач, вследствие чего неимеет смысла подробноостанавливаться на их устройстве. Гораздо интереснее рассмотреть реляционныеБД.
Итак,данные в таких базах размещены во взаимосвязанных таблицах, строки которыхназываются записями, а столбцы — полями. Приэтом данные в ячейках одного поля должны
быть одинакового типа. Вкаждой таблице, как правило, имеются специальныеполя, которые позволяют однозначно идентифицировать ту или иную запись — они называются первичнымиключами или первичными индексами. Такиеполя помогают отличать одну запись отдругой, даже если все остальные поля нескольких таких записей абсолютно идентичны. Например, представьте, что вы разрабатываете справочник сотрудников своей организации, и при этом каждая запись хранит данные об одном сотруднике, а их выборка осуществляется по полю «Фамилия». Может оказаться так, что в организации работает несколько человек с одинаковой фамилией. Чтобы отличить эти записи друг от друга, применяются первичные индексные поля. Чаще всего за тип данных первичного ключа берется целочисленное значение счетчика — в таком случае при добавленииновой записи в таблицу значения этого полязаполняются автоматически. Однако не запрещается использовать в качестве первичногоключа поле, имеющее, к примеру, символьный тип данных, хотя подобные ситуации возникают крайне редко.
Помимозадачи идентификации записей первичные индексы также часто используются длясвязывания между собой данных из разных таблиц. Кроме первичных индексов существуют и вторичные индексы, которые обеспечиваютмеханизм быстрого поиска и доступа к данным таблицы. Чтобы получить ответ назапрос к таблице, не имеющей индексного поля, SQL-серверу придется сканировать полностью всю таблицу,считывая строки целиком.Очевидно, что такой подход прибольших объемах информации слишком расточителен с точки зрения затрат аппаратных ресурсов. Тем не менее необходимопомнить, что с увеличением количества индексов растет и объем базы данных.
По признаку метода доступа БД делятсяна локальные, сетевые ираспределенные.
К локальным базам доступ возможентолько с того компьютера, на котором они расположены. Сетевые базы призваны обеспечитьработу с данными с других компьютеровпосредством локальной сети или Интернета. Распределенные БД — это, по сути,подвид сетевых баз с той лишь разницей, что различные части информации находятсяна множестве разных компьютеров.
Насегодняшний день основным видом являетсявторой тип БД — сетевые базы. Именно ониприменяются в Интернете для организации доступа пользователей к информации сайтов, форумов, гостевых книг и каталогов товаров.
Такие БД делятся на файл-серверные и клиент-серверные. В файл-серверной моделипри подключении СУБД клиента к удаленной базе все данные скачиваются на локальный компьютер, а после их обработки или изменения снова закачиваются на сервердля обновления в полном составе. Таким образом, происходит весьма интенсивный информационный обмен с сервером,что чрезвычайно нагружает сеть. Кроме того, в такой модели весьма сложно организовать одновременную работу несколькихпользователей, поэтому в настоящее время она используется редко и только для простых баз. Клиент-серверная модельорганизована совершенно иначе. Системауправления такой базой состоит издвух частей — клиента и сервера. Клиентская часть программы посылаетзапросы с помощью языка запросов SQL,
серверная частьобрабатывает их и отправляет обратно только те данные, которые были нужны пользователю. Информация об изменении этих данных возвращается на сер-
вер, который обрабатывает ее ификсирует в общей базе.Нагрузка на сеть при такой организацииработы минимальна, а организацию одновременной работы нескольких пользователей берет на себя сервер.
Целью любойСУБД являться предоставление пользователю простых механизмов доступа и манипулирования данными.Существует много различных методов ее достижения, одним из которых являетсяязык SQL. Расшифрованнаяи переведенная на русский язык эта аббревиатура будет выглядеть как Структурированный Язык Запросов.
Стандарт языка SQL. определяется Американским национальным институтомстандартов (ANSI) и Международной организацией постандартизации (ISO). Однако некоторые производители БД вносят в язык свои изменения идополнения. Например, компания Огас1есоздала язык PL/SQL, которыйявляется процедурным расширением оригинальногоSQL.
Однако истандартный SQLможет использоваться в двух различныхвариантах — интерактивном и вложенном.Первый представляется собойотдельный программный модуль на SQL,который сам выполняет запросы и отображаетрезультаты работы. Второй — этовнедрение элементов SQLв другойязык высокого уровня, например С или Delphi. В этом случае основная программа самостоятельно формируетзапросы для сервера SQL, а потом использует результатывыборок из базы, не предъявляя их пользователю в чистом виде.
В целом же SQL— это язык, ориентированный на работу с реляционными базами данных. Егоиспользование позволяет на порядок сократить объем работ, который понадобился бы в случае созданияприложений, использующих БД на универсальном языке программирования, например на том жеС.
Действительно,чтобы сформировать реляционнуюбазу данных на С, нужно было бы описать как минимум один объект (двумерный массив), называемый в SQL.таблицей, который должен иметь возможность менятьразмер для вмещения любого необходимогочисла строк. Затем пришлось бы создавать процедуры для помещения значений в такую таблицу, а также поиска и извлечения этих значений. Это непросто даже напервый взгляд. Так, если бы вы захотели найти все строки в таблице «TAB», в которых значения некоего поля «num» равно 5, то необходимо было бывыполнить по шагам весьмасложную процедуру.
Грамотный листинг программы, реализующий такой алгоритм на С исоблюдающий все подобающиепроверки займет, пожалуй, всю эту страницу. В случае же использования SQLдостаточно написать вот такой запрос:
SELECT *
FROM tab
WHERE num = 5
Дело в том, чтокоманды SQLмогут работать со всеми записями таблицы как с единым объектом. Необходимость организации циклов и проверок значений вручную отпадает.
Упомянутый в примере оператор SELECTявляется основным и наиболее часто используемымдля выборки данных из таблиц. Все обращения к таблицам происходят в видезапросов, которые состоят из таких же операторов, — меняются только условия поиска.
В настоящеевремя трудно найти язык программированиявысокого уровня, которыйбы не поддерживал работу с SQL. Для этих целей разработчиками различных компиляторов предусмотрены специальные библиотеки компонентов, которыеобеспечивают связь между приложениями, написанными на их языке, и серверамиSQL, в результате чего данные, которые будут выбираться из базы, можно использовать в клиентской программеобработки по своему усмотрению.
Сразупредупредим, что SQLServer2000 возможно установить только на серверные версии операционной системы Windows— 2000 Serverи 2003 Server. Попытки инсталляции ее на пользовательские версии ОС, такие как WindowsХР Professional, если только речь не идет о клиентскойчасти, не увенчаются успехом. Если же вы непременно хотите пользоваться языком запросов, работая под пользовательской ОС, существует MSDE— это урезанная версия SQLServer, которая входит в дистрибутив МSOffice2003.
После запуска инсталлятора скомпакт-диска в двух первых окнах мастера установки необходимо последовательновыбрать пункты «Components» и «InstallDatabaseServer». Результатом этих действий станет появление окна спредложением указать расположение будущегосервера. Здесь возможны следующие варианты: «LocalComputer» — локальный компьютер, «Remotecomputer» — удаленный компьютер в вашейсети, «VirtualServer» — виртуальный серверсети. Этот выбор зависит только от конкретнойзадачи, которую вы решаете в данныймомент.
Если вывыбрали компьютер, где до этого уже существовала некая версия SQLServer, тов следующем окне будет доступен пункт «Upgrade, removeoraddcomponentstoanexistinginstanceofSQLServer» — добавление, изменение и удалениесуществующих компонентовсервера. Иначе здесь можно будетвыбрать лишь «CreateanewinstanceofSQLServerorinstallClientTolls» — создать новый экземпляр SQL-сервера или установить клиентскую часть. Кстати, этопо-
следнее «или» способствует появлениюеще одного ветвления в дереве вариантов установки. Следующее окно «InstallationDefinition» предоставляет на выбор пункты: «ClientToolsOnly» — поставить клиентскую часть, которая используется дляорганизации доступа к серверу с клиентскихмашин; «ServerandClientTools» — серверную и клиентскую части, атакже «Connectivityonly» — только драйверы для присоединения к базе. Последний тип установки применяется исключительно на клиентскихмашинах, которые должны работать с базами данных, то есть утилиты для работы ссервером, подобные EnterpriseManadger, инсталлироваться не будут. Поскольку мы устанавливаем именно сервер — здесь следует выбрать второй вариант.
Ввод имени («InstanceName») в следующем окне недолжен вызвать затруднений. Поумолчанию оно будет идентично NETBIOS-имени вашей машины. Если требуется его изменить, придется снять галочку в пункте «Default», после чего можно будет ввести другое название.
Из предложенныхдалее вариантов установки «Typical», «Minimum» и «Custom» полезно использовать именно последний вариант. При этомвыбирать что-то из спискапредложенных компонентов не придется — пунктов, отмеченных здесь по умолчанию, более чем достаточно дляначала работы сервера.
ОднакопараметрамзапускасервисовSQL Server вследующемокнестоитуделитьболеепристальноевнимание: «Auto start SQL Service» — всесервисыстартуютавтоматически; «Customizethe setting for each Service» — каждомусервисуназначитьсвоипараметрызапуска. Если вы выберете второй вариант, то в левой части окна на панели «Services» станут доступны элементы «SQLServer» и «SQLServerAgent». При выборе любого из них вправой части окна на панели «ServiceSetting» можно будет настроить параметры запуска, выбраводин из трех стандартных вариантов: отключено, автоили вручную.
На этомнастройки самого сервера фактически завершены, осталось только указать параметры учетных записей,авторизации и режималицензирования. Итак, «UsetheLocalSystemaccount» — использовать учетную запись локальной системы, «UseaDomainUseraccount» — использовать доменную учетную запись. Выбор целиком зависит от вашихпредпочтений.
Дляуказания метода авторизации (AuthenticationMode) необходимо выбрать: «WindowsAuthenticationMode» — использоватьавторизацию WindowsNT или«MixedMode (Windows Authentication and SQL Server Authentication)» — использоватьсмешаннуюавторизациюWindowsNTи SQL-сервера). При использовании второго метода не забудьте указать парольучетной записиадминистратора «sа»,которая создается по умолчанию.
И, наконец, последнее окно мастера «ChooseLicensingMode» посвящено выбору режима лицензирования, который зависитот условий, на которых вы приобрели данную версию SQL Server2000.
Основныеинструменты
Наиболее часто используемой утилитой для работы с SQLServerявляется EnterpriseManager. Этот инструмент создавался с целью облегчения выполнения наиболее сложных административных задач, сочетая простоту работы с высокой функциональностью. Среди них такие какуправление системой безопасности, создание баз данных и ее объектов, создание и восстановление резервных копий, запуск и установка служб, атакже конфигурирование связанных иудаленных серверов.
Например, создание новой базыданных с помощью EnterpriseManagerсводится к нескольким кликам мыши и вводу имени БД. В левой части экрана утилиты необходимо выбрать тот SQLServer, на котором она будет размещена, и нажать правой кнопкой мыши на папке Database, после чего в контекстном меню выбрать пункт «NewDatabase». В появившемся окне «DatabaseProperties» в поле «Name» необходимо вписатьназвание базы и нажать кнопку «ОК». Описаниеэтого процесса заняло больше времени,чем он длился бы на деле.
Созданиетаблиц происходит совершенноаналогично: клик сначала правой кнопкой мыши на значке «Table», затем левой — на пункте «NewTable» в контекстном меню. Выше был приведен пример алгоритма выборки из базы данных для классического языка высокого уровня. Просто представьте, сколько времени и сил заняло бы описание на нем такойструктуры как БД с несколькими взаимосвязанными таблицами.
Как бы хорошо не была настроена база данных, всегда существует вероятность потери информации по независящим от администратора причинам. Для сведения подобных потерь к разумному минимуму EnterpriseManagerсодержит инструмент резервного копирования БД.
Чтобы выполнить резервное копированиебазы вручную, нужно щелкнуть правой кнопкой мыши по названию базы и выбрать «Все задачи • > BackupDatabase». Далее в появившемся окне надо нажать кнопку «Аdd'», после чего выбрать каталог для сохранения и в поле «Filename» ввести имя файла, в котором будет содержаться база. Имя этого файла с названием базы может быть никак не связано. После подтверждения намерения остается только дожидаться конца процесса копирования.
Для того чтобы восстановитьданные из ранее сохраненного файла,необходимо иметь на SQLServerбазу данных с названием,идентичным имени родительской базы. Другими словами, если вы сохранялиБД как Data_Base, то для восстановления данных необходимо создать на серверебазу с таким же названием (не путать с именем файла резервной копии).
Для восстановления информации изфайла нужно нажатьправой кнопкой мыши на базу, предназначенную для приема данных и выбрать «Все задачи – RestoreDatabase». Далее в
последовательно сменяющих друг друга окнах нужно выбрать пункты «FromDevise», «SelectDevise» и «Аdd» и указать каталог, в котором расположен резервныйфайл.
Вторая по важности и частоте использования утилита после EnterpriseManagerэто QueryAnalyzer. Она предназначена для выполнения, отладки и анализа запросов.Окно «QueryAnalizer» разделенона три части. Слева находится браузер объектов (ObjectBrowser), с помощью которого можно посмотреть списоквсех объектов, расположенных в любой базе данных сервера, а также переченьвсех функций и типов данных. Правая часть разделена на верхнюю и нижнюю, при этом верхняяполовина является полемдля ввода запросов, а нижняяиспользуется для вывода результатов их работы и отладочной информации.
При отладкехранимых процедур весьма удобнавозможность трассировки их выполнения: для этого необходимо кликнуть на нужной процедуре правой кнопкой мыши и в появившимся контекстном меню выбрать пункт «Debug».
Помимовыполнения процедур и запросов в QueryAnalyzerпредусмотрена возможность оценки скорости работы. Эту функциюможно включить, еслиоткрыть меню «Query» и выбрать в нем, соответственно, пункты «DisplayEstimated», «ExecutionPlan» или «DisplayExecutionPlan».
Оператор SELECT
Основной оператор языка SQL, предназначенный для выборки данных,- SELECT:
SELECT * FROM Table 1
Звёздочка означает все столбцы, а Table1 – имя таблицы, из которой мы этистолбцы хотим извлечь. Практическуюценность оператору SELECTпридает ключевое слово WHERE, позволяющее выводить исключительно те строки таблицы,которые соответствуютусловию. Предположим, у насесть таблица с информацией о персонале (Employees), где указаны имя работника (Name) и его заработная плата (Salary). Если нам нужно увидеть данные обо всех работниках, получающих заработную платуболее 30 000 рублей, мыформулируем запрос:
SELECT Name FROM Employees WHERE Salary > 30000
На практикесуществует необходимость запрашивать информацию одновременно из нескольких таблиц. Предположим, что у нас есть таблица Agentsс информацией о торговых агентах: идентификационныйномер (Agent_id), имя (Name) и дата рождения (Birth_Date). Есть еще одна таблица — Contacts, где содержатся данные о контрактах, заключенных агентами: идентификационный номер клиента (Client_id),номер агента (Agent_id),дата заключения контракта (CDate) и сумма сделки (Gross_Income).
Предположим, необходимо премировать агентов, заключавших с начала года контракты на сумму более 500 000 рублей. Запрос к базе данных будет выглядеть так:
SELECT Name, Bitth_Date FROM Agents, Contacts WHEREAgents.Agent_id = Contracts.Agent_id AND Contracts.CDate >`31.12.2004` ANDCONTRACTS.Gross_Income > 500000
Условия WHEREсвязывает друг с другом две таблицы через номер агента,отбрасывает старые достижения и выбирает значительные контракты. Логический оператор ANDпозволяет задавать несколько условий.Запись . применяется для того, чтобы различать столбцы с одним и тем женазванием из разныхтаблиц.
Поскольку один агент может заключитьнесколько больших контрактов, его данные могут быть несколько раз продублированы. Чтобы избежатьэтого, необходимо использоватьключевое слово DISTINCT:
SELECTDISTINCT Name, Birth_Day From …
Использованиеимен и вложенных запросов
В SQL-конструкциях назначение новых имен применяется, чтобы сохранить длядальнейших операцийрезультаты, возвращаемые запросами ивстроенными функциями, и сделать текстзапроса более компактным за счетсокращений. Для демонстрации эффектов переназначения имен, возьмем, кпримеру, таблицу Roomsс информацией о жилых комнатах вмногоквартирном доме со следующими столбцами: идентификатор комнаты (Room_id), тип (Room_type), длина (Length) и ширина (Width). Предположим, мы хотим получить информацию о жилой площади всех спален игостиных в доме. Дляэтогоформулируемзапрос:
SELECTRoom_Type, Length * Width AS
Living_Space
FROM Rooms
WHERERoom_Type = `ГостинаяOR Room_Type =`Спальня`
В результирующей таблице не будетданных о длине и ширине, зато появитсястолбец с информацией о площади, котораябыла вычислена непосредственно приисполнении запроса
Второй вариантприменения ключевого слова ASможно проиллюстрировать на примере о торговых агентах изпредыдущей заметки, который теперь будет выглядетьтак:
SELECT DISTINCT Name, Birth_Date
FROM Agents AS A1, Contracts AS C1
WHERE A1.Agent_id = C1.Agent_id AND C1.CDate
>`31.12.2004` AND C1.Gross_Income > 500000
Дав с помощью ключевого слова АSтаблицам Agentsи Contactsсокращенные имена, мы сделали текст болеекомпактным. Запрос можно сделать многоступенчатым, тогда результат вложенного запроса станетисходными данными. Тотже самый пример с агентами можно выполнить ввиде вложенного запроса:
SELECT Name, Birth_Day
FROM Agents
WHERE Agent_id IN(SELECT Agent_id
FROM Contracts
WHERE CDate >`31.12.2004` AND
Gross_Income >500000
В данном случае предикат INпоследовательно проверяет, имеется ли среди результатоввложенного запроса по базе контрактов идентификатор каждого из агентов. Если он есть, то в результирующую таблицу головногозапроса добавляются его данные (для противоположного результата можно использовать предикат NOTIN). В большинстве случаев предпочтительнее вместо вложенных запросов применять соединение таблиц по общим столбцам (...WHERE Agents.Ag_Num= Contracts.Ag_Num...), однако иногда бывает, что все-таки без вложений необойтись.
Объединенияи внешние соединения
Выше мы воспользовались оператором ORдля выборки данных о спальнях и гостиных. Можнопойти другим путем ииспользовать оператор UNIONдля объединения двух запросов:
(SELECT Room_Type, Length1 * Width1 AS
Living_Space FROM Rooms WHERE Room_Type =
`Гостиная`) UNION(SELECT Room_Type, Length1 *
Width1 AS Living_Space FROM Rooms WHERE
Room_Type = `Спальня`)
Оператор UNIONстроит на основе двух таблиц третью, куда попадают строки,которые есть либо в первой исходной, либо во второй, либо в обеих вместе; строки-дубликаты при этом удаляются. Иногда для подобных целей удобнеепользоваться оператором OR, однако если условия объединяемых подзапросов сложные, UNIONдля их составления подходит больше. Суть такого инструмента как внешнеесоединение можно пояснить на следующем примере. Допустим, нам необходимо сделатьвыборку по контрактам, заключенным агентами в июне 2005 года. Мы можем воспользоваться для этого такимзапросом:
SELECT Name, CDate, Gross_Income
FROM Agents AS A1, Contracts AS C1
WHERE A1.Agent_id = C1.Agent_id ANDC1.CDate
BETWEEN `01.06.2005`AND`30.06.2005`
Он, разумеется, выдаст правильныерезультаты, однаконаличие имени агента после обработки запроса зависит от того, заключил ли он сделку в этот период. Еслинеобходимо, чтобы в результирующей таблице всегда присутствовали все агенты,необходимо использовать так называемое левое внешнее соединение (LEFTOUTERJOIN). Его смысл состоит в том, что все строки таблицы, указанной слева от оператора LEFTOUTERJOIN, попадают в таблицу-результат, а из таблицы справа берутся толькоданные, которыесоответствуют условию:
SELECT Name, CDate, Gross_Income
FROM Agents LEFT OUTER JOINContracts ON
Agents.Agent_id = Contracts.Agent_id
AND Contracts.CDate BETWEEN`01.06.2005` AND
`30.06.2005`
Каждый агент из таблицы Agentsзаписанной слева от LEFTOUTERJOIN, попадет в результат запроса, даже если емунельзя будет подобратьсоответствующих строк из правойтаблицы (поскольку не все агенты заключали контракты в июне 2005 года). Необходимо обратить внимание, что вместо ключевого слова WHEREздесь используется слово ON. Если использовать слово WHERE, результат будет тот же самый, что и с обычным запросом. Следует также помнить,что синтаксис левого внешнего соединения может сильно различаться в разных системах.
Математическиефункции и средства работы с датами
Поскольку SQLориентирован на выборку данных, а нена управление вычислениями, егоматематический инструментарий довольноограничен. Впрочем, перечень доступныхфункций в продуктах различных разработчиков может варьироваться. Как правило, в большинстве реализаций присутствуют следующие функции: POWER(возведение в степень), SQRT(квадратный корень), АВS(модуль), LNи LOG10 (натуральныйи десятичный логарифмы), ЕХР(экспоненциальная функция). Функция ROUND(х, р) округляет число х до р десятичных знаков, TRUNCATE(х, р) — усекает. Функции FLOOR(х) и CEILING(х) возвращают ближайшие к нецелому х целые