MSSQL约束可能会导致循环或多个级联路径

时间:2015-03-19 11:57:26

标签: sql-server

我有这样的场景:

User可拥有多个AccountsUser也有比特币地址(他自己输入)并且它们是#34;撤回地址"。每个Account也可能有多个比特币地址("存放地址")。

所有地址都在一个表格中,唯一的区别是存款/取款只是由表格Type中的列BitcoinAddresses指定。

我想创建一个方案,删除User将导致他拥有的所有提款BitcoinAddresses被删除,以及他拥有的所有Accounts都将被删除。但删除Account会导致BitcoinAddresses引用设置为NULL

我尝试过这样的事情:

CREATE TABLE [dbo].[Users] (
    [Id]                 NVARCHAR (128) NOT NULL,
    [UserName]           NVARCHAR (64)  NULL,
    CONSTRAINT [PK_dbo.Users] PRIMARY KEY CLUSTERED ([Id] ASC),
);

CREATE TABLE [dbo].[Accounts] (
    [Id]       BIGINT         IDENTITY (1, 1) NOT NULL,
    [UserId]   NVARCHAR (128) NOT NULL,
    [Number] BIGINT         NOT NULL,
    CONSTRAINT [PK_dbo.Accounts] PRIMARY KEY CLUSTERED ([Id] ASC),
    CONSTRAINT [FK_dbo.Accounts.Users_UserId] FOREIGN KEY ([UserId]) REFERENCES [dbo].[Users] ([Id]) ON DELETE CASCADE
);

CREATE TABLE [dbo].[BitcoinAddresses] (
    [BitcoinAddressId] INT            IDENTITY (1, 1) NOT NULL,
    [Address]          NVARCHAR (MAX) NOT NULL,
    [AccountId]     BIGINT         NULL,
    [UserId]           NVARCHAR (128) NULL,
    [Type]            NVARCHAR (MAX) NULL,
    CONSTRAINT [PK_dbo.BitcoinAddresses] PRIMARY KEY CLUSTERED ([BitcoinAddressId] ASC),
    CONSTRAINT [FK_dbo.BitcoinAddresses_dbo.Accounts_AccountId] FOREIGN KEY ([AccountId]) REFERENCES [dbo].[Accounts] ([Id]) ON DELETE SET NULL,
    CONSTRAINT [FK_dbo.BitcoinAddresses_dbo.Users_UserId] FOREIGN KEY ([UserId]) REFERENCES [dbo].[Users] ([Id]) ON DELETE CASCADE
);

此解决方案会导致错误:

Introducing FOREIGN KEY constraint 'FK_dbo.BitcoinAddresses_dbo.Users_UserId' on table 'BitcoinAddresses' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints.

但显然我没有看到这种方法有任何周期。你能解释一下为什么会出现这种情况吗?我该如何解决?我想指出,我不想将Wihtdrawal和存款地址拆分为两个不同的表(因为这对于这种情况来说是一个正确的解决方案,但我想知道为什么我不能创建这样的参考文献)

这是我的小提琴:http://sqlfiddle.com/#!6/5d9cd

1 个答案:

答案 0 :(得分:3)

如果您删除用户,他的帐户将被删除,他的bitcoinaddresses将被删除。但是当他的account被删除后,该帐户bitcoinaddresses也会更新为NULL。这对SQL Server来说太复杂了。它需要级联链简单而整洁,而不是分支和/或会聚。如果用户删除会导致删除比特币并将其帐户设置为NULL,那么SQL-Server如何知道您想要哪个?