Программирование >>  Sql: полное руководство 

1 ... 80 81 82 [ 83 ] 84 85 86 ... 264


Условия уникальности столбцов и значения NULL

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

По этой причине в SQL требуется, чтобы любой столбец, являющийся частью первичного ключа, и любой столбец, на который наложено условие уникальности, был объявлен с офаничением not null.

Ссылочная целостность

в главе 4 уже были рассмотрены первичные и внешние ключи, а также отношения предок/потомок между таблицами, создаваемые этими ключами. На рис. И.1 изображены таблицы salesreps и office, а также показана связь между ними, реализованная через первичный и внешний ключи. Столбец office является первичным ключом таблицы offices и уникальным образом идентифицирует каждую строку в этой таблице. Столбец rep office таблицы salesreps представ/гяет собой внешний ключ для таблицы offices. Он идентифицирует офис, за которым закреплен каждый служащий.

Столбцы Rep 0ffice и office создают между сфоками таблиц offices и salesreps отношение предок/потомок. Для каждой сфоки таблицы obtices (предок) существует ноль или более сфок таблицы salesreps (потомки) с таким же идентификатором офиса. Для каждой сфОки таблицы salesreps (потомок) существует ровно одна строка таблицы offices (предок) с таким же идентификатором офиса

Таблица OFFICES

OFFICE

CITY

REGION

NGfl

TARGET

SALES

Denver

Western

$300.000 00

$186.042 00

New York

Eastern

$575.000 00

$692.637 00

Chicago

Eastern

$800,kOO 00

$736,042 00

Atlanta

Eastern

$360.000 00

$367.911 00

Los Angeles

Western

$725,000 00

$836,916 00

Первичный ключ

Таблица SALESREPS

Ссылка

Внешний ключ

EMPL NUM

NAME

REP OFFICE

TITLE

Bill Adams

Sales Rep

Mary Jones

Sales Rep

Sue Smith

Sales Rep

Sam Clark

VP Sales

Bab Smitfi

Sales Mgr

Dan Roberts

Sales Rep

Tom Snyder

NULL

Sales Rep

Larry Fitch

Sales Mgr

Paul Cruz

Sales Rep

Nancy Angel 11

Sales Rep

Рис 1 J. 1. Отношение внешний ключ ~ первичный ключ



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

INSERT INTO SALESREPS (EMPL NUM, NAME, REP OFFICE, AGE,

HIRE DATE, SALES) VALT3ES (115, George Smith, 31, 37, Ol-APR-90, 0.00)

Ha первый взгляд, это нормальная инструкция insert. И действительно, во многих СУБД такая строка будет благополучно добавлена в таблицу. В базе данных появится информация о том, что Джордж Смит (George Smith) работает в офисе с идентификатором 31, хотя офиса с таким идентификатором в таблице offices нет. Ясно, что новая строка нарущает отношение предок/потомок, существующее между таблицами offices и salesreps. Скорее всего, идентификатор офиса 31 в инструкции insert является ошибочным - вероятно, пользователь намеревался ввести идентификатор 11, 21 или 13.

Кажется достаточно очевидным, что допустимое значение для столбца rep OF-fice должно быть равно одному из значений, содержащихся в столбце office. Это правило известно как условие ссылочной целостности. Оно обеспечивает целостность отношений предок/потомок, создаваемых внешними и первичными ключами.

Ссылочная целостность стала ключевым элементом реляционной модели с тех пор, как доктор Кодд впервые описал эту модель. Однако условия ссылочной целостности отсутствовали как в System/R - экспериментальной СУБД компании IBM, так и в первых версиях DB2 и SQL/DS. Компания IBM ввела поддержку ссылочной целостности в DB2 только в 1989 году, а в стандарт SQL1 она была добавлена уже после выхода его первой редакции. В настоящее время большинство поставщиков либо уже реализовали в своих СУБД поддержку ссылочной целостности, либо объявили о планах сделать это в следующих версиях своих профаммных продуктов.

Проблемы, связанные со ссылочной целостностью

Существует четыре типа изменений базы данных, которые могут нарушить ссылочную целостность отношений предок/потомок. Рассмофим каждую из этих четырех ситуаций на примере таблиц offices и salesreps, представленных на рис. II.1.

Добавление новой строки-потомка. Когда происходит добавление новой строки в таблицу-потомок (salesreps), значение ее внешнего ключа (rep office) должно быть равно одному из значений первичного ключа (office) в таблице-предке (offices). Если значение внешнего ключа не равно ни одному из значений первичного ключа, то добавление такой сфоки разрушит базу данных, поскольку появится потомок без предка ( сирота ). Обратите внимание на то, что добавление Сфоки в таблицу-предок не вызовет проблем; она просто станет предком без потомков.

Обновление внешнего ключа в строке-потомке. Это та же проблема, что и в предыдущей ситуации, но выраженная в иной форме. Если внешний ключ (rep of-Fice) обновляется инсфукцией update, то его новое значение должно быть равно одному из значений первичного ключа (office) в таблице-предке (offices). В противном случае обновленная сфока окажется сиротой.

Удаление строки-предка. Если из таблицы-предка (offices) будет удалена строка, у которой есть хотя бы один потомок (в таблице salesreps), то строки-потомки станут сиротами. Значения внешних ключей (rep office) в этих строках больше



не будут равны ни одному из значений первичного ключа (office) таблицы-предка. Обратите внимание на то, что удаление строки из таблицы-потомка не вызовет проблем; просто предок этой строки после удаления будет иметь на одного потомка меньше, ш Обновление первичного ключа в строке-предке. Это иная форма проблемы, рассмотренной в предыдущем пункте. Если происходит изменение первичного ключа (office) некоторой строки в таблице-предке (offices), все существующие потомки этой строки становятся сиротами, поскольку их внешние ключи больше не равны ни одному первичному ключу.

Средства поддержки ссылочной целостности, имеющиеся в DB2 и в стандарте ANSI/ISO, позволяют обрабатывать каждую из четырех описанных ситуаций. Первая проблема (добавление строки в таблицу-потомок) решается путем проверки значений в столбцах внешнего ключа перед выполнением инструкции insert. Если они не равны ни одному из значений первичного ключа, то инструкция insert отбрасывается и выдается сообщение об ошибке. По отношению к рис. 11.1 это означает, что для добавления в таблицу salesreps нового служащего необходимо, чтобы в таблице offices уже был офис, в который назначается данный служащий. Как видите, в учебной базе данных это ограничение имеет смысл.

Вторая проблема (обновление таблицы-потомка) решается аналогично: путем проверки нового значения внешнего ключа. Если нет ни одного равного ему значения первичного ключа, инструкция update отбрасывается с выдачей сообщения об ошибке. По отношению к рис. 11.1 это означает, что для перевода служащего в другой офис необходимо, чтобы этот офис уже присутствовал в таблице offices. В учебной базе данных это ограничение также имеет смысл.

Третья проблема (удаление строки-предка) является более сложной. Предположим, например, что вы закрыли офис в Лос-Анджелесе и хотите удалить соответствующую строку из таблицы offices. Что при этом должно произойти с двумя строками-потомками в таблице salesreps, которые представляют служащих, закрепленных за офисом в Лос-Анджелесе? В зависимости от ситуации можно:

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

автоматически удалить двух служащих из таблицы salesreps;

в столбце rep office установить для этих двух служащих значение null, показывая тем самым, что идентификатор их офиса неизвестен;

в столбце rep office для этих двух служащих установить по умолчанию некоторое значение, например идентификатор главного офиса в Нью-Йорке, указывая тем самым, что служащие автоматически переводятся в этот офис. Аналогичные сложности существуют и в четвертой ситуации (обновление первичного ключа в таблице-предке). Допустим, по каким-либо причинам требуется изменить идентификатор офиса в Лос-Анджелесе с 21 на 23. Подобно предыдущему примеру, возникает вопрос о том, как поступить с двумя строками-потомками в таблице salesreps, представляющими служащих лос-анджелесского офиса. И снова проблему можно решить четырьмя способами:

не изменять идентификатор офиса до тех пор, пока служащие не будут переведены в другой офис; в таком случае в таблицу offices следует вначале добавить строку с новым идентификатором офиса в Лос-Анджелесе, затем обновить таблицу salesreps и, наконец, удалить строку со старым идентификатором лос-анджелесского офиса;



1 ... 80 81 82 [ 83 ] 84 85 86 ... 264

© 2006 - 2024 pmbk.ru. Генерация страницы: 0.001
При копировании материалов приветствуются ссылки.
Яндекс.Метрика