Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Кудравцев Создание баз данных 2010

.pdf
Скачиваний:
83
Добавлен:
16.08.2013
Размер:
2.65 Mб
Скачать

SELECT * INTO item_row

FROM item

WHERE item_id = stock_row.item_id ;

msg=''order more'' || item_row.description || ''s at '' || to_char(item_row.cost_price, ''99.99'') ;

INSERT INTO reorders VALUES(stock_row.item_id, msg);

end ; end loop ;

RETURN reorder_count ; END ;

'

LANGUAGE 'plpgsql' ;

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

Триггеры

Триггер представляет собой механизм запуска хранимой процедуры в случае наступления какого либо события, а именно: применения к таблице операторов INSERT, DELETE, UPDATE.

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

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

1)не имеет параметров, причем аргументы триггерной функции передаются в массиве с именем tg_argv, начиная с tg_argv[0];

2)имеет специальный тип возврата OPAQUE.

Триггерная процедура будет вызвана, когда над заданной таблицей будут проводиться изменения. Она должна вернуть или NULL, или строку, соответствующую структуре таблицы, для которой была вызвана триггерная процедура. Для триггеров AFTER, вызываемых после UPDATE, обычно возвращается NULL. Для триггеров BEFORE возвращаемый результат используется для

121

управления обновлением данных. Если возвращается NULL, то UPDATE не выполняется, если же возвращается строка, то именно она выступает как источник обновления.

Триггеры создаются командой CREATE TRIGGER, в которой указывается, для какой таблицы, какого события, до или после этого события будет вызываться триггерная процедура. Рассмотрим пример триггерной процедуры, которая будет вызываться всякий раз после выполнения SQL операторов INSERT или UPDATE над таблицей stock (склад).

Триггерная процедура

CREATE FUNCTION reorder_trigger() RETURNS OPAQUE AS '

DECLARE mq integer ;

item_record record ;

BEGIN mq:=tg_argv[0];

raise notice ''in trigger, mq is %'', mq ; if new.quantity <= mq

then

SELECT * INTO item_record

FROM item WHERE item_id <= new.item_id ;

INSERT INTO reorders

VALUES(new.item_id, item_record.description);

end if;

RETURN NULL ; END ;

'

LANGUAGE 'plpgsql' ;

Создание триггера

CREATE TRIGGER trig_reorder AFTER INSERT OR UPDATE ON stock

FOR EACH ROW EXECUTE PROCEDURE reorder_trigger(3) ;

122

Триггер будет вызываться всякий раз после выполнения команд INSERT или UPDATE по изменению содержимого таблицей stock (склад), т.е. после изменения товаров на складе. Если остаток товара окажется меньше заданного количества (меньше 3), то будет добавлена запись в таблицу reorders, т.е. будет формироваться таблица заказов на товары, оставшиеся в малом количестве.

Контрольные вопросы

1.Какова структура хранения данных в форматах MyISAM и InnoDB СУБД MySQL?

2.Каково назначение системных таблиц в СУБД PostgreSQL?

3.Каким образом реализуется механизм транзакций и каковы базовые свойства транзакций?

4.Чем отличаются хранимые процедуры от триггеров?

5.Чем отличается составной тип данных RECORD от

ROWTYPE?

6.Каким образом выполняется доступ к серверу базы данных из приложений пользователя?

123

Глава 5. ЯЗЫК SQL

Cтруктура языка SQL

Во второй главе были рассмотрены два фундаментальных языка запросов к реляционным БД: реляционная алгебра и реляционное исчисление. При всей своей строгости и теоретической обоснованности эти языки редко используются в современных реляционных СУБД в качестве средств пользовательского интерфейса. Запросы на этих языках трудно формулировать и понимать.

Язык SQL (Structure Query Language) представляет собой неко-

торую комбинацию реляционного исчисления кортежей и реляционной алгебры.

На рис. 5.1 представлена обобщенная структура языка SQL.

 

 

 

 

 

 

SQL

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Операторы

 

 

 

 

 

Операторы

 

манипулирования

 

 

 

 

манипулирования

 

 

данными

 

 

 

 

 

схемой БД

 

 

(SQL)

 

 

 

 

 

(DDL)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

SELECT

 

 

 

 

 

 

CREATE

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

INSERT

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

DROP

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

DELETE

 

 

 

 

 

 

ALTER

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

UPDATE

 

 

 

 

 

 

GRANT

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Рис. 5.1. Обобщенная структура языка SQL

Язык SQL состоит из двух частей. Операторы манипулирования данными (SELECT, INSERT, DELETE, UPDATE) ориентированы на удобную и понятную пользователям формулировку запросов к реляционной БД.

124

Операторы определения и манипулирования схемой базы дан-

ных DDL — Date Definition Language (CREATE, DROP, ALTER)

содержат средства для:

определения и манипулирования схемой БД;

определения ограничений целостности и триггеров;

определения представлений БД;

определения структур физического уровня, поддерживающих эффективное выполнение запросов;

авторизации доступа к отношениям и их полям;

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

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

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

Самый общий вид запроса на языке SQL представляет теорети- ко-множественное алгебраическое выражение, составленное из элементарных запросов, при этом допустимы все базовые теорети- ко-множественные операции (UNION, INTERSECT и MINUS).

Операторы манипулирования данными UPDATE и DELETE построены на тех же принципах, что и оператор выборки данных SELECT. Набор кортежей указанного отношения, подлежащих модификации или удалению, определяется входящим в соответствующий оператор логическим выражением, которое может включать сложные предикаты, в том числе и с вложенными подзапросами.

В число операторов определения и манипулирования схемы БД SQL входят операторы создания и уничтожения постоянных и временных хранимых отношений (CREATE TABLE и DROP TABLE) и создания и уничтожения представляемых отношений (CREATE VIEW и DROP VIEW). Оператор манипулирования схемой БД ALTER TABLE позволяет добавлять указываемые поля к существующим отношениям.

125

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

ВSQL используются структуры физического уровня: индексы и связи, обеспечивающие эффективное выполнение запросов к БД. Индекс — это инвертированный файл, обеспечивающий доступ к кортежам соответствующего отношения на основе заданных значений одного или нескольких столбцов, составляющих ключ индекса.

Важной особенностью языка SQL является обеспечение защиты доступа к данным средствами самого языка. Основная идея такого подхода состоит в том, что по отношению к любому отношению БД и любому столбцу отношения вводится предопределенный набор привилегий. С каждой транзакцией неявно связывается идентификатор пользователя, от имени которого она выполняется.

После создания нового отношения все привилегии, связанные с этим отношением и всеми его столбцами, принадлежат только пользователю-создателю отношения. В число привилегий входит привилегия передачи всех или части привилегий другому пользователю, включая привилегию на передачу привилегий. Технически передача привилегий осуществляется при выполнении оператора GRANT. Существует также привилегия изъятия (REVOKE) всех или части привилегий у пользователя, которому они ранее были переданы.

Деятельность по стандартизации языка SQL началась практически одновременно с появлением первых его коммерческих реализаций. Первый стандарт ANSI/ISO вышел в октябре 1985 г.

Вмарте 1992-го был выработан окончательный проект стандарта (SQL-92), который охватывает практически все необходимые для реализации аспекты: манипулирование схемой БД, управление транзакциями, подключение к БД, динамический SQL.

Определение схемы данных. Оператор CREATE

После создания ER-диаграммы предметной области необходимо перейти к реляционной схеме данных, т.е. описать таблицы, поля таблиц (с указанием имен и типов полей), задать индексы и ограничения целостности и т.д. Для выполнения этих операций предна-

126

значен язык DDL (Date Definition Language) являющийся одной из составных частей языка SQL. Конструкции языка DDL очень просты и не требуют большого времени для их изучения. Описание любой реляционной схемы должно начинаться с создания базы данных. Для этого выполняется оператор CREATE DATABASE. Например, для создания базы банных mydb необходимо, после соединения с сервером базы данных, выполнить команду (здесь и в дальнейшем будут рассматриваться примеры для СУБД PostgreSQL):

CREATE DATABASE mydb;

Далее следует присоединиться к вновь созданной базе данных с помощью команды

\c mydb;

После этого можно создавать таблицы с помощью команды

CREATE TABLE, например: CREATE TABLE student

(

st_id

serial,

 

fio

varchar(32)

NOT NULL,

CONSTRAINT

st_pk

PRIMARY KEY(st_id)

);

После имени таблицы (в примере — student) в круглых скобках задаются имена и типы полей (разделяемые запятыми), а также ограничения для столбцов и таблиц.

В приведенном примере в качестве ограничения на столбец fio указано NOT NULL (поле не может быть пустым). Кроме того, можно указать: UNIQUE (уникальность), PRIMARY KEY (первичный ключ), DEFAUL <value> (значение по умолчанию), CHECK (condition) (проверка условий при вводе или обновлении данных), REFERENCES (ссылочная целостность).

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

CONSTRAINT st_pk PRIMARY KEY(st_id)

Это означает, что первичным ключом является поле st_id. Можно было бы указать PRIMARY KEY в качестве ограничения для столбца st_id, т.е. записать

st_id serial PRIMARY KEY,

127

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

Наибольшую сложность в задании ограничений представляет ограничение ссылочной целостности REFERENCES, которую можно задавать для столбцов и таблиц. Рассмотрим две таблицы: student (студент) и group_table (группа):

CREATE TABLE student

(

st_id

serial PRIMARY KEY,

gr_id

integer REFERENCES group_table(gr_id),

fio

varchar(32) NOT NULL

);

CREATE TABLE group_table

(

gr_id

serial

PRIMARY KEY,

name

varchar(32)

NOT NULL

);

В таблице student поле gr_id является внешним ключом и для него задается ограничение REFERENCES group_table(gr_id), гово-

рящее о том, что данный внешний ключ ссылается на таблицу group_table с первичным ключом gr_id. Заметим, что в качестве имени таблицы названия групп выбрано group_table, а не group, поскольку GROUP BY является ключевой фразой в SQL запросах и это могло бы привести впоследствии к проблемам при построении и отладке SQL-запросов.

Аналогичные ограничения для таблиц можно записать так:

CREATE TABLE student

(

 

 

st_id

serial,

 

gr_id

integer,

 

fio

varchar(32)

NOT NULL,

CONSTRAINT st_pk PRIMARY KEY(st_id), CONSTRAINT gr_fk FOREIGN KEY(gr_id) REFERENCES group_table(gr_id)

);

128

CREATE TABLE group_table

(

 

 

gr_id

serial,

 

name

varchar(32)

NOT NULL,

CONSTRAINT gr_pk PRIMARY KEY(gr_id),

);

Рекомендуется [6] всегда использовать ограничения для таблиц, а не смешивать разные виды ограничений для столбцов и таблиц.

Если возникает необходимость удалить какую-то таблицу или вообще базу данных, то необходимо использовать оператор DROP:

DROP TABLE student;

DROP DATABASE mydb;

Изменение структуры таблиц выполняется с помощью команды ALTER, которая имеет простой и понятный синтаксис. Например, с помощью команд

ALTER TABLE table_name ADD COLUMN col_name col_type; ALTER TABLE table_name RENAME COLUMN old_col_name

TO new_col_name;

ALTER TABLE old_table_name RENAME TO new_table_name;

можно добавить и переименовать столбец или переименовать саму таблицу.

Выборка данных. Оператор SELECT

Прежде чем переходить к рассмотрению особенностей построения сложных SQL-запросов, рассмотрим общий синтаксис оператора SELECT на примере СУБД PostgreSQL (данное описание получено с помощью ввода команды \h SELECT в psql):

SELECT [ ALL | DISTINCT [ ON ( expression [, ...] ) ] ] * | expression [ AS output_name ] [, ...]

[ FROM from_item [, ...] ] [ WHERE condition ]

[ GROUP BY expression [, ...] ]

129

[ HAVING condition [, ...] ]

[ { UNION | INTERSECT | EXCEPT } [ ALL ] select ]

[ ORDER BY expression [ ASC | DESC | USING operator ] [, ...] ] [ LIMIT { count | ALL } ]

[ OFFSET start ]

[ FOR UPDATE [ OF table_name [, ...] ] ]

где from_item может быть одним из следующих значений:

[ONLY] table_name [*] [[AS] alias [(column_alias [, ...])]] ( select ) [AS] alias [(column_alias [, ...])]

function_name([argument[,...]]) [AS] alias [(column_alias [,...] | column_definition [, ...])]

function_name([argument[,...]]) AS (column_definition [, ...] ) from_item [NATURAL] join_type from_item [ON join_condition | USING ( join_column [, ...])]

Всамом простейшем виде запрос выглядит так: SELECT * FROM table1;

Вэтом случае будут выбраны все поля и строки таблицы table1

втом порядке, в котором они хранятся в базе данных. Символ звездочка используется для указания всех полей таблицы, причем последовательность вывода полей будет совпадать с последовательностью заданной при создании таблицы. В реальных задачах запросы могут быть очень сложными, иметь несколько десятков строк, а их разработка и отладка аналогичны разработке и отладке программы на языке высокого уровня типа C/C++ или Pascal. Язык SQL нечувствителен к регистру, однако в дальнейших примерах ключевые слова языка SQL (SELECT, FROM, WHERE и т.д.), будут записаны заглавными буквами, а названия таблиц, столбцов, функций будут представлены в нижнем регистре.

Основой оператора SELECT является синтаксическая конструкция "табличное выражение (table expression)". Семантика табличного выражения состоит в том, что на основе последовательно-

го применения разделов FROM, WHERE, GROUP BY и HAVING

из заданных в разделе FROM таблиц строится некоторая новая ре-

130