Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/72.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 如何在2个或3个项目之间建立关系模型?_Sql_Database_Database Design_Relational Database - Fatal编程技术网

Sql 如何在2个或3个项目之间建立关系模型?

Sql 如何在2个或3个项目之间建立关系模型?,sql,database,database-design,relational-database,Sql,Database,Database Design,Relational Database,我有3个表:组、规则、操作 我可以在(1组,1规则),(1组,1动作)或(1组,1规则,1动作)之间建立关系 我想我可以创建一个链接表group_rule_action,并将其中一个FK设置为NULL,如果它只是两个项目之间的关系 例如,我在组1和规则a之间有一个关系,我有(1,a,NULL) 问题是,如果我为这个组/规则创建一个操作,我必须更新这个与(1,A,ACTION1)的关系。。。但是如果我以后添加一个新操作,我需要插入(1,a,ACTION2),所以它不是很一致 我还可以在操作和规则上

我有3个表:组、规则、操作

我可以在(1组,1规则),(1组,1动作)或(1组,1规则,1动作)之间建立关系

我想我可以创建一个链接表group_rule_action,并将其中一个FK设置为NULL,如果它只是两个项目之间的关系

例如,我在组1和规则a之间有一个关系,我有(1,a,NULL)

问题是,如果我为这个组/规则创建一个操作,我必须更新这个与(1,A,ACTION1)的关系。。。但是如果我以后添加一个新操作,我需要插入(1,a,ACTION2),所以它不是很一致

我还可以在操作和规则上设置groupId FK,但是当我将操作链接到规则时,我需要确保它们具有相同的groupId(并且最终会有冗余信息)

有更好的主意吗?

正如你所说

我还可以在操作和规则上设置groupId FK

我认为这意味着组和规则以及组和操作都是“一对多”的:一个组可以有许多规则/操作,一个规则/操作只能属于一个组。如果是这样的话,那么一定要为这些关系使用
groupId

现在,要在规则和操作之间建立多对多关系,并限制相关的规则和操作必须属于同一个组,您必须引入一些冗余,特别是复制两个实体所属组的信息

有鉴于此,第三个表,
RulesActions
,可以这样定义:

RuleID
ActionID
GroupID
FOREIGN KEY (RuleID, GroupID)
FOREIGN KEY (ActionID, GroupID)
GroupID
列是冗余位:显然,可以通过查找相应的表来确定
RuleID
ActionID
的组。但是,正如您所看到的,使用单个
GroupID
列作为这两个项目的组引用,从而确保这两个项目具有相同的组。为了确保组ID确实是规则和操作都属于的ID(而不仅仅是任意ID),列包含在两个外键中,即
RulesActions
表引用
Rules
by
(RuleID,GroupID)
,而不仅仅是
RuleID
,对于
操作
也一样

当然,给定这样的FK定义,目标表中相应的主键或唯一约束也需要以相同的方式定义。我之所以说主键或唯一约束,是因为在我使用的产品SQL Server中,允许外键引用定义为主键或应用唯一约束的列。因此,在SQL Server中,我可以这样定义
规则
操作
表:

  • 规则

    RuleID   PRIMARY KEY
    GroupID  FOREIGN KEY
    UNIQUE (RuleID, GroupID)
    
    RuleID   UNIQUE
    GroupID  FOREIGN KEY
    PRIMARY KEY (RuleID, GroupID)
    
  • 操作

    ActionID  PRIMARY KEY
    GroupID   FOREIGN KEY
    UNIQUE (RuleID, GroupID)
    
    ActionID  UNIQUE
    GroupID   FOREIGN KEY
    PRIMARY KEY (RuleID, GroupID)
    
这将允许我在前面指定
RulesActions
模式。我不确定其他许多产品是否允许这样做,如果不允许,您可以尝试以下方法:

  • 规则

    RuleID   PRIMARY KEY
    GroupID  FOREIGN KEY
    UNIQUE (RuleID, GroupID)
    
    RuleID   UNIQUE
    GroupID  FOREIGN KEY
    PRIMARY KEY (RuleID, GroupID)
    
  • 操作

    ActionID  PRIMARY KEY
    GroupID   FOREIGN KEY
    UNIQUE (RuleID, GroupID)
    
    ActionID  UNIQUE
    GroupID   FOREIGN KEY
    PRIMARY KEY (RuleID, GroupID)
    
这样,唯一约束仅应用于(实体)ID列,以确保ID的唯一性,
RulesActions
中外键的目标列集被定义为主键,这样您就有了一个共同的FK PK关系


请注意,如果事实证明您需要多对多的组/规则和/或组/操作关系,那么想法本身将不会有什么变化。对于多对多关系,您需要引入一个映射表,其中
EntityID、GroupID
将是主键,而相应的外键将需要引用该表而不是主实体。有三个表将它们连接起来:(1)组规则,(2)组规则动作,以及(3)组规则动作。与规则关联的组和与操作关联的组之间,以及与规则和操作关联的组之间,可能存在重要的语义差异。您没有说明单个组是否可以仅与一个规则关联,或者单个组是否可以与多个规则关联;团体和行动也是如此;组、规则和操作同上。说明书不完整。但是可选的空字段会使
操作
规则
相关,然后
规则
相关@JonathanLeffler,实际上没有什么重要的语义差异,只是插入顺序不同而已。。。用户必须先创建一个组,然后才能为该组创建规则和操作,然后才能将规则与操作关联(N到N)@EkoDedy,这没有帮助,因为如果没有规则,我无法创建操作(这是一项要求)如果您指定了功能和多值以及其他依赖项,那么您的需求将是明确的。在任何情况下,我认为您都不希望在某些情况下更新表,而在某些情况下插入表。那么,为什么要首先插入一个空的行呢?如果G->R,G->A和GR->A在您的情况下有效,那么有3个表(G,R),(G,A)和(G,R,A),并且仅当GR->A对于一组三个值为true时,才在最后一个表中插入一个元组,以便您以后不需要更新该表。