Да. Внешний ключ не предназначен только для очистки после себя, но прежде всего для обеспечения правильности данных (в некоторых случаях это также может помочь оптимизатору). Я использую внешние ключи повсюду, но мне еще предстоит найти необходимость в реализации каскадных действий. Я понимаю цель каскада, но мне всегда было лучше контролировать эти процессы.
EDIT хотя я пытался объяснить уже, что вы можете работать вокруг проблемы каскадного (при этом еще удовлетворяющий ваш третье условие), я думал, что я хотел бы добавить иллюстрацию:
Можно, конечно, по-прежнему позволяют для заказов оставаться после удаления клиента. Ключ состоит в том, чтобы сделать столбец Orders.CustomerID
нулевым, например.
CREATE TABLE dbo.Customers(CustomerID INT PRIMARY KEY);
CREATE TABLE dbo.Orders(OrderID INT PRIMARY KEY, CustomerID INT NULL
FOREIGN KEY REFERENCES dbo.Customers(CustomerID));
Теперь, когда вы хотите удалить клиента, если вы контролировать эти операции с помощью хранимой процедуры, вы можете сделать это таким образом, первым установив их Orders.CustomerID
в NULL
:
CREATE PROCEDURE dbo.Customer_Delete
@CustomerID INT
AS
BEGIN
SET NOCOUNT ON;
UPDATE dbo.Orders SET CustomerID = NULL
WHERE CustomerID = @CustomerID;
DELETE dbo.Customers
WHERE CustomerID = @CustomerID;
END
GO
Если вы можете «т управления специальной удалений из таблицы Customers, то вы можете добиться этого с вместо триггера:
CREATE TRIGGER dbo.Cascade_CustomerDelete
ON dbo.Customers
INSTEAD OF DELETE
AS
BEGIN
SET NOCOUNT ON;
UPDATE o SET CustomerID = NULL
FROM dbo.Orders AS o
INNER JOIN deleted AS d
ON o.CustomerID = d.CustomerID;
DELETE c
FROM dbo.Customers AS c
INNER JOIN deleted AS d
ON c.CustomerID = d.CustomerID;
END
GO
это все сказанное, я не уверен, Я понимаю цель удаления клиента и сохранения их заказов (или любых указаний о том, кто разместил этот заказ).
Я совершенно не расстраиваю ваш ответ, потому что, если вы говорите «да», я должен использовать их в своем сценарии, но этот ответ нарушает условие «3»: я хочу удалить клиента, хотя некоторые заказы ссылаются на этого клиента. Исправьте свое решение. – Elisabeth
@Elisa Ваш вопрос: «Имеет ли внешний ключ смысл в этом сценарии, когда я не использую ссылочную целостность с помощью On/Delete Cascade?» Если это не вопрос, на который вы хотите, чтобы люди ответили, пожалуйста, исправьте свой вопрос. –
Возможно, у моего образца заказчик заказов был глупым. Его просто образец, чтобы проиллюстрировать проблему. Я просто хочу разрешить пользователю удалять данные из родительских таблиц, но данные детей все равно могут читать. С помощью каскада delete или внешнего ключа. Я не могу это сделать. Исключение составляет отношение NULL/optional от 1 клиента к * .. N Заказ. Это решение просто препятствует тому, чтобы я получил ограничение внешнего ключа - исключение, исключающее клиента. НО, когда я не использую накладные расходы FK. У меня нет этой проблемы вообще. FK's и индекс на нем полезны только в этом случае: – Elisabeth