我在SQL Server 2014中有三个表。
Product
表(productid,...)ProductVersions
(ProductVersionID,ProductID等)这些表在产品ID上带有外键,在删除级联时也是如此。
现在,我想添加另一个将许可证映射到特定ProductVersions
的表。这可能是n:m关系,所以我创建了一个映射表LicenseVersion
(LicenseID, ProductVersionID
)
当我尝试向该关系添加外键时,我收到一条错误消息,因为存在循环或服务器级联路径,因此无法添加外键。用于删除任何操作或更改外键。
我想,为什么会发生这种情况(删除产品会导致LicenseVersion
行在一次事务中同时从两种方式中删除),但是解决此问题的最佳实践是什么?
数据库应该随时保持一致,因此我不想在软件应用程序逻辑中解决此问题。
我可以使用触发器(我认为)和外键而不执行任何操作,但这是最好的方法吗?
CREATE TABLE [dbo].[Products]
(
[ProductID] [int] IDENTITY(1,1) NOT NULL,
[ProductName] [nvarchar](255) NOT NULL,
CONSTRAINT [PK_dbo.Products]
PRIMARY KEY CLUSTERED([ProductID] ASC)
)
CREATE TABLE [dbo].[ProductVersions]
(
[ProductVersionID] [int] IDENTITY(1,1) NOT NULL,
[ProductID] [int] NOT NULL,
[Name] [nvarchar](255) NOT NULL,
CONSTRAINT [PK_dbo.ProductVersions]
PRIMARY KEY CLUSTERED ([ProductVersionID] ASC)
)
CREATE TABLE [dbo].[License]
(
[LicenseId] [int] IDENTITY(1,1) NOT NULL,
[LicenseName] [nvarchar](255) NOT NULL,
[ProductId] [int] NOT NULL,
CONSTRAINT [PK_dbo.License]
PRIMARY KEY CLUSTERED ([LicenseId] ASC)
)
CREATE NONCLUSTERED INDEX [IX_ProductId]
ON [dbo].[License] ([ProductId] ASC)
CREATE NONCLUSTERED INDEX [IX_ProductID]
ON [dbo].[ProductVersions] ([ProductID] ASC)
ALTER TABLE [dbo].[License] WITH CHECK
ADD CONSTRAINT [FK_dbo.License_dbo.Products_ProductId]
FOREIGN KEY([ProductId]) REFERENCES [dbo].[Products] ([ProductID])
ON UPDATE CASCADE
ON DELETE CASCADE
ALTER TABLE [dbo].[License] CHECK CONSTRAINT [FK_dbo.License_dbo.Products_ProductId]
ALTER TABLE [dbo].[ProductVersions] WITH CHECK
ADD CONSTRAINT [FK_dbo.ProductVersions_dbo.Products_ProductID]
FOREIGN KEY([ProductID]) REFERENCES [dbo].[Products] ([ProductID])
ON UPDATE CASCADE
ON DELETE CASCADE
ALTER TABLE [dbo].[ProductVersions] CHECK CONSTRAINT [FK_dbo.ProductVersions_dbo.Products_ProductID]
--add new table
CREATE TABLE [dbo].[LicenseVersion]
(
[LicenseID] [int] NOT NULL,
[ProductVersionID] [int] NOT NULL,
CONSTRAINT [PK_LicenseVersion]
PRIMARY KEY CLUSTERED ([LicenseID] ASC, [ProductVersionID] ASC)
)
ALTER TABLE [dbo].[LicenseVersion] WITH CHECK
ADD CONSTRAINT [FK_LicenseVersion_ProductVersions]
FOREIGN KEY([ProductVersionID]) REFERENCES [dbo].[ProductVersions] ([ProductVersionID])
ON UPDATE CASCADE
ON DELETE CASCADE
ALTER TABLE [dbo].[LicenseVersion] CHECK CONSTRAINT [FK_LicenseVersion_ProductVersions]
--error here:
ALTER TABLE [dbo].[LicenseVersion] WITH CHECK
ADD CONSTRAINT [FK_LicenseVersion_Licenses]
FOREIGN KEY([LicenseID]) REFERENCES [dbo].[License] ([LicenseID])
ON UPDATE CASCADE
ON DELETE CASCADE
ALTER TABLE [dbo].[LicenseVersion] CHECK CONSTRAINT [FK_LicenseVersion_Licenses]