355 500 произведений, 25 200 авторов.

Электронная библиотека книг » авторов Коллектив » Базы данных: конспект лекций » Текст книги (страница 5)
Базы данных: конспект лекций
  • Текст добавлен: 6 октября 2016, 00:12

Текст книги "Базы данных: конспект лекций"


Автор книги: авторов Коллектив


Жанр:

   

Базы данных


сообщить о нарушении

Текущая страница: 5 (всего у книги 12 страниц)

1. Операция объединения.

Для того чтобы реализовать операцию объединения двух отношений приходится использовать одновременно два оператора Select, каждый из которых соответствует какому-то одному из исходных отношений-операндов. И к этим двум базовым операторам Select необходимо применить специальную операцию Union. Учитывая все вышесказанное, запишем, как же операция объединения будет выглядеть с использованием семантики языка структурированных запросов:

Selectсписок имен атрибутов отношения 1

Fromимя отношения 1

Union

Selectсписок имен атрибутов отношения 2

Fromимя отношения 2;

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

Но, что интересно отметить, сами имена атрибутов в этих отношениях могут быть различными. В таком случае результирующему отношению приписываются имена атрибутов, указанные в первом операторе Select.

Также необходимо знать, что использование операции Union предполагает автоматическое исключение из результирующего отношения всех дубликатов кортежей. Поэтому, если вам нужно, чтобы все повторяющиеся строки в конечном результате сохранились, вместо операции Union следует применять модификацию этой операции – операцию Union All. В таком случае операция объединения двух отношений будет выглядеть следующим образом:

Selectсписок имен атрибутов отношения 1

Fromимя отношения 1

Union All

Selectсписок имен атрибутов отношения 2

Fromимя отношения 2;

В этом случае из результирующего отношения дубликаты кортежей удаляться не будут.

Используя уже упоминавшееся ранее обозначение для необязательных элементов и опций в операторах Select, запишем самый общий вид операции объединения двух отношений на языке структурированных запросов:

Selectсписок имен атрибутов отношения 1

Fromимя отношения 1

Union [All]

Selectсписок имен атрибутов отношения 2

Fromимя отношения 2;

2. Операция пересечения.

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

Этот способ предполагает участие двух конструкций Select, но они не равноправны (как в представлении операции объединения), одна из них является как бы «подконструкцией», «подциклом». Такой оператор обычно называют подзапросом.

Итак, пусть у нас имеются две схемы отношений (R1 и R2), приблизительно определенные следующим образом:

R1 (ключ, …) и

R2 (ключ, …);

Воспользуемся также при записи этой операции специальной опцией in, что буквально означает «в» или (как в данном конкретном случае) «содержится в».

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

Select *

From R1

Whereключ in

(SelectключFrom R2);

Таким образом, мы видим, что подзапросом в данном случае будет являться оператор в круглых скобках. Этот подзапрос в нашем случае возвращает список значений ключа отношения R2. И, как следует из нашей записи операторов, из анализа условия выборки, в результирующее отношение попадут только те кортежи отношения R1, ключ которых содержится в списке ключей отношения R2. То есть, в итоговом отношении, если вспомнить определение пересечения двух отношений, останутся лишь те кортежи, которые принадлежат обоим отношениям.

3. Операция разности.

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

Но в отличие от воплощения в жизнь предыдущей операции, при реализации операции разности необходимо использовать другое ключевое слово, а именно not in, что в дословном переводе означает «не в» или (как уместно перевести в нашем рассматриваемом случае) – «не содержится в».

Итак, пусть, как и в предыдущем примере, у нас имеются две схемы отношений (R1 и R2), приблизительно заданные:

R1 (ключ, …) и

R2 (ключ, …);

Как видим, среди атрибутов этих отношений снова заданы ключевые атрибуты.

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

Select *

From R1

Where ключ not in

(Select ключ From R2);

Таким образом, в результирующее отношение выбираются только те кортежи отношения R1, ключ которых не содержится в списке ключей отношения R2. Если рассматривать запись буквально, то действительно получается, что из отношения R1 «вычли» отношение R2. Отсюда делаем вывод, что условие выборки в этом операторе записано верно (ведь определение разности двух отношений выполняется) и использование ключей, как и в случае реализации операции пересечения, полностью оправдано.

Два случая применения «метода ключей», которые мы рассмотрели, являются самыми распространенными. На этом изучение использования ключей в составлении операторов, представляющих отношения, завершим. Все оставшиеся бинарные операции реляционной алгебры записываются иными способами.

4. Операция декартова произведения.

Как мы помним из предыдущих лекций, декартово произведение двух отношений-операндов составляется как набор всех возможных пар именованных значений кортежей на атрибутах. Поэтому на языке структурированных запросов операция декартова произведения реализовывается при помощи перекрестного соединения, обозначаемого ключевым словом cross join, что буквально и переводится «перекрестное объединение» или «перекрестное соединение».

Оператор Select в конструкции, представляющей операцию декартова произведения на языке структурированных запросов, присутствует только один и имеет следующий вид:

Select *

From R1cross join R2

Здесь R1 и R2 – имена исходных отношений-операндов. Опция cross join обеспечивает, что в результирующее отношение запишутся все атрибуты (все, потому что в первой строчке оператора поставлен значок «*»), соответствующие всем парам кортежей отношений R1 и R2.

Очень важно помнить одну особенность воплощения в жизнь операции декартова произведения. Эта особенность является следствием определения бинарной операции декартова произведения. Напомним его:

r4(S4) = r1(S1) × r2(S2) = {t(S1S2) | t[S1] ∈ r1& t(S2) ∈ r2}, S1S2= ∅;

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

Рассмотрим пример, в котором нужно найти декартово произведение двух отношений, имеющих некоторые имена своих атрибутов совпадающими. Итак, пусть даны следующие отношения:

R1 ( A, B),

R2 (B, C);

Мы видим, что атрибуты R1.B и R2.B имеют одинаковые имена. С учетом этого оператор Select, реализующий на языке структурированных запросов эту операцию декартова произведения, будет выглядеть следующим образом:

Select А, R1.B as B1, R2.B as B2, C

From R1cross join R2;

Таким образом, с использованием опции переименования as, у машины не возникнет «вопросов», по поводу совпадающих имен двух исходных отношений-операндов.

5. Операции внутреннего соединения.

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

Итак, для начала вспомним определение операции внутреннего соединения, которое мы проходили раньше:

r1(S1) × Pr2(S2) = σ

(r1 × r2), S1S2 = ∅.

Для нас в этом определении особенно важно то, что рассматриваемые схемы отношений-операндов S1 и S2 не должны пересекаться.

Для реализации операции внутреннего соединения в языке структурированных запросов существует специальная опция inner join, которая и переводится с английского буквально «внутреннее объединения» или «внутреннее соединение».

Оператор Select в случае осуществления операции внутреннего соединения будет выглядеть следующим образом:

Select *

From R1inner join R2;

Здесь, как и раньше, R1 и R2 – имена исходных отношений-операндов.

При реализации этой операции нельзя допускать пересечения схем отношений-операндов.

6. Операция естественного соединения.

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

Так как рассматриваемая нами операция естественного соединения является частным случаем операции внутреннего соединения, для ее реализации используется та же опция, что и для предыдущей рассмотренной операции, т. е. опция inner join. Но поскольку при составлении оператора Select для операции естественного соединения необходимо еще учесть условие равенства кортежей исходных отношений-операндов на пересечении их схем, то дополнительно к означенной опции применяется ключевое слово on. В переводе с английского, это буквально означает «на», а применительно к нашему смыслу, можно перевести как «при условии».

Общий вид оператора Select для выполнения операции естественного соединения следующий:

Select *

Fromимя отношения 1inner joinимя отношения 2

onусловие равенства кортежей;

Рассмотрим пример.

Пусть даны два отношения:

R1 ( A, B, C),

R2 (B, C, D);

Операцию естественного соединения этих отношений можно реализовать с помощью следующего оператора:

SelectА, R1.B, R1.C, D

FromR1inner joinR2

onR1.B = R2.B and R1.C = R2.C

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

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

Интересно, что использованная формулировка условия соединения (R1.B = R2.B and R1.C = R2.C) предполагает, что общие атрибуты соединяемых отношений Null-значений не допускают. Это изначально встроено в систему языка структурированных запросов.

7. Операция левого внешнего соединения.

Выражение на языке структурированных запросов SQL операции левого внешнего соединения получается из реализации операции естественного соединения заменой ключевого слова inner на ключевое слово left outer.

Таким образом, на языке структурированных запросов эта операция запишется следующим образом:

Select *

Fromимя отношения 1 left outer joinимя отношения 2

onусловие равенства кортежей;

8. Операция правого внешнего соединения.

Выражение для операции правого внешнего соединения на языке структурированных запросов получается из осуществления операции естественного соединения заменой ключевого слова inner на ключевое слово right outer.

Итак, получаем, что на языке структурированных запросов SQL операция правого внешнего соединения запишется следующим образом:

Select *

Fromимя отношения 1 right outer joinимя отношения 2

onусловие равенства кортежей;

9. Операция полного внешнего соединения.

Выражение на языке структурированных запросов операции полного внешнего соединения получается, как и в двух предыдущих случаях, из выражения для операции естественного соединения путем замены ключевого слова inner на ключевое слово full outer.

Таким образом, на языке структурированных запросов эта операция запишется так:

Select *

Fromимя отношения 1full outer joinимя отношения 2

onусловие равенства кортежей;

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

4. Использование подзапросов

Как можно было понять из пройденного материала, понятие «подзапрос» в языке структурированных запросов является понятием базовым и довольно широко применимым (иногда, кстати, их еще называют SQL-запросами. Действительно, практика программирования и работы с базами данных показывает, что составление системы подзапросов для решения различных сопутствующих задач – деятельность гораздо более благодарная по сравнению с какими-то другими приемами работы со структурированной информацией. Поэтому, рассмотрим пример для лучшего понимания действий с подзапросами, их составлением и использованием.

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

Предметы (Код предмета, Имя предмета);

Студенты (№ зачетной книжки, Фамилия, Имя, Отчество);

Сессия (Код предмета, № зачетной книжки, Оценка);

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

Для удобства работы, дополнительно предположим, что атрибуты «Фамилия», «Имя» и «Отчество» не допускают Null-значений и не являются пустыми. Это требование вполне объяснимо и закономерно, ведь в базу данных любого учебного заведения первыми из данных на нового ученика вводятся именно данные о его фамилии, имени и отчестве. И само собой разумеется, что не может быть записи в подобной базе данных, в которой присутствуют данные на ученика, но при этом неизвестно его имя.

Заметим, что атрибут «Имя предмета» схемы отношения «Предметы» является ключом, поэтому, как следует из определения (подробнее об этом будет сказано дальше), все наименования предметов являются уникальными. Это тоже понятно и без пояснения представления ключа, ведь все преподающиеся в учебном заведении предметы должны иметь и имеют различные имена.

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

Во-первых, нам будет полезна функция Trim, записывается Trim («строка»), т. е. аргументом этой функции является строка. Что делает эта функция? Они возвращает сам аргумент без пробелов, стоящих в начале и в конце этой строки, т. е., эту функцию применяют, например, в случаях: Trim («Богучарников») или Trim («Максиме-енко»), когда после или до аргумента стоят по несколько лишних пробелов.

А во-вторых, необходимо также рассмотреть функцию Left, которая записывается Left (строка, число), т. е. функцию от уже двух аргументов, одним из которых является, как и раньше, строка. Второй ее аргумент – число, оно показывает, сколько символов из левой части строки следует вывести в результат.

Например, результатом операции:

Left («Михаил, 1») + «.» + Left («Зиновьевич, 1»)

будут инициалы «М. З.». Именно для выведения инициалов студентов мы и будем использовать эту функцию в нашем запросе.

Итак, приступим к составлению искомого запроса.

Для начала составим небольшой вспомогательный запрос, который потом используем в основном, главном запросе:

Selectзачетной книжки, Оценка

FromСессия

WhereКод предмета = (SelectКод предмета

FromПредметы

WhereИмя предмета = «Базы данных»)

as«Оценки „Базы данных“;

Применение здесь опции as означает, что мы присвоили этому запросу псевдоним «Оценки „Базы данных“. Сделали мы это для удобства дальнейшей работы с этим запросом.

Далее, в этом запросе подзапрос:

SelectКод предмета

FromПредметы

WhereИмя предмета = «Базы данных»;

позволяет выделить из отношения «Сессия» те кортежи, которые относятся к рассматриваемому предмету, т. е. к базам данных.

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

А весь запрос «Оценки „Базы данных“ позволяет выделить из отношения «Сессия» данные о тех студентах (их номера зачетных книжек и оценки), которые удовлетворяют условию, оговоренному в подзапросе, т. е. информацию о предмете под названием «База данных».

Теперь составим основной запрос, используя уже полученные результаты.

SelectСтуденты.зачетной книжки,

Trim (Фамилия) + « » + Left (Имя, 1) + «.» + Left (Отчество, 1) + «.»asФИО, Оценки «Базы данных». Оценка

FromСтудентыinner join

(

Selectзачетной книжки, Оценка

FromСессия

WhereКод предмета = (SelectКод предмета

FromПредметы

WhereИмя предмета = «Базы данных»)

) as«Оценки „Базы данных“.

onСтуденты.зачетной книжки = Оценки «Базы данных».зачетной книжки.

Итак, сначала мы перечисляем атрибуты, которые будет необходимо вывести, после окончания работы запроса. Необходимо упомянуть, что атрибут «№ зачетной книжки» из отношения Студенты, оттуда же – атрибуты «Фамилия», «Имя» и «Отчество». Правда, два последних атрибута выводим не полностью, а только первые буквы. Также мы упоминаем атрибут «Оценка» из запроса Оценки «Базы данных, которое ввели раньше.

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

Надо заметить, что так как атрибуты «Фамилия», «Имя» и «Отчество» по условию не допускают Null-значений и не являются пустыми, то формула вычисления, возвращающая атрибут «ФИО» (Trim (Фамилия) + « » + Left (Имя, 1) + «.» + Left (Отчество, 1) + «.»as ФИО), соответственно не требует дополнительных проверок, упрощается.

Лекция № 7. Базовые отношения

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

Необходимо знать, что в зависимости от своей природы и структуры, отношения делятся на:

1) базовые отношения;

2) виртуальные отношения.

Отношения базового вида содержат только независимые данные и не могут быть выражены через какие-либо другие отношения баз данных.

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

1. Базовые типы данных

Типы данных, как и отношения, делятся на базовые и виртуальные.

(О виртуальных типах данных мы поговорим чуть позже, посвятим этой теме отдельную главу.)

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

Прежде чем перейти к рассмотрению собственно базовых типов данных, перечислим, каких типов данные вообще бывают:

1) числовые данные;

2) логические данные;

3) строковые данные;

4) данные, определяющие дату и время;

5) идентификационные данные.

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

Назовем их.

1. В числовом типе данных выделяют:

1) Integer. Этим ключевым словом обычно обозначают целый тип данных;

2) Real, соответствующий вещественному типу данных;

3) Decimal (n, m). Это десятичный тип данных. Причем в обозначении n – это число, фиксирующее общее количество знаков числа, а m показывает, сколько символов из них стоит после десятичной точки;

4) Money или Currency, введен специально для удобного представления данных денежного типа данных.

2. В логическом типе данных обычно выделяют только один базовый тип, это Logical.

3. Строковый тип данных насчитывает четыре базовых типа (имеются в виду, разумеется, наиболее распространенные):

1) Bit (n). Это строки бит с фиксированной длиной n;

2) Varbit (n). Это тоже строки бит, но с переменной длиной, не превышающей n бит;

3) Char (n). Это строки символов с постоянной длиной n;

4) Varchar (n). Это строки символов, с переменной длиной, не превышающей n символов.

4. Тип дата и время включает в себя следующие базовые типы данных:

1) Date – тип данных даты;

2) Time – тип данных, выражающих время суток;

3) Date-time – тип данных, выражающий одновременно и дату, и время.

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

Необходимо заметить, что все базовые типы данных могут иметь варианты различного по диапазону представления данных. Приведем пример: вариантами четырехбайтового типа данных integer могут быть восьмибайтовые (bigint) и двухбайтовые (smallint) типы данных.

Поговорим отдельно о базовом типе данных GUID. Этот тип предназначен для хранения шестнадцатибайтовых значений так называемого глобального уникального идентификатора. Все различные значения этого идентификатора генерируются автоматически при вызове специальной встроенной функции NewId (). Это обозначение происходит от полного английского словосочетания New Identification, что в переводе буквально и означает «новое значение идентификатора». Каждое генерируемое на конкретном компьютере значение идентификатора уникально в пределах всех производимых компьютеров.

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

Такие GUID-идентификаторы могут быть использованы и разработчиками баз данных наравне с другими базовыми типами.

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

Для обозначения данных этого типа используется специальное ключевое слово Counter (x, ∆x), что в буквальном переводе с английского и означает «счетчик». Параметр x задает начальное значение, а x – шаг приращения.

Значения этого типа Counter обязательно являются целочисленными.

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

Значения данных типа счетчик генерируются автоматически при вставки строк. Причем эта генерация проводится без повторений, так что счетчик всегда будет уникально идентифицировать каждую строку. Но это создает некоторые неудобства при работе с таблицами, содержащими данные типа счетчик. Если, например, данные в отношении, заданном таблицей, изменятся и их придется удалить или поменять местами, значения счетчика легко могут «спутать карты», особенно если работает неопытный программист. Приведем пример, иллюстрирующий подобную ситуацию. Пусть дана следующая таблица, представляющая какое-то отношение, в которую введены четыре строки:

Счетчик каждой новой строке автоматически дал уникальное имя.

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

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

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

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

1 год = 365 дней * 24 ч * 60 с * 60 с < 366 дней * 24 ч * 60 с * 60 с < 225 с.

1 секунда > 2-25 год.

24*8 значений / 1 значение/секунду = 232 с > 27 год > 100 лет.


    Ваша оценка произведения:

Популярные книги за неделю