У меня есть сценарий вроде этого:MSSQL Constraint может вызвать циклы или несколько путей каскадных
User
может владеть мультипликатор Accounts
. User
также имеет адреса биткойнов (которые он сам вводит), и они являются «адресами вывода». Каждый 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 и Deposit на две разные таблицы (так как это было бы правильным решением для этого сценария, но я хочу знать, почему я не могу создавать такие ссылки)
Вот моя скрипка, чтобы играть с: http://sqlfiddle.com/#!6/5d9cd
У вашего дизайна есть еще одна проблема. Строка в «биткойнАдрессах» может ссылаться на «Пользователь» и «Учетная запись» с разными 'UserId'. Это намеренно? Если нет, вы можете удалить 2 FK и использовать только один, с: 'FOREIGN KEY (UserId, AccountId) ССЫЛКИ [dbo]. [Учетные записи] (UserId, Id)', вы сможете решить обе свои проблемы;) О, и вам нужно будет добавить ограничения 'UNIQUE' в' Accounts' для определения указанного FK. –
Разделение таблицы на два кажется лучшим решением для этого. Для пользователей нужно было бы только FK (и никакой столбец AccountID), а другой - только для учетных записей. Нет нескольких каскадных путей и столбцов с нулевым значением. –
Спасибо за ваши предложения. Я знаю, что могу разбить его на две таблицы, хотя в моем случае это не так просто, потому что весь этот сценарий управляется Entity Framework. Таким образом, структура гарантирует, что у меня нет ситуации, когда у меня есть разные «учетные записи» и «пользователь» на одном «биткойн-аддресе». Но спасибо, что заметили, хороший улов! –