Л е к ц и я №07. Основы SQL.

advertisement
Л е к ц и я №07. Базы данных.
Основы SQL.
1.
Объявление домена BOOLEAN ............................................................................................................... 1
2.
Соединения и теоретико-множественные операции над отношениями .............................................. 2
2.1. Операция выборки ..................................................................................................................................... 2
2.2. Операция проекции ................................................................................................................................... 3
2.3. Декартово произведение .......................................................................................................................... 3
2.4. Операция соединения по двум отношениям (таблицам) ....................................................................... 4
2.4.1. Операция тета-соединения .................................................................................................................. 5
2.4.2. Естественное соединение .................................................................................................................... 5
2.4.3. Левое внешнее соединение .................................................................................................................. 7
2.4.4. Полусоединение .................................................................................................................................... 8
2.5. Операция объединения ............................................................................................................................ 8
2.6. Операция пересечения ............................................................................................................................. 9
2.7. Операция разности .................................................................................................................................... 9
2.8. Операция деления отношений ............................................................................................................... 10
3.
Построение вычисляемых полей ........................................................................................................... 12
СЛАЙД №2
1. Объявление домена BOOLEAN
Firebird не поддерживает тип данных BOOLEAN. Домены в стиле BOOLEAN являются идеалом,
потому что вы можете объявлять атрибуты, которые будут постоянными для всех таблиц. Рекомендуется использование минимальных типов данных: CHAR для переключателя
T[rue]/F[aise] или Y[es]/N[о] или SMALLINT для пары 1/0. Следующие примеры предлагают способы, которыми вы можете реализовать ваши типы BOOLEAN.
Пример 13.1. Двухфазный переключатель со значением по умолчанию 'F' (False)
CREATE DOMAIN D_BOOLEAN AS CHAR
DEFAULT 'F' NOT NULL
CHECK (VALUE IN ('T', 'F'));
Пример 13.2. Трехфазный переключатель, допускающий значение UNKNOWN (т. е. NULL):
CREATE DOMAIN D_LOGICAL AS SMALLINT
CHECK (VALUE IS NULL OR VALUE IN (1,0));
Пример 13.3. Трехфазный переключатель, представляющий UNKNOWN как значение:
CREATE DOMAIN D_GENDER AS CHAR(4)
DEFAULT 'N/K' NOT NULL
CHECK (VALUE IN ('FEM', 'MASC', 'N/K'));
ВНИМАНИЕ! He используйте BOOLEAN, UNKNOWN, TRUE или FALSE в качестве имен для булевых доменов. В Firebird это зарезервированные слова. Истинно логические типы планируются в Firebird 2 и могут появиться в промежуточных релизах между 1.5 и 2.
СЛАЙД №3
2
2. Соединения и теоретико-множественные операции над отношениями
Рассмотрим основные операции над отношениями, которые могут представлять интерес с точки зрения извлечения данных из реляционных таблиц. Это объединение, пересечение, разность, расширенное декартово произведение отношений, а также специальные операции
над отношениями: выборка, проекция и соединение.
СЛАЙД №4
Для иллюстрации теоретико-множественных операций над отношениями введем абстрактные
отношения (таблицы) с некоторыми атрибутами (полями).
Скрипт
Результат выполнения скрипта
Отношение R
R.a1
CREATE TABLE R
(
a1 CHAR(1),
a2 INT, PRIMARY KEY(a1,a2)
)
R.a2
A
1
A
2
B
1
B
3
B
4
Отношение S
CREATE TABLE S
(
b1 INT PRIMARY KEY,
b2 CHAR(1)
)
S.b1
S.b2
1
h
2
g
3
h
Операции выборки и проекции являются унарными, поскольку они работают с одним отношением.
СЛАЙД №5
2.1. Операция выборки
Операция выборки – построение горизонтального подмножества, т.е. подмножества кортежей, обладающих заданными свойствами.
Операция выборки работает с одним отношением R и определяет результирующее отношение,
которое содержит только те кортежи (строки) отношения R, которые удовлетворяют заданному
условию F (предикату).
или
.
Пример 5.1. Операция выборки в SQL.
Выборка
записывается следующим образом:
Скрипт
Результат выполнения скрипта
3
Отношение R
SELECT a1, a2
FROM R
WHERE a2 = 1
R.a1
R.a2
A
1
B
1
СЛАЙД №6
2.2. Операция проекции
Операция проекции – построение вертикального подмножества отношения, т.е. подмножества
кортежей, получаемого выбором одних и исключением других атрибутов.
Операция проекции работает с одним отношением R и определяет новое отношение, которое
содержит вертикальное подмножество отношения R, создаваемое посредством извлечения
значений указанных атрибутов и исключения из результата строк-дубликатов.
Пример 5.2. Операция проекции в SQL.
Проекция
записывается следующим образом:
Скрипт
Результат выполнения скрипта
Отношение S
S.b2
SELECT DISTINCT b2
FROM S
h
g
СЛАЙД №7
2.3. Декартово произведение
К основным операциям над отношениями относится декартово произведение. Декартово произведение R x S двух отношений (двух таблиц) определяет новое отношение - результат конкатенации (т.е. сцепления) каждого кортежа (каждой записи) из отношения R с каждым кортежем (каждой записью) из отношения S.
Скрипт
Результат выполнения скрипта
RxS
R.a1 R.a2 S.b1 S.b2
SELECT R.a1, R.a2, S.b1, S.b2
FROM R, S
RxS={(a, 1, 1, h), (a, 2, 1, h),
(b, 1, 1, h), ... }
a
1
1
h
a
1
2
g
a
1
3
h
a
2
1
h
a
2
2
g
a
2
3
h
b
1
1
h
4
b
1
2
g
b
1
3
h
b
3
1
h
b
3
2
g
b
3
3
h
b
4
1
h
b
4
2
g
b
4
3
h
Если одно отношение имеет N записей и K полей, а другое M записей и L полей, то отношение
с их декартовым произведением будет содержать NxM записей и K+L полей. Исходные отношения могут содержать поля с одинаковыми именами, тогда имена полей будут содержать
названия таблиц в виде префиксов для обеспечения уникальности имен полей в отношении,
полученном как результат выполнения декартова произведения.
Однако в таком виде (см. таблицу выше) отношение содержит больше информации, чем обычно необходимо пользователю. Как правило, пользователей интересует лишь некоторая часть
всех комбинаций записей в декартовом произведении, удовлетворяющая некоторому условию.
Поэтому вместо декартова произведения обычно используется одна из самых важных операций реляционной алгебры – операция соединения, которая является производной от операции декартова произведения. С точки зрения эффективности реализации в реляционных СУБД
эта операция – одна из самых трудных и часто входит в число основных причин, вызывающих
свойственные всем реляционным системам проблемы с производительностью.
СЛАЙД №8
2.4. Операция соединения по двум отношениям (таблицам)
Соединение – это процесс, когда две или более таблицы объединяются в одну. Способность
объединять информацию из нескольких таблиц или запросов в виде одного логического набора
данных обусловливает широкие возможности SQL.
В языке SQL для задания типа соединения таблиц в логический набор записей, из которого будет выбираться необходимая информация, используется операция JOIN в предложении
FROM.
Формат операции:
FROM имя_таблицы_1 {INNER | LEFT | RIGHT}
JOIN имя_таблицы_2
ON условие_соединения
Существуют различные типы операций соединения:
 Тета-соединение (Theta Join)
;
 Соединение по эквивалентности (Equi Join) частный случай тета-соединения
 Естественное соединение (Natural Join)
 Внешнее соединение (Outer Join)
 Полусоединение (Semi Join)
;
,
.
СЛАЙД №9
;
;
5
2.4.1. Операция тета-соединения
Операция тета-соединения
определяет отношение, которое содержит кортежи из
декартова произведения отношений R и S, удовлетворяющие предикату F. Предикат F имеет
вид
<, <=, =, <>).
, где вместо
может быть указан один из операторов сравнения (>, >=,
Если предикат F содержит только оператор равенства (=), то соединение называется соединением по эквивалентности.
Операция тета-соединения в языке SQL называется INNER JOIN (внутреннее соединение) и
используется, когда нужно включить все строки из обеих таблиц, удовлетворяющие условию
объединения. Внутреннее соединение имеет место и тогда, когда в предложении WHERE
сравниваются значения полей из разных таблиц. В этом случае строится декартово произведение строк первой и второй таблиц, а из полученного набора данных отбираются записи, удовлетворяющие условиям объединения.
В условиях объединения могут участвовать поля, относящиеся к одному и тому же типу данных
и содержащие один и тот же вид данных, но они не обязательно должны иметь одинаковые
имена.
Блоки данных из двух таблиц объединяются, как только в указанных полях будут найдены совпадающие значения.
Если в предложении FROM перечислено несколько таблиц и при этом не употребляется спецификация JOIN, а для указания соответствия полей из таблиц используется условие в предложении WHERE, то некоторые реляционные СУБД (например, Access) оптимизируют выполнение запроса, интерпретируя его как соединение.
Если перечислять ряд таблиц или запросов и не указывать условия объединения, в качестве
исходной таблицы будет выбрано декартово (прямое) произведение всех таблиц.
Скрипт
Результат выполнения скрипта
SELECT R.a1, R.a2, S.b1, S.b2
FROM R, S
WHERE R.a2 = S.b1
R.a1
или
SELECT R.a1, R.a2, S.b1, S.b2
FROM R INNER JOIN S
ON R.a2 = S.b1
R.a2
S.b1
S.b2
a
1
1
h
a
2
2
g
b
3
3
h
b
1
1
h
СЛАЙД №10
2.4.2. Естественное соединение
Естественным соединением называется соединение по эквивалентности двух отношений R
и S, выполненное по всем общим атрибутам, из результатов которого исключается по одному
экземпляру каждого общего атрибута.
Степенью естественного соединения называется сумма степеней операндов-отношений R и S
за вычетом количества атрибутов.
Скрипт
Результат выполнения скрипта
6
SELECT R.a1, R.a2, S.b2
FROM R, S
WHERE R.a2 = S.b1
или
SELECT R.a1, S.b1, S.b2
FROM R INNER JOIN S
ON R.a2 = S.b1
R.a1
R.a2 или S.b1
S.b2
a
1
h
a
2
g
b
3
h
b
1
h
СЛАЙД №11
Пример 5.6. Вывести информацию о проданных товарах.
SELECT *
FROM Сделка, Товар
WHERE Сделка.КодТовара = Товар.КодТовара
Или (что эквивалентно)
SELECT *
FROM Товар INNER JOIN Сделка
ON Товар.КодТовара = Сделка.КодТовара
5.6. Выборка информации о проданных товарах.
Можно создать вложенные объединения, добавив третью таблицу к результату объединения
двух других таблиц.
Пример 5.7. Получить сведения о товарах, дате сделок, количестве проданного товара и покупателях.
SELECT Товар.Название, Сделка.Количество, Сделка.
Дата, Клиент.Фирма
FROM Клиент INNER JOIN
(Товар INNER JOIN Сделка
ON Товар.КодТовара = Сделка.КодТовара)
ON Клиент.КодКлиента = Сделка.КодКлиента
5.7. Выборка сведений о товарах, дате сделок, количестве проданного товара и покупателях.
Использование общих имен таблиц для идентификации столбцов неудобно из-за их громоздкости. Каждой таблице можно присвоить какое-нибудь краткое обозначение, псевдоним.
Пример 5.8. Получить сведения о товарах, дате сделок, количестве проданного товара и покупателях. В запросе используются псевдонимы таблиц.
SELECT Т.Название, С.Количество,
С.Дата, К.Фирма
FROM Клиент AS К INNER JOIN
(Товар AS Т INNER JOIN
Сделка AS С
ON Т.КодТовара = С.КодТовара)
ON К.КодКлиента = С.КодКлиента;
СЛАЙД №12
7
2.4.3. Внешнее соединение (Левое/Правое)
При соединении двух отношений часто возникает такая ситуация, что для кортежа одного отношения не находится соответствующий кортеж в другом отношении. Иначе говоря, в столбцах
соединения оказываются несовпадающие значения. Но иногда может потребоваться, чтобы
строка из одного отношения была представлена в результатах соединения, даже если в другом
отношении нет совпадающего значения. Эта цель может быть достигнута с помощью внешнего
соединения
.
Внешнее соединение похоже на внутреннее, но в результирующий набор данных включаются
также записи ведущей таблицы соединения, которые объединяются с пустым множеством записей другой таблицы. Для обозначения отсутствующих значений во втором отношении используется значение NULL.
Преимуществом внешнего соединения является сохранение исходных кортежей, которые были
бы исключены в результате выполнения при использовании других типов соединения.
Какая из таблиц будет ведущей, определяет вид соединения. LEFT – левое внешнее соединение, ведущей является таблица, расположенная слева от вида соединения; RIGHT – правое
внешнее соединение, ведущая таблица расположена справа от вида соединения.
Левым внешним соединением называется соединение, при котором кортежи отношения R,
не имеющие совпадающих значений в общих столбцах отношения S, также включаются в результирующее отношение.
Скрипт
Результат выполнения скрипта
R.a1 R.a2 S.b1 S.b2
SELECT R.a1, R.a2, S.b1, S.b2
FROM R LEFT OUTER JOIN S
ON R.a2 = S.b1
a
1
1
h
a
2
2
g
b
1
1
h
b
3
3
h
b
4
null
null
Существует и правое внешнее соединение
, называемое так потому, что в результирующем отношении содержатся все кортежи правого отношения.
Кроме того, имеется и полное внешнее соединение (FULL OUTER JOIN), в его результирующее отношение помещаются все кортежи из обоих отношений (как левой, так и правой таблицы), а для обозначения несовпадающих значений кортежей в нем используются определители
NULL.
Это отличительная черта полных внешних объединений, обе таблицы являются внешними, поэтому возвращаются строки и той, и другой таблицы. Именно поэтому полные внешние объединения непопулярны в веб-разработке, ведь случаи их использования достаточно редки.
Напротив, внутренние и левые внешние объединения применяются довольно часто.
SELECT R.a1, R.a2, S.b1, S.b2
FROM R RIGHT OUTER JOIN S
ON R.a2 = S.b1
Пример 5.11. Вывести информацию о всех товарах. Для проданных товаров будет указана дата сделки и количество. Для непроданных эти поля останутся пустыми.
8
SELECT Товар.*, Сделка.*
FROM Товар LEFT OUTER JOIN Сделка
ON Товар.КодТовара = Сделка.КодТовара;
СЛАЙД №13
2.4.4. Полусоединение
Операция полусоединения (Semi-Join) определяет отношение, содержащее те кортежи отношения R, которые входят в соединение отношений R и S.
Преимущество полусоединения заключается в том, что оно позволяет сократить количество
кортежей, которые нужно обработать для получения соединения. Это особенно полезно при
вычислении соединений в распределенных системах.
Основное преимущество полусоединений в распределенной системе – это сокращение размеров операндов, участвующих в соединениях, и, следовательно, коммуникационных затрат.
Однако в более современных методах, учитывающих, наряду с коммуникационным расходами,
также и затраты на локальную обработку, полусоединения не используются, поскольку они
приводят к увеличению объема локальной обработки.
Скрипт
Результат выполнения скрипта
SELECT R.a1, R.a2
FROM R, S
WHERE R.a2 = S.b1
R.a1
или
SELECT R.a1,
R.a2
FROM R INNER JOIN S
ON R.a2 = S.b1
R.a2
a
1
a
2
b
3
b
1
СЛАЙД №14
2.5. Операция объединения
Объединение двух отношений R и S определяет новое отношение, которое включает все кортежи, содержащиеся только в R, только в S, одновременно в R и S, причем все дубликаты кортежей исключены. При этом отношения R и S должны быть совместимыми по объединению.
Объединением двух таблиц R и S является таблица, содержащая все строки, которые имеются в первой
таблице R, во второй таблице S или в обеих таблицах сразу.
Если R и S включают, соответственно, I и J кортежей, то объединение этих отношений можно
получить, собрав все кортежи в одно отношение, которое может содержать не более (I + J) кортежей. Объединение возможно, только если схемы двух отношений совпадают, т.е. состоят из
одинакового количества атрибутов, причем каждая пара соответствующих атрибутов имеет
одинаковый домен.
Отметим, что в определении совместимости по объединению не указано, что атрибуты должны
иметь одинаковые имена. В некоторых случаях для получения двух совместимых по объединению отношений может быть использована операция проекции.
Объединение (UNION)
отношений R и S можно получить в результате их конкатенации
с образованием одного отношения с исключением кортежей-дубликатов. При этом отношения
R и S должны быть совместимы, т.е. иметь одинаковое количество полей с совпадающими типами данных. Иначе говоря, отношения должны быть совместимы по объединению.
9
Когда два (или более) запроса подвергаются объединению, их столбцы вывода должны быть
совместимы для объединения. Это означает, что каждый запрос должен указывать одинаковое число столбцов и в том же порядке что и первый, второй, третий, и так далее, и каждый
должен иметь тип, совместимый с каждым.
Скрипт
Результат выполнения скрипта
R.a1 R.a2
SELECT R.a1, R.a2
FROM R
UNION
SELECT S.b2, S.b1
FROM S
a
1
a
2
b
3
b
1
b
4
g
2
h
1
h
3
СЛАЙД №15
2.6. Операция пересечения
Операция пересечения (INTERSECT)
определяет отношение, которое
содержит кортежи, присутствующие как в отношении R, так и в отношении S. Отношения R
и S должны быть совместимы по объединению.
Пересечением двух таблиц R и S является таблица, содержащая все строки, присутствующие
в обеих исходных таблицах одновременно.
Результат выполнения
скрипта
Скрипт
SELECT R.a1, R.a2
FROM R, S
WHERE R.a1 = S.b2 AND R.a2 = S.b1
R.a1
или
SELECT
FROM
WHERE
AND
R.a2
R.a1, R.a2
R
R.a1 IN (SELECT S.b2 FROM S WHERE S.b2 = R.a1)
R.a2 IN (SELECT S.b1 FROM S WHERE S.b1 = R.a2)
СЛАЙД №16
2.7. Операция разности
Разность (EXCEPT) R-S двух отношений R и S состоит из кортежей, которые имеются в отношении R, но отсутствуют в отношении S. Причем отношения R и S должны быть совместимы по
объединению.
Разностью двух таблиц R и S является таблица, содержащая все строки, которые присутствуют
в таблице R, но отсутствуют в таблице S.
Скрипт
SELECT R.a1, R.a2
FROM R
Результат выполнения скрипта
R.a1
R.a2
10
WHERE NOT EXISTS
(SELECT S.b1, S.b2
FROM S
WHERE S.b1 = R.a2 AND S.b2 = R.a1)
a
1
a
2
b
1
b
3
b
4
СЛАЙД №17
2.8. Операция деления отношений
Результат операции деления R:S – набор кортежей отношения R, определенных на множестве
атрибутов C, которые соответствуют комбинации всех кортежей отношения S .
T1 = ПC(R);
T2 = ПC((SxT1) - R);
T = T1 - T2.
Операция деления может применяться в случае запросов особого типа, которые довольно часто встречаются в приложениях баз данных. Предположим, что отношение R определено на
множестве атрибутов А, а отношение S – на множестве атрибутов В, причем В ∈ А (т.е. В является подмножеством А). Пусть С = А – В, т.е. С является множеством атрибутов отношения R,
которые не являются атрибутами отношения S. Тогда определение операции деления будет
выглядеть следующим образом.
.
Результатом операции деления является набор кортежей отношения R, определенных на множестве атрибутов C, которые соответствуют комбинации всех кортежей отношения S.
Отношение R определено
атрибутов B, причем и C = A – B.
на множестве атрибутов A, а отношение S - на множестве
Пример. Деление отношений в SQL. Пусть
 A = {имя, пол, рост, возраст, вес};
 B = {имя, пол, возраст};
 C = А – В = {рост, вес}.
Скрипт
CREATE TABLE R
(i
int primary key,
имя
varchar(3),
пол
varchar(3),
рост
int,
возраст int,
вес
int)
Результат выполнения скрипта
Создание отношения R (СЛАЙД №18)
Отношение R
имя
пол
рост
возраст
вес
a
ж
160
20
60
b
м
180
30
70
c
ж
150
16
40
Создание отношения S (СЛАЙД №19)
CREATE TABLE S
(i
int primary key,
имя
varchar(3),
пол
varchar(3),
возраст int)
Отношение S
имя
пол
возраст
a
ж
20
Создание отношения T1 (СЛАЙД №20)
T1=ПC(R)
11
CREATE VIEW T1 AS
SELECT рост, вес
FROM R
рост
вес
160
60
180
70
150
40
Создание отношения TT (СЛАЙД №21)
CREATE VIEW TT AS
SELECT S.имя, S.пол, S.возраст,
T1.рост, T1.вес
FROM S, T1
TT=(SхT1) – R
имя
пол
возраст
рост
вес
a
ж
20
180
70
a
ж
20
150
40
Создание отношения T2 (СЛАЙД №22)
CREATE VIEW T2 AS
SELECT TT.рост, TT.вес
FROM TT
WHERE NOT EXISTS
(SELECT R.рост, R.вес
FROM R
WHERE TT.имя=R.имя AND
TT.пол=R.пол
AND TT.возраст=R.возраст
AND TT.рост=R.рост
AND TT.вес=R.вес)
T2=ПC((SхT1) – R)
рост
вес
180
70
150
40
Создание отношения T (СЛАЙД №23)
SELECT T1.рост, T1.вес
FROM T1
WHERE NOT EXISTS
(SELECT T2.рост, T2.вес
FROM T2
WHERE T1.рост=T2.рост
AND T1.вес=T2.вес)
T=T1 – T2
рост
вес
160
60
СЛАЙД №24
2.9. Краткий перечень операций реляционной алгебры
Операция
Выборка
Проекция
Объединение
Разность
Пересечение
Декартово произведение
Обозначение
Область применения
Определяет результирующее отношение, которое содержит только те
кортежи (строки) из отношения R, которые удовлетворяют заданному
условию (предикату)
Определяет новое отношение, содержащее вертикальное подмножество отношения R, создаваемое посредством извлечения значений указанных атрибутов и исключения из результата строк-дубликатов
Определяет новое отношение, которое включает все кортежи, содержащиеся только в R, только в S, одновременно в R и S, причем все
дубликаты кортежей исключены. При этом отношения R и S должны
быть совместимыми по объединению
Разность двух отношений R и s состоит из кортежей, которые имеются
в отношении R. но отсутствуют в отношении S. Причем отношения R и s
должны быть совместимыми по объединению
Определяет отношение, которое содержит кортежи, присутствующие
как в отношении R, так и в отношении S. Отношения R и S должны быть
совместимыми по объединению
Определяет новое отношение, которое является результатом конкатенации (т.е. сцепления) каждого кортежа из отношения R с каждым кор-
12
Тетаcоединение
Соединение по
эквивалентности
Естественное
соединение
(Левое) внешнее соединение
Полусоединение
Деление
тежем из отношения S
Определяет отношение, которое содержит кортежи из декартова произведения отношений R и S, удовлетворяющие предикату F
Определяет отношение, которое содержит кортежи из декартова произведения отношений R и S, удовлетворяющие предикату F (предикат
должен предусматривать только сравнение на равенство)
Естественным соединением называется соединение по эквивалентности двух отношений R и S, выполненное по всем общим атрибутам х, из
результатов которого исключается по одному экземпляру каждого общего атрибута
Соединение, при котором кортежи отношения R, не имеющие совпадающих значений в общих столбцах отношения S, также включаются в
результирующее отношение
Определяет отношение, содержащее те кортежи отношения R, которые
входят в соединение отношений R и S
Определяет отношение, состоящее из множества кортежей отношения
R, которые определены на атрибуте С, соответствующем комбинации
всех кортежей отношения S, где C — множество атрибутов, имеющихся
в отношении R, но отсутствующих в отношении S
3. Построение вычисляемых полей
В общем случае для создания вычисляемого (производного) поля в списке SELECT следует
указать некоторое выражение языка SQL. В этих выражениях применяются арифметические
операции сложения, вычитания, умножения и деления, а также встроенные функции языка
SQL. Можно указать имя любого столбца (поля) таблицы или запроса, но использовать имя
столбца только той таблицы или запроса, которые указаны в списке предложения FROM соответствующей инструкции. При построении сложных выражений могут понадобиться скобки.
Стандарты SQL позволяют явным образом задавать имена столбцов результирующей таблицы, для чего применяется фраза AS.
Пример 6.1. Рассчитать общую стоимость для каждой сделки. Этот запрос использует расчет
результирующих столбцов на основе арифметических выражений.
SELECT Товар.Название, Товар.Цена,
Сделка.Количество,
Товар.Цена*Сделка.Количество AS Стоимость
FROM Товар INNER JOIN Сделка
ON Товар.КодТовара=Сделка.КодТовара
6.1. Расчет общей стоимости для каждой сделки.
Пример 6.2. Получить список фирм с указанием фамилии и инициалов клиентов.
SELECT Фирма, Фамилия + " " +
Left(Имя,1) + "." + Left(Отчество,1) + "." AS ФИО
FROM Клиент
6.2. Получение списка фирм с указанием фамилии и инициалов клиентов.
В запросе использована встроенная функция Left, позволяющая вырезать в текстовой переменной один символ слева в данном случае.
Пример 6.3. Получить список товаров с указанием года и месяца продажи.
SELECT Товар.Название, Year(Сделка.Дата) AS Год,
13
Month(Сделка.Дата) AS Месяц
FROM Товар INNER JOIN Сделка
ON Товар.КодТовара=Сделка.КодТовара
6.3. Получение списка товаров с указанием года и месяца продажи.
В запросе использованы встроенные функции Year и Month для выделения года и месяца из
даты.
Использование итоговых функций
С помощью итоговых (агрегатных) функций в рамках SQL-запроса можно получить ряд обобщающих статистических сведений о множестве отобранных значений выходного набора.
Пользователю доступны следующие основные итоговые функции:
 Count (Выражение) - определяет количество записей в выходном наборе SQL-запроса;
 Min/Max (Выражение) - определяют наименьшее и наибольшее из множества значений в
некотором поле запроса;
 Avg (Выражение) - эта функция позволяет рассчитать среднее значение множества значе-
ний, хранящихся в определенном поле отобранных запросом записей. Оно является арифметическим средним значением, т.е. суммой значений, деленной на их количество.
 Sum (Выражение) - вычисляет сумму множества значений, содержащихся в определенном
поле отобранных запросом записей.
Чаще всего в качестве выражения выступают имена столбцов. Выражение может вычисляться
и по значениям нескольких таблиц.
Все эти функции оперируют со значениями в единственном столбце таблицы или с арифметическим выражением и возвращают единственное значение. Функции COUNT, MIN и MAX применимы как к числовым, так и к нечисловым полям, тогда как функции SUM и AVG могут использоваться только в случае числовых полей, за исключением COUNT(*). При вычислении результатов любых функций сначала исключаются все пустые значения, после чего требуемая
операция применяется только к оставшимся конкретным значениям столбца. Вариант
COUNT(*) - особый случай использования функции COUNT, его назначение состоит в подсчете
всех строк в результирующей таблице, независимо от того, содержатся там пустые, дублирующиеся или любые другие значения.
Если до применения обобщающей функции необходимо исключить дублирующиеся значения,
следует перед именем столбца в определении функции поместить ключевое слово DISTINCT.
Оно не имеет смысла для функций MIN и MAX, однако его использование может повлиять на
результаты выполнения функций SUM и AVG, поэтому необходимо заранее обдумать, должно
ли оно присутствовать в каждом конкретном случае. Кроме того, ключевое слово DISTINCT
может быть указано в любом запросе не более одного раза.
Очень важно отметить, что итоговые функции могут использоваться только в списке предложения SELECT и в составе предложения HAVING. Во всех других случаях это недопустимо. Если
список в предложении SELECT содержит итоговые функции, а в тексте запроса отсутствует
фраза GROUP BY, обеспечивающая объединение данных в группы, то ни один из элементов
списка предложения SELECT не может включать каких-либо ссылок на поля, за исключением
ситуации, когда поля выступают в качестве аргументов итоговых функций.
Пример 6.4. Определить первое по алфавиту название товара.
SELECT Min(Товар.Название) AS Min_Название
FROM Товар
14
6.4. Определение первого по алфавиту названия товара.
Пример 6.5. Определить количество сделок.
SELECT Count(*) AS Количество_сделок
FROM Сделка
6.5. Определить количество сделок.
Пример 6.6. Определить суммарное количество проданного товара.
SELECT Sum(Сделка.Количество) AS Количество_товара
FROM Сделка
6.6. Определение суммарного количества проданного товара.
Пример 6.7. Определить среднюю цену проданного товара.
SELECT Avg(Товар.Цена) AS Avg_Цена
FROM Товар INNER JOIN Сделка
ON Товар.КодТовара=Сделка.КодТовара;
6.7. Определение средней цены проданного товара.
Пример 6.8. Подсчитать общую стоимость проданных товаров.
SELECT Sum(Товар.Цена*Сделка.Количество) AS Стоимость
FROM Товар INNER JOIN Сделка
ON Товар.КодТовара=Сделка.КодТовара
6.8. Подсчет общей стоимости проданных товаров.
Предложение GROUP BY
Часто в запросах требуется формировать промежуточные итоги, что обычно отображается появлением в запросе фразы "для каждого...". Для этой цели в операторе SELECT используется
предложение GROUP BY. Запрос, в котором присутствует GROUP BY, называется группирующим запросом, поскольку в нем группируются данные, полученные в результате выполнения
операции SELECT, после чего для каждой отдельной группы создается единственная суммарная строка. Стандарт SQL требует, чтобы предложение SELECT и фраза GROUP BY были тесно связаны между собой. При наличии в операторе SELECT фразы GROUP BY каждый элемент списка в предложении SELECT должен иметь единственное значение для всей группы.
Более того, предложение SELECT может включать только следующие типы элементов: имена
полей, итоговые функции, константы и выражения, включающие комбинации перечисленных
выше элементов.
Все имена полей, приведенные в списке предложения SELECT, должны присутствовать и во
фразе GROUP BY - за исключением случаев, когда имя столбца используется в итоговой
функции. Обратное правило не является справедливым - во фразе GROUP BY могут быть
имена столбцов, отсутствующие в списке предложения SELECT.
Если совместно с GROUP BY используется предложение WHERE, то оно обрабатывается первым, а группированию подвергаются только те строки, которые удовлетворяют условию поиска.
Стандартом SQL определено, что при проведении группирования все отсутствующие значения
рассматриваются как равные. Если две строки таблицы в одном и том же группируемом столб-
15
це содержат значение NULL и идентичные значения во всех остальных непустых группируемых
столбцах, они помещаются в одну и ту же группу.
Пример 6.9. Вычислить средний объем покупок, совершенных каждым покупателем.
SELECT Клиент.Фамилия, Avg(Сделка.Количество)
AS Среднее_количество
FROM Клиент INNER JOIN Сделка
ON Клиент.КодКлиента=Сделка.КодКлиента
GROUP BY Клиент.Фамилия
6.9. Вычисление среднего объема покупок, совершенных каждым покупателем.
Фраза "каждым покупателем" нашла свое отражение в SQL-запросе в виде предложения
GROUP BY Клиент.Фамилия.
Пример 6.10. Определить, на какую сумму был продан товар каждого наименования.
SELECT Товар.Название,
Sum(Товар.Цена*Сделка.Количество)
AS Стоимость
FROM Товар INNER JOIN Сделка
ON Товар.КодТовара=Сделка.КодТовара
GROUP BY Товар.Название
6.10. Определение, на какую сумму был продан товар каждого наименования.
Пример 6.11. Подсчитать количество сделок, осуществленных каждой фирмой.
SELECT Клиент.Фирма, Count(Сделка.КодСделки)
AS Количество_сделок
FROM Клиент INNER JOIN Сделка
ON Клиент.КодКлиента=Сделка.КодКлиента
GROUP BY Клиент.Фирма
6.11. Подсчет количества сделок, осуществленных каждой фирмой.
Пример 6.12. Подсчитать общее количество купленного для каждой фирмы товара и его стоимость.
SELECT Клиент.Фирма, Sum(Сделка.Количество)
AS Общее_Количество,
Sum(Товар.Цена*Сделка.Количество)
AS Стоимость
FROM Товар INNER JOIN
(Клиент INNER JOIN Сделка
ON Клиент.КодКлиента=Сделка.КодКлиента)
ON Товар.КодТовара=Сделка.КодТовара
GROUP BY Клиент.Фирма
6.12. Подсчет общего количества купленного для каждой фирмы товара и его стоимости.
Пример 6.13. Определить суммарную стоимость каждого товара за каждый месяц.
SELECT Товар.Название, Month(Сделка.Дата)
AS Месяц,
Sum(Товар.Цена*Сделка.Количество)
AS Стоимость
FROM Товар INNER JOIN Сделка
16
ON Товар.КодТовара=Сделка.КодТовара
GROUP BY Товар.Название, Month(Сделка.Дата)
6.13. Определение суммарной стоимости каждого товара за каждый месяц.
Пример 6.14. Определить суммарную стоимость каждого товара первого сорта за каждый месяц.
SELECT Товар.Название, Month(Сделка.Дата)
AS Месяц,
Sum(Товар.Цена*Сделка.Количество)
AS Стоимость
FROM Товар INNER JOIN Сделка
ON Товар.КодТовара=Сделка.КодТовара
WHERE Товар.Сорт="Первый"
GROUP BY Товар.Название, Month(Сделка.Дата)
6.14. Определение суммарной стоимости каждого товара первого сорта за каждый месяц.
Предложение HAVING
При помощи HAVING отражаются все предварительно сгруппированные посредством GROUP
BY блоки данных, удовлетворяющие заданным в HAVING условиям. Это дополнительная возможность "профильтровать" выходной набор.
Условия в HAVING отличаются от условий в WHERE:
 HAVING исключает из результирующего набора данных группы с результатами агрегиро-
ванных значений;
 WHERE исключает из расчета агрегатных значений по группировке записи, не удовлетворя-
ющие условию;
 в условии поиска WHERE нельзя задавать агрегатные функции.
Пример 6.15. Определить фирмы, у которых общее количество сделок превысило три.
SELECT Клиент.Фирма, Count(Сделка.Количество)
AS Количество_сделок
FROM Клиент INNER JOIN Сделка
ON Клиент.КодКлиента=Сделка.КодКлиента
GROUP BY Клиент.Фирма
HAVING Count(Сделка.Количество)>3
6.15. Определение фирм, у которых общее количество сделок превысило три.
Пример 6.16. Вывести список товаров, проданных на сумму более 10000 руб.
SELECT Товар.Название,
Sum(Товар.Цена*Сделка.Количество)
AS Стоимость
FROM Товар INNER JOIN Сделка
ON Товар.КодТовара=Сделка.КодТовара
GROUP BY Товар.Название
HAVING Sum(Товар.Цена*Сделка.Количество)>10000
6.16. Вывод списка товаров, проданных на сумму более 10000 руб.
Пример 6.17. Вывести список товаров, проданных на сумму более 10000 без указания суммы.
17
SELECT Товар.Название
FROM Товар INNER JOIN Сделка
ON Товар.КодТовара=Сделка.КодТовара
GROUP BY Товар.Название
HAVING Sum(Товар.Цена*Сделка.Количество)>10000
6.17. Вывод списка товаров, проданных на сумму более 10000 без указания суммы.
18
ЧАСТЬ IV. База данных и ее объекты.
ГЛАВА 14. Чертежная доска для базы данных.
Конечно же, база данных хранит данные. Однако данные сами по себе не могут использоваться,
если они не были сохранены в соответствии с некоторыми правилами, которые, во-первых,
определяют их смысл и значение и, во-вторых, позволяют их отыскивать соответствующим образом. База данных, существующая в контексте системы управления базами данных (СУБД),
такой как Firebird, включает в себя множество "вещей" помимо данных.
Firebird является реляционной системой управления базами данных. По существу она разработана для создания и поддержания абстрактных структур данных не только для хранения данных, но также для поддержки отношений, оптимизации скорости и обеспечения целостности, в
соответствии с которой запрашиваемые данные могут быть возвращены клиентским приложениям.
Пользователь SYSDBA и пароль
Во всех версиях Firebird, включая 1.5, пользователь SYSDBA имеет полные права ко всем базам
данных на сервере. Инсталляционные скрипты устанавливают базу данных безопасности с паролем по умолчанию masterkey.
Некоторые релизы 1.5 для Linux запускают скрипт, который генерирует новый пароль для
пользователя SYSDBA. Вы можете посмотреть сгенерированный пароль в файле
SYSDBA.password в корневом каталоге Firebird.
!!!
ВНИМАНИЕ! Пароль masterkey широко известен. Убедитесь, что вы изменили его на малопонятную восьмисимвольную строку. См. инструкции в главе 34.
.!.
Метаданные
Все вместе объекты, определенные в базе данных, называются метаданными или, более традиционно, ее схемой. Процесс создания и модификации метаданных называется определением
данных. Термин "определение данных" также часто применяется к описанию одного объекта и
его атрибутов.
19
В этом разделе в деталях рассматриваются концепции, терминология и язык определения данных.
Язык определения данных
Основные структуры базы данных - ее таблицы, просмотры и индексы - создаются с использованием подмножества языка SQL Firebird, известного как язык определения данных (Data
Definition Language, DDL). Оператор DDL начинается с одного из ключевых слов CREATE,
ALTER, RECREATE или DROP, которые означают создание, изменение, пересоздание или удаление одного объекта, соответственно. База данных, ее объекты, правила и отношения объединяются для формирования структуры реляционной базы данных.
Системные таблицы
Firebird хранит метаданные в множестве таблиц, которые он создает прямо в базе данных, - в
системных таблицах. Идентификаторы всех системных таблиц начинаются с символов "RDB$".
Например, таблица, которая хранит определения и другую информацию о структурах всех таблиц в вашей базе данных, называется RDB$RELATIONS. Связанная с ней таблица
RDB$RELATION_FIELDS хранит информацию и описания всех столбцов в каждой таблице.
Такая "база данных в базе данных" является высоко нормализованной. Операторы DDL разработаны для выполнения безопасных операций с таблицами метаданных и в полном соответствии с каскадными эффектами.
Возможно изменение данных в системных таблицах посредством обычных операций SQL. Некоторые инструменты администратора, такие как isql и gfix, выполняют внутренние изменения
данных в системных таблицах. При этом, будучи сложной системой управления базами данных,
Firebird не была разработана в предположении, что конечный пользователь будет манипулировать строками системных таблиц.
!!!
ВНИМАНИЕ! Не рекомендуется пренебрегать операторами DDL и самостоятельно изменять
системные таблицы с помощью кода приложений или через интерактивные инструменты. Системные таблицы являются "мета-метаданными" любой базы данных. Любое вмешательство
человека, скорее всего, приведет к непредсказуемым повреждениям.
.!.
Запросы SELECT к системным таблицам являются замечательным средством и могут быть
очень полезными для отображения таких вещей, как наборы символов, зависимости и т.д. Полное описание системных таблиц см. в приложении 9.
20
Проектирование базы данных
Хотя реляционные базы данных являются очень гибкими, существует только один способ обеспечения целостности данных и удовлетворительной производительности базы данных - основательное проектирование базы данных. Не существует никакой встроенной защиты от скверных
проектных решений.
Хорошее проектирование базы данных имеет несколько преимуществ.
* Удовлетворяет требованиям пользователей к содержимому базы данных. Прежде чем вы
сможете начать проектирование базы данных, вы должны провести обширные исследования
требований пользователей к базе данных, а также выяснить, как база данных будет использоваться. Наиболее гибкие проекты баз данных на сегодняшний день создаются во время хорошо
управляемого процесса анализа, создания прототипа и тестирования; в этот процесс вовлекаются все люди, которые будут использовать базу данных.
* Обеспечивает полноту и целостность данных. При проектировании таблицы вы определяете
некоторые атрибуты и ограничения, фильтрующие данные, которые пользователь или приложение могут вводить в таблицу и ее столбцы. Выполняя проверку данных до их помещения в
таблицу, база данных реализует правила модели данных и обеспечивает целостность данных.
* Предоставляет естественную, простую в понимании структуру информации. Хорошее проектирование делает запросы более понятными - мала вероятность того, что пользователи привнесут несогласованность в данные или что им потребуется вводить избыточные данные.
* Удовлетворяет требованиям пользователей к производительности. Хорошее проектирование
базы данных обеспечивает лучшую производительность. Если таблицы будут слишком большими или будет слишком много (или слишком мало) индексов, результатом станет долгое ожидание. Если база данных является слишком большой с высоким объемом транзакций, проблемы
производительности, как результат плохого проектирования, будут увеличиваться.
* Изолирует систему от ошибок проектирования в последующих циклах разработки.
Описание и анализ
База данных абстрактно представляет совокупность организации, отношений, правил и процессов. Прежде чем подойти к началу проектирования структур и правил базы данных, аналитик/дизайнер должен многое сделать, работая с людьми, вовлеченными в определение структур, правил и требований реальной жизни, из которых будет создан проект базы данных. Следует особенно подчеркнуть важность скрупулезного описания и анализа.
Анализ логических данных является итеративным процессом детализации и поиска сути во
множестве входных данных, задач и выходных данных, которые должны быть реализованы в
базе данных. Большие неупорядоченные структуры информации постепенно сокращаются до
меньших, более специализированных объектов данных и понемногу начинают отображать модель данных.
Важной частью такого процесса редуцирования является нормализация - разделение групп элементов данных с целью установления основных отношений, уменьшения избыточности и объединения связанных элементов данных в структуры, которыми можно эффективно манипулировать.
21
Эта фаза может быть одной из наиболее сложных задач для проектировщика базы данных, особенно в окружении, где> бизнес был приспособлен к работе с электронными таблицами и
настольными базами данных. Прискорбно, что даже в среде клиент-сервер можно найти слишком много медленно работающих, подверженных разрушению баз данных, которые были
"спроектированы" с использованием отчетов и электронных таблиц в качестве своей основы[32].
Модель данных <> база данных
Тот "мир", который был получен в процессе описания и анализа, является черновиком для
структур ваших данных. Считается, что логическая модель должна описывать отношения и
наборы. Обычная ошибка (и западня, присущая всем инструментам CASE) слепо транслировать
модель данных в схему базы данных. В сложных системах управления базами данных, таких
как Firebird, структура таблицы не всегда представляет оптимальный объект, из которого должны отыскиваться данные. Запросы, просмотры, массивы, вычисляемые столбцы и хранимые
процедуры выбора являются лишь небольшой частью доступных механизмов поиска и хранения, которые будут влиять на вашу реализацию модели при физическом проектировании.
Даже прекрасная модель данных будет иметь недостатки в гибкости и экономичности, если она
не принимает в расчет производительность и экономичность динамических характеристик сервера. Динамические структуры для выборки и манипулирования данными являются артериями
баз данных клиент-сервер.
Одна база данных или много?
Один сервер Firebird- за исключением локального встроенного сервера под Windows - может
управлять множеством баз данных через свою собственную физическую файловую систему.
Для больших предприятий не является необычным использование нескольких баз данных для
обслуживания отдельных подсистем подразделений. Поскольку одной базе данных ничего не
известно об объектах и зависимостях в другой, требуется аккуратное проектирование, планирование и балансировка системных ресурсов и сетевых сервисов для интеграции таких независимых систем. Обычно подобные базы данных периодически синхронизируются с помощью системы репликации.
При проектировании принимайте во внимание, что Firebird не поддерживает запросы, соединяющие или объединяющие таблицы из различных баз данных. При этом он поддерживает одновременные запросы к множеству баз данных в контексте одной транзакции и при двухфазном
ее подтверждении. Таким образом, приложения могут выполнять задачи, которые работают с
образами данных из двух и более баз данных и выполняют операторы DML к одной базе данных, используя данные, прочитанные из другой. Подробности о транзакциях с несколькими базами данных и о двухфазном подтверждении см. в главе 27.
Download