我有這樣一個場景:MSSQL約束可能會導致循環或多個級聯路徑
User
可以擁有多個Accounts
。 User
也有比特幣地址(他自己輸入),他們是「取款地址」。每個Account
也可能有多個比特幣地址(這是「存款地址」)。
所有的地址都在一張表中,唯一的區別是存款/提款只是在表BitcoinAddresses
的列Type
中指定。
我想創建一個場景,其中刪除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
您的設計還有一個問題。 'BitcoinAddresses'中的一行可以使用不同的'UserId'來引用'User'和'Account'。這是故意的嗎?如果沒有,你可以刪除2個FK,只用一個:'FOREIGN KEY(UserId,AccountId)REFERENCES [dbo]。[Accounts](UserId,Id)',你將能夠解決你的問題;)哦,你需要在'Accounts'中添加一個'UNIQUE'約束來定義上面的FK。 – 2015-03-19 14:05:42
將表分成兩個似乎是最好的解決方案。人們只需要FK給用戶(並且沒有AccountID列),另一個只需要帳戶。沒有多個級聯路徑和不可空列。 – 2015-03-19 14:18:40
感謝您的建議。我知道我可以將它分成兩個表格,但在我的情況下並不那麼容易,因爲整個場景都是由Entity Framework管理的。所以這個框架確保我沒有在一個'BitcoinAddress'上有不同'Account'和'User'的情況。不過謝謝你的注意,很好! – 2015-03-19 14:50:29