Sql server 如何将可选的多对多关系添加到另一个多对多关系表?

Sql server 如何将可选的多对多关系添加到另一个多对多关系表?,sql-server,database-design,many-to-many,database-normalization,Sql Server,Database Design,Many To Many,Database Normalization,我已经定义了以下表格: - Group - GroupID (pk - int) - ... - Item - ItemID (pk - int) - ... - Groups_Items - GroupID (pk - int) - ItemID (pk - int) GroupID上有一个FK链接到组表,ItemID上有一个FK链接到项表 我需要向Groups_Items表中添加一个可选关系,即RuleSetId - Groups_Items - Group

我已经定义了以下表格:

- Group
  - GroupID (pk - int)
  - ...

- Item
  - ItemID (pk - int)
  - ...

- Groups_Items
  - GroupID (pk - int)
  - ItemID (pk - int)
GroupID上有一个FK链接到组表,ItemID上有一个FK链接到项表

我需要向Groups_Items表中添加一个可选关系,即RuleSetId

- Groups_Items
  - GroupId (pk - int)
  - ItemId (pk - int)
  - RuleSetId (int - nullable)
规则集表定义如下:

- RuleSet
  - RuleSetId (int)
  - RuleId (int)
- Rule
  - RuleId (int)
  - ...
- RuleSet
  - RuleSetId (int)
  - RuleId (int)
- Rule
  - RuleId (int)
  - ...
- RuleSet
  - RuleSetId (pk - int)
  - GroupID (fk - int)
  - RuleId (fk - int)
- Rule
  - RuleId (pk - int)
  - ...
规则表定义如下:

- RuleSet
  - RuleSetId (int)
  - RuleId (int)
- Rule
  - RuleId (int)
  - ...
- RuleSet
  - RuleSetId (int)
  - RuleId (int)
- Rule
  - RuleId (int)
  - ...
- RuleSet
  - RuleSetId (pk - int)
  - GroupID (fk - int)
  - RuleId (fk - int)
- Rule
  - RuleId (pk - int)
  - ...
当我尝试使用RuleSet表中的RuleSetId将FK添加到Groups_Items表中的RuleSetId时,会出现一个错误,告诉我不允许

每个项目必须关联到一个组,一个组可以有多个项目,但我想提供一个选项,允许一个或多个规则通过规则集关联到一个项目。请注意,我不想将规则集直接关联到项目本身,而是关联到与组关联的项目,因为项目可能是相同的,但关联到不同的组,并且根据项目所属的组,可能会应用不同的规则集

我希望这是有道理的

我正在努力让它工作,所以我必须设计这个错误,但我不知道如何最好地接近这一点

更新-1

这是我试图实现的目标的示意图。请注意,我同时添加了RuleSet表,它只包含一个主键,即RuleSetId

- Groups_Items
  - GroupId (pk - int)
  - ItemId (pk - int)
  - RuleSetId (int - nullable)

当我尝试在GroupsItems表和RuleSet表之间添加关系时,出现以下错误:

The ALTER TABLE statement conflicted with the FOREIGN KEY constraint 
"FK_GroupsItems.ERuleSet". The conflict occurred in database 
"MyDatabase", table "dbo.RuleSet", column 'RuleSetId'.
当我尝试在RuleSet表和RuleSetRules表之间添加关系时,会出现以下错误:

Unable to create relationship 'FK_RuleSetsRules.RuleSet'.
The ALTER TABLE statement conflicted with the FOREIGN KEY constraint 
"FK_RuleSetsRules.RuleSet". The conflict occurred in database "MyDatabase", 
table "dbo.RuleSet", column 'RuleSetId.

更新:请注意,在这个答案中,我更改了“规则集”表的含义。在这个答案中,Ruleset表创建每个规则集(但不是规则)。RulesetID是一个int和PK。然后,规则在规则集\规则中链接到此规则集


我认为规则集表还需要有外键引用的主键。我建议Ruleset和Rules还可以获得一个多对多表来链接它们(如果您想重用规则),或者将RulesetID作为规则中的一个字段。此示例具有多对多的功能:

CREATE TABLE Grp (GroupID int PRIMARY KEY)
CREATE TABLE Item (ItemID int PRIMARY KEY)

CREATE TABLE RuleSet(RulesetID int PRIMARY KEY)
CREATE TABLE Rules(RuleID int PRIMARY KEY)
GO

CREATE TABLE RuleSet_Rules (RulesetID int, RuleID int, PRIMARY KEY (RulesetID, RuleID))
CREATE TABLE Grp_Item (GroupID int, ItemID int, RuleSetID int, PRIMARY KEY (GroupId, ItemId))
GO

ALTER TABLE [dbo].[Grp_Item] ADD CONSTRAINT [FK_Grp_Item_Grp] FOREIGN KEY([GroupID]) REFERENCES [dbo].[Grp] ([GroupID])
GO
ALTER TABLE [dbo].[Grp_Item] ADD CONSTRAINT [FK_Grp_Item_Item] FOREIGN KEY([ItemID]) REFERENCES [dbo].[Item] ([ItemID])
GO
ALTER TABLE [dbo].[Grp_Item] ADD CONSTRAINT [FK_Grp_Item_Ruleset] FOREIGN KEY([RulesetID]) REFERENCES [dbo].[RuleSet] ([RulesetID])
GO
下面是一个包含设置和示例插入的示例

更新:下面是一个评论。这有更多的FK,也解释了一些插入故意失败

注意:这假设组/项的每个组合可以分配0或1个规则集。如果需要有多个规则集,Grp_项的多对多表中的规则集会变得稍微复杂一些

还要注意的是,我并没有创建所有的FK,只是与Grp_项中当前问题相关的FK

规则集表定义如下:

- RuleSet
  - RuleSetId (int)
  - RuleId (int)
- Rule
  - RuleId (int)
  - ...
- RuleSet
  - RuleSetId (int)
  - RuleId (int)
- Rule
  - RuleId (int)
  - ...
- RuleSet
  - RuleSetId (pk - int)
  - GroupID (fk - int)
  - RuleId (fk - int)
- Rule
  - RuleId (pk - int)
  - ...
规则表定义如下:

- RuleSet
  - RuleSetId (int)
  - RuleId (int)
- Rule
  - RuleId (int)
  - ...
- RuleSet
  - RuleSetId (int)
  - RuleId (int)
- Rule
  - RuleId (int)
  - ...
- RuleSet
  - RuleSetId (pk - int)
  - GroupID (fk - int)
  - RuleId (fk - int)
- Rule
  - RuleId (pk - int)
  - ...
当我尝试使用RuleSet表中的RuleSetId将FK添加到 Groups_Items表中的RuleSetId,它给了我一个错误 告诉我我不被允许

请注意,我不想将规则集直接关联到该项 它本身,但与组关联的项关联,因为该项可能是 相同但与不同的组和一组不同的 根据项目所属的组,规则可能适用

通过将RuleSetId添加到Groups_Items表中,规则集和项之间存在显式关联,这是您不希望看到的。目前,RuleSet表只包含主键和RuleId,缺少GroupId。我想你在找这样的东西:

规则集表定义如下:

- RuleSet
  - RuleSetId (int)
  - RuleId (int)
- Rule
  - RuleId (int)
  - ...
- RuleSet
  - RuleSetId (int)
  - RuleId (int)
- Rule
  - RuleId (int)
  - ...
- RuleSet
  - RuleSetId (pk - int)
  - GroupID (fk - int)
  - RuleId (fk - int)
- Rule
  - RuleId (pk - int)
  - ...
规则表定义如下:

- RuleSet
  - RuleSetId (int)
  - RuleId (int)
- Rule
  - RuleId (int)
  - ...
- RuleSet
  - RuleSetId (int)
  - RuleId (int)
- Rule
  - RuleId (int)
  - ...
- RuleSet
  - RuleSetId (pk - int)
  - GroupID (fk - int)
  - RuleId (fk - int)
- Rule
  - RuleId (pk - int)
  - ...

现在规则集表包含GroupId和RuleId之间的关系,因此没有理由将规则集id添加到Groups\u Items表中。

最简单的方法是从头开始。使用编辑器创建DDL(模式)

--规则RUL存在。
--
规则{RUL}
PK{RUL}
--规则集RST存在。
--
rset{RST}
PK{RST}
--规则RUL是规则集RST的成员。
--
规则集{RST,RUL}
PK{RST,RUL}
FK1{RST}引用rset{RST}
FK2{RUL}引用规则{RUL}
--项目ITM存在。
--
项目{ITM}
PK{ITM}
--组GRP存在。
--
组{GRP}
PK{GRP}
——ITM项目是GRP组的成员。
--
项目组{GRP,ITM}
PK{GRP,ITM}
FK1{ITM}引用项{ITM}
FK2{GRP}引用组{GRP}
--规则集RST适用于GRP组中的ITM项。
--
项目组{GRP,ITM,RST}
PK{GRP,ITM}
FK1{GRP,ITM}引用项目组{GRP,ITM}
FK2{RST}引用rset{RST}
注:

所有属性(列)不为空
PK=主键
FK=外键

我理解您的意思,但您的建议不会使规则集仅与组关联,而不是与我需要的组和项目关联。例如,我可以有两个组,即Private&Public和一个名为“first name”的项目,我想在其上应用min len,但“first name”需要5个字符,而Public可能需要7个字符。我可以有第三个名为Personal的组,它也使用“名字”,不需要应用任何规则。这有意义吗?我确实这样做了,刚刚发现了您的回复,即引入了一个规则集表,该表只有一个规则集ID,但由于某种原因,如果我试图在它和规则集\规则或组\项表之间添加关系,则该表失败。我会在一秒钟内尝试你的脚本,而不是数据库图,看看我是怎么做的。我添加了一个图,突出显示了我要实现的目标。请注意,我已经运行了您的dbfiddle,并且得到了一个错误。“Msg 547级别16状态0第2行INSERT语句与外键约束“FK_Grp_Item_Ruleset”冲突。冲突发生在数据库“fiddle_86fe7f407ef641139e4a0af2508ff927”、表“dbo.Ruleset”、列“RulesetID”中。Msg 3621级别0状态。”