Язык определения данных

Современная структура языка.

Существуют различные подходы к структурированию языка SQL, но мы воспользуемся традиционным. Как уже отмечалось ранее, в языках для работы с данными выделяют три части – язык определения данных (DDL), язык манипулирования данными (DML) и язык управления данными (DCL). Эти три части имеются и в языке SQL.

К языку определения данных в первую очередь относятся запросы, предназначенные для создания (CREATE), изменения (ALTER) и удаления (DROP) таблиц. Помимо таблиц, в базе данных немало и других сущностей, которые также можно создавать, изменять и удалять, но мы, в рамках данного конспекта, остановимся только на работе с таблицами. Этого достаточно, чтобы выполнять основные операции.

Язык манипулирования данными включает запросы на добавление (INSERT), изменение (UPDATE) и удаление (DELETE) записей. Кроме того, сюда же относятся и запросы на выборку данных (SELECT).

Наконец, говоря о языке управления данными, нужно в первую очередь упомянуть запросы для создания ролей (CREATE ROLE), а также назначения (GRANT) и отзыва (REVOKE) полномочий. Не все СУБД вообще поддерживают эти запросы, а во многих СУБД эти же действия можно выполнить, используя графические средства администрирования. В настоящем конспекте мы не будет рассматривать эту часть языка, а интересующиеся могут обратиться к литературе или непосредственно к стандарту.

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

Как уже было сказано, мы рассмотрим конструкции языка, использующиеся для работы с таблицами.

Для создания таблиц используется запрос CREATE TABLE. Мы не будем углубляться в подробности, а ограничимся базовыми частями этого запроса. Его структура выглядит следующим образом:

CREATE TABLE имя_таблицы

(имя_поля1 тип_поля [(размер)] [ограничение_поля],

….

имя_поляN тип_поля [(размер)] [ограничение_поля],

[ограничения_таблицы]);

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

CREATE TABLE Студент

(НомерЗачетки CHAR(10) PRIMARY KEY,

Имя VARCHAR(25) NOT NULL,

Отчество VARCHAR(25) NOT NULL,

Фамилия VARCHAR(25) NOT NULL,

ДатаРождения DATE NOT NULL,

СерияПаспорта CHAR(4) NOT NULL,

НомерПаспорта CHAR(6) NOT NULL,

Аттестат VARCHAR(20) NOT NULL UNIQUE,

РоднойГород VARCHAR(50) NOT NULL DEFAULT ‘Киров’,

ШифрГруппы VARCHAR(10),

UNIQUE (СерияПаспорта, НомерПаспорта),

CONSTRAINT Студент_Группа FOREIGN KEY (ШифрГруппы)

REFERENCES Группа (ШифрГруппы)

ON UPDATE CASCADE ON DELETE SET NULL);

Теперь прокомментируем запрос. Первое поле таблицы, НомерЗачетки, в качестве типа использует строку постоянной длины (предположим, что номера зачетных книжек состоят из 10 символов), а также к нему применено ограничение PRIMARY KEY, что в переводе означает первичный ключ. С помощью этого ограничения мы можем определить первичный ключ таблицы. Надо иметь в виду, что если первичный ключ составной, то следует задавать ограничение не для отдельных строк, а для таблицы в целом, как это будет рассмотрено немного далее.

Поля Имя, Отчество и Фамилия – это строки переменной длины (то есть, хранятся только введенные символы, но не более заданного размера), и кроме того, для них задано ограничение NOT NULL. Это ограничение означает запрет пустых значений в этих полях. В самом деле, у каждого человека должно быть имя, отчество и фамилия (по крайней мере, мы так предполагаем). Соответственно, СУБД будет отслеживать заполненность этих полей значениями. Надо помнить, что NULL означает отсутствие значения, и NULL не эквивалентно пустой строке или строке из одних пробелов – это уже определенные значения. Об этом нужно помнить, и мы еще вернемся к этому вопросу при рассмотрении запросов на выборку данных.

Поля ДатаРождения, СерияПаспорта и НомерПаспорта не представляют особого интереса. Обратим внимание на поле Аттестат. Для него, помимо запрета пустых значений, задано ограничение UNIQUE. Оно означает требования уникальности значений в этом поле. То есть, номера аттестатов у наших студентов не могут повторяться. При попытке добавить строку, номер аттестата в которой совпадает с уже имеющимся, мы получим ошибку и строка добавлена не будет.

Следующее поле, РоднойГород, снабжено значением по умолчанию при помощи конструкции DEFAULT. В нашем случае мы предполагаем, что большинство студентов будет местными, то есть если город в явном виде задан не будет, то будет устанавливаться значение по умолчанию – Киров.

Последнее поле ШифрГруппы – это поле внешнего ключа, с его помощью мы сможем установить связь студента и группы, в которой он учится. Обратите внимание, что для данного поля мы не установили ограничения NOT NULL, так как студент в какие-то моменты времени может и не входить ни в одну группу. В случае, если бы такое ограничение было задано, мы не смогли бы внести данные о студенте без помещения его в конкретную группу, а это не всегда удобно.

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

Для записи следующего ограничения использован более полный синтаксис. Запись начинается с ключевого слова CONSTRAINT, что в переводе и означает «ограничение». Далее идет имя ограничения, с помощью которого можно к нему обращаться, скажем, при необходимости его удалить (в запросе на изменение таблицы). После имени указывается тип ограничения, в нашем случае это ограничение внешнего ключа, FOREIGN KEY, а затем уже идут параметры самого ограничения. Для внешнего ключа мы сначала указываем, какое поле (или поля) в нашей таблице используется для связи, затем, после ключевого слова REFERENCES (англ. «ссылается») указываем таблицу и список полей, которые используются для связи в ней. В большинстве случаев это поля первичного ключа. Наконец, после указания полей, мы можем задать поведение нашей таблицы при изменении значения первичного ключа в главной таблице. Ключевое слово ON UPDATE задает поведение при изменении первичного ключа, в нашем случае это CASCADE, то есть каскадное обновление. При изменении шифра группы в таблице групп все записи студентов, связанных с этой группой, также будут обновлены и им будет задано новое значение внешнего ключа. Ключевое слово ON DELETE определяет поведение студентов при удалении группы, в которую они входят. Очевидно, что студенты не должны никуда исчезать, поэтому каскадное удаление тут не подходит. В то же время, задать новое значение шифра группы также невозможно – оно просто неизвестно в этот момент. Поэтому выбран вариант SET NULL – установка пустого значения. Соответственно, после удаления группы студенты, которые в ней числились, перестают входить в какую-либо группу.

Мы рассмотрели основные элементы запроса создания таблицы. Теперь можно обсудить запрос на изменение таблицы. Он выглядит следующим образом:

ALTER TABLE имя_таблицы

[ADD [COLUMN] имя_поля тип_поля [(размер)] [ограничения_поля]]

| [ALTER [COLUMN] имя_поля SET DEFAULT значение]

| [ALTER [COLUMN] имя_поля DROP DEFAULT]

| [ALTER [COLUMN] имя_поля ADD SCOPE имя_таблицы]

| [ALTER [COLUMN] имя_поля DROP SCOPE {RESTRICT | CASCADE}]

| [DROP [COLUMN] имя_поля {RESTRICT | CASCADE}]

| [ADD ограничение_таблицы]

| [DROP CONSTRAINT ограничение_таблицы {RESTRICT | CASCADE}];

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

Предложения ADD SCOPE и DROP SCOPE используются для определения пользовательских типов данных. В настоящем конспекте мы не затрагиваем эту тему, интересующиеся могут обратиться к литературе.

Ключевые слова RESTRICT и CASCADE определяют поведение СУБД, если у удаляемой колонки таблицы, области определения или ограничения имеются зависимые элементы. Использование RESTRICT приведет к тому, что операция удаления будет отменена, если найдутся зависимые элементы, а при использовании CASCADE зависимые элементы будут также удалены. Приведем небольшой пример, удалим значение по умолчанию для поля РоднойГород таблицы Студент.

ALTER TABLE Студент

ALTER COLUMN РоднойГород DROP DEFAULT;

В целом формирование таких запросов не должно представлять особых сложностей.

Для удаления таблицы используется запрос DROP TABLE, который выглядит следующим образом:

DROP TABLE имя_таблицы {RESTRICT | CASCADE}

Ключевые слова RESTRICT и CASCADE имеют здесь тот же смысл, что и в запросе на изменение таблицы.

На этом мы закончим рассмотрение языка определения данных. Мы не затрагивали особенности реализации запросов в конкретных СУБД, эта тема выходит за рамки данного конспекта. Тем не менее, приведенные в качестве примера запросы должны успешно сработать в большинстве популярных систем.


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: