Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Подготовка к ПР_2.4.rtf
Скачиваний:
4
Добавлен:
01.05.2025
Размер:
7.36 Mб
Скачать

2.1.2. Ограничения для таблиц

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

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

CREATE TABLE Студент (

Фамилия CHAR(20),

Имя CHAR(15),

Отчество CHAR(20),

Специальность INTEGER,

Примечание VARCHAR,

CONSTRAINT PRIMARY KEY (Фамилия, Имя, Отчество)

);

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

INSERT INTO Студент (Фамилия, Имя, Отчество, Специальность)

VALUES ('Петров', 'Петр', 'Петрович', 5) ;

INSERT INTO Студент (Фамилия, Имя, Отчество, Специальность)

VALUES ('Петров', 'Петр', 'Иванович', 5);

2.1.3. Внешние ключи

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

Пусть в базе данных имеются две таблицы:

Заказы (ID_заказа, ID_клиента)- содержит сведения о том, какие заказы сделал тот или иной клиент;

Клиенты (ID_клиента, Имя, Адрес, Телефон)- сведения о клиентах (справочник).

В таблице Клиенты столбец ID_клиента является первичным клю­чом, т. е. его значения отличны от NULL и уникальны. В таблице Заказы столбец ID_клиента не обязан иметь уникальные значе­ния, поскольку один и тот же клиент может сделать несколько заказов. Вместе с тем любому значению столбца Заказы. ID_клиента соответствует единственное значение столб­ца Клиенты.ID_клиента. При описанных условиях столбец ID_клиента таблицы Заказы является внешним ключом, ссылаю­щимся на первичный ключ ID_клиента таблицы Клиенты.

Внешний ключ определяется как ограничение для таблицы в выра­жении с ключевыми словами CONSTRAIN FOREIGN KEY (ограниче­ние "внешний ключ"):

CONSTRAINT FOREIGN KEY внешнийКлюч REFERENCES

внешняяТаблица (первичныйКлюч)

Здесь внешнийКлюч- имя столбца или список столбцов, разде­ленных запятыми, которые определяют внешний ключ, за ключе­вым словом REFERENCES (ссылки) указывается внешняя таблица и ее первичный ключ, на который ссылается внешний ключ.

Для рассмотренного ранее примера таблицу Заказы можно опре­делить следующим образом:

CREATE TABLE Заказы (

ID_заказа INTEGER,

ID_клиента INTEGER,

CONSTRAINT FOREIGN KEY ID_клиента REFERENCES Клиенты (ID_клиента)

);

Использование внешних ключей обеспечивает сохранение ссы­лочной целостности базы данных при изменении и удалении записей. Если бы таблицы заказы и клиенты не были связаны, то при удалении записи из таблицы Клиенты в таблице Заказы могли остаться ссылки на клиента, о котором уже нет сведений. Этот факт обычно расценивается как аномалия удаления. В случае оп­ределения в таблице заказы внешнего ключа ID_клиента из таб­лицы клиенты не удастся удалить клиента, если он сделал хотя бы один заказ. Если требуется удалить из базы данных все, что каса­ется определенного клиента, то сначала удаляются записи в таб­лице Заказы, а потом - в таблице Клиенты.

Аналогичная ситуация может произойти и при обновлении дан­ных. Например, в таблице клиенты вы изменили идентификатор клиента, имеющего заказы, и, таким образом, внешнему ключу теперь не на что ссылаться. Это аномалия изменения. В данном случае необходимо сначала добавить новую запись в таблицу клиенты, указав в ней необходимое значение ID_клиента, затем изменить в таблице заказы все старые значения ID_клиента на то, которое вы только что ввели в новой записи таблицы клиенты, а затем удалить из таблицы Клиенты запись со старым идентифи­катором клиента.

Чтобы в таблицах, связанных внешним ключом, не делать моди­фикацию данных в несколько этапов, в выражении CONSTRAIN FOREIGN KEY можно использовать дополнительные ключевые слова:

  • ON DELETE CASCADE | SET NULL (при удалении каскадировать | установить NULL);

  • ON UPDATE CASCADE| SET NULL (при обновлении каскадировать | установить NULL).

Здесь вертикальная черта не является элементом синтаксиса, а лишь разделяет возможные варианты ключевых слов.

Так, при использовании ON DELETE CASCADE в случае удаления записи со значением первичного ключа, которое имеется во внешнем ключе другой таблицы, соответствующие записи уда­ляются автоматически из двух таблиц. Например, при удалении из таблицы Клиенты записи о клиенте, имеющем заказы, в табли­це Заказы также будут удалены все записи, ссылающиеся на дан­ного клиента. Чтобы данная стратегия выполнялась, таблица Заказы должна быть определена следующим образом:

CREATE TABLE Заказы (

ID_заказа INTEGER,

ID_клиента INTEGER,

CONSTRAINT FOREIGN KEY ID_клиента REFERENCES Клиенты (ID_клиента)

ON DELETE CASCADE

);

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

Вариант SET NULL обычно используется при обновлении данных.

Например:

CREATE TABLE Заказы (

ID_заказа INTEGER,

ID_клиента INTEGER,

CONSTRAINT FOREIGN KEY ID_клиента REFERENCES Клиенты (ID_клиента)

ON UPDATE SET NULL

);

В данном случае при изменении (в том числе и при удалении) в таблице Клиенты записи, на которую ссылается внешний ключ таблицы Заказы, значения внешнего ключа устанавливаются в NULL. Однако этот вариант не сработает, если на столбец Заказы. ID_клиента наложено ограничение NOT NULL. Обычно так и бывает, поскольку при оформлении заказа клиент должен быть обязательно указан. Поэтому, на всякий случай, лучше использо­вать ключевые слова ON UPDATE CASCADE.