Lab5_SQL (1059123), страница 4
Текст из файла (страница 4)
Обеспечение целостности ссылок
Сейчас в базе данных Sales находится три таблицы: по одной для данных о клиентах, товарах и заказах. Каждая из этих трех таблиц содержит данные, на которые влияют данные, содержащиеся в других двух таблицах. Например, на данные таблицы Orders влияют данные таблицы Customers, т.е. вы не должны создавать заказ для клиента, данные о котором отсутствуют в таблице Customers. На таблицу Orders также влияют данные таблицы Products, т.е. вы не станете создавать заказ отсутствующего продукта. Чтобы обеспечить гарантию наличия записи о клиенте в таблице Customers перед тем, как продать ему что-нибудь, или чтобы не продавать несуществующую продукцию, вам нужно обеспечить целостность ссылок.
Суть обеспечения целостности ссылок очевидна из названия: данные в одной
таблице, ссылающиеся на данные из другой таблицы, защищены от некорректного
обновления. В терминологии SQL Server обеспечение целостности ссылок называется декларативной ссылочной целостностью и достигается путем связывания первичного ключа одной из таблиц с внешним ключом другой таблицы.
Использование внешних ключей
Внешний ключ используется в комбинации с первичным для связывания двух таблиц по общему столбцу. Вы, к примеру, можете связать таблицы Orders и Customers через столбец CustID, который есть в обеих таблицах. Если вы используете поле CustID таблицы Customers в качестве первичного ключа (кстати, он у вас уже есть), то можете использовать поле CustID таблицы Orders в качестве внешнего ключа, который свяжет две таблицы. Вы не сможете добавить запись в таблицу Orders, если в таблице Customers нет соответствующей записи. Кроме того, вы не сможете удалить запись из таблицы Customers при наличии соответствующей записи в таблице Orders, поскольку вы не хотите выполнять заказ без информации о клиенте.
Перед демонстрацией того, как все это работает, мы покажем, что произойдет в случае отсутствия ссылочной целостности.
-
В SQL Server Management Studio щелкните на кнопке New Query и выполните команду New SQL Server Query. Подключитесь с помощью аутентификации Windows.
-
Чтобы вставить в таблицу Orders запись с идентификатором клиента, идентификатором продукта и текущей датой (с помощью функции GETDATE ()), введите и выполните следующий код:
USE sales
INSERT orders
VALUES (999,5,57,getdate())
3. Обратите внимание на то, что предыдущий код был успешно выполнен даже несмотря на то, что в таблице Customers нет клиента с идентификационным номером 999.
4. Чтобы удалить ошибочные записи, введите и выполните следующий код (отметим, что это потенциально опасная команда, поскольку она удаляет все записи из таблицы):
truncate table orders
Итак, вы убедились, что можно ввести заказ для несуществующего клиента, и вам нужно защитить от этого базу данных. Создайте в поле CustID таблицы Orders внешний ключ, связанный с полем CustID таблицы Customers (которое является первичным ключом таблицы Customers). С таким отношением данные в ваших таблицах будут защищены. Итак, создадим отношение.
-
Откройте SQL Server Management Studio. B Object Explorer раскройте папки
Databases=>Sales=>Tables=>Orders. -
Щелкните правой кнопкой мыши на папке Keys и выполните команду New Key.
-
В правом блоке в разделе Identity (Name) введите имя FK_Customers_Orders.
-
В блок Description введите описание: Relate tables on CustID.
-
В разделе Tables And Columns Specification щелкните на кнопке с многоточием.
-
В раскрывающемся списке Primary Key Table выберите Customers.
-
В обоих раскрывающихся списках решетки выберите поле CustID, как показано на рисунке (рис. 15).
Рис. 15. Связывание таблиц
-
Щелкните на кнопке ОК. Диалоговое окно Foreign Key Relationships должно выглядеть следующим образом (рис. 16).
Рис. 16. Создание внешнего ключа
-
Чтобы создать ключ, щелкните на кнопке Close.
-
Чтобы сохранить таблицу, щелкните на кнопке [X], а затем на Yes в диалоговом окне Save.
11. В Object Explorer щелкните правой кнопкой мыши на папке Keys таблицы Orders и выполните команду Refresh.
12. Расширьте папку Keys и вы увидите новый ключ.
Обратите внимание на следующие параметры в нижней части диалогового окна, показанного на рис. 16:
-
Check Existing Data On Creation Or Re-Enabling (эта строка находится сверху и её не видно на рисунке). Параметр указывает SQL Server проверить соответствие всех существующих данных в обеих таблицах параметрам ограничения. В случае несоответствия вы получите предупреждение.
-
Enable Relationship For Replication. Репликация используется для копирования баз данных с одного сервера на другой. Этот параметр включает копирование связи посредством репликации на другой сервер вместе с таблицами первичных и внешних ключей.
-
Enforce Foreign Key Constraint. Если вам больше не нужно созданное отношение, вы можете снять этот флажок и отключить отношение, не удаляя его. Таким образом, в будущем вам не нужно будет полностью воссоздавать это отношение.
Протестируйте созданное отношение. Попытайтесь добавить в таблицу Orders несколько записей, для которых нет соответствующих данных в таблице Customers, а затем удалить из таблицы Customers запись, которая ссылается на запись в таблице Orders.
1. Попытайтесь добавить запись:
USE sales
INSERT orders
VALUES (999,5,57,getdate())
2. Как видите, добавление не было выполнено, поскольку в таблице Customers нет клиента с идентификационным номером 999 (рис. 17).
3. Чтобы окончательно убедиться, что все работает, как надо, добавьте в таблицу Orders запись с существующим номером клиента, выполнив в окне запросов следующий код:
USE sales
INSERT orders
VALUES (1,5,57,getdate())
Рис. 17. Добавление записи было отклонено
-
Как видите, код был выполнен, поскольку клиент с номером 1 существует.
-
Теперь при наличии соответствующей записи в таблице Orders попытайтесь удалить данные о клиенте 1 из таблицы Customers.
USE sales
DELETE from customers
WHERE custid = 1
Теперь вы видите, что записи в связанных таблицах защищены от некорректных обновлений. Пользователи не могут добавить запись в таблицу внешнего ключа без соответствующей записи в таблице первичного ключа, а записи в таблице первичного ключа нельзя удалить, если имеются соответствующие записи в таблице внешнего ключа.