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

Kel*_*all 3 sql-server

我有一个这样的场景:

User可以拥有多个AccountsUser还有比特币地址(他自己输入的),它们是“提现地址”。每个Account也可能有多个比特币地址(即“存款地址”)。

所有地址都在一张表中,唯一的区别是充值/提现仅由Type表中的一列指定BitcoinAddresses

我想创建一个场景,删除User将导致他拥有的所有提款都BitcoinAddresses被删除,并且Accounts他拥有的所有提款也被删除。但是删除 anAccount应该会导致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
);
Run Code Online (Sandbox Code Playgroud)

该解决方案会导致错误:

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.
Run Code Online (Sandbox Code Playgroud)

但显然我没有看到这种方法有任何循环。你能向我解释一下为什么会出现这种行为吗?我该如何解决?我想指出的是,我不想将提款和存款地址拆分到两个不同的表(因为这对于这种情况来说是正确的解决方案,但我想知道为什么我无法创建此类引用)

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

Tab*_*man 5

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

  • 你是对的,但即使我将它设置为级联删除每个引用,那么它也会给我同样的错误。 (2认同)
  • @TabAlleman 请编辑您的naswer,从“SQL”到“SQL-Server”。还有其他 SQL 产品(如 Postgres)可以与多个级联路径完美配合。SQL-Server 架构师选择禁止这样做(出于一些充分的理由,没有争论)。 (2认同)