
- •Организация хранения данных в sql Server
- •Страницы
- •Экстенты
- •Использование sql Server Management Studio
- •Создание баз данных в sql Server Management Studio
- •Использование ограничений на умолчания
- •Обеспечение целостности сущностей
- •Использование первичных ключей
- •Использование ограничений на уникальность
- •Обеспечение целостности ссылок
- •Использование внешних ключей
Обеспечение целостности ссылок
Сейчас в базе данных 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, как показано на рисунке (рис. 20).
Рис. 20. Связывание таблиц
Щелкните на кнопке ОК. Диалоговое окно Foreign Key Relationships должно выглядеть следующим образом (рис. 21).
Рис. 21. Создание внешнего ключа
Чтобы создать ключ, щелкните на кнопке Close.
Чтобы сохранить таблицу, щелкните на кнопке [X], а затем на Yes в диалоговом окне Save.
11. В Object Explorer щелкните правой кнопкой мыши на папке Keys таблицы Orders и выполните команду Refresh.
12. Расширьте папку Keys и вы увидите новый ключ.
Обратите внимание на следующие параметры в нижней части диалогового окна, показанного на рис. 21:
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 (рис. 23).
3. Чтобы окончательно убедиться, что все работает, как надо, добавьте в таблицу Orders запись с существующим номером клиента, выполнив в окне запросов следующий код:
USE sales
INSERT orders
VALUES (1,5,57,getdate())
Рис. 23. Добавление записи было отклонено
Как видите, код был выполнен, поскольку клиент с номером 1 существует.
Теперь при наличии соответствующей записи в таблице Orders попытайтесь удалить данные о клиенте 1 из таблицы Customers.
USE sales
DELETE from customers
WHERE custid = 1
Теперь вы видите, что записи в связанных таблицах защищены от некорректных обновлений. Пользователи не могут добавить запись в таблицу внешнего ключа без соответствующей записи в таблице первичного ключа, а записи в таблице первичного ключа нельзя удалить, если имеются соответствующие записи в таблице внешнего ключа.