Sql 关系和代理键将阻止DBMS直接强制执行(您必须编写自定义触发器) PRODUCT.PUBLIC的使用-您必须在客户端代码中将此字段视为“魔术”。另一种方法是简单地用所有可能的组合填充用户组产品,但这种方法在添加新用户的情况下是脆弱的-除非您也更新用户组产品

Sql 关系和代理键将阻止DBMS直接强制执行(您必须编写自定义触发器) PRODUCT.PUBLIC的使用-您必须在客户端代码中将此字段视为“魔术”。另一种方法是简单地用所有可能的组合填充用户组产品,但这种方法在添加新用户的情况下是脆弱的-除非您也更新用户组产品,sql,database-design,user-permissions,Sql,Database Design,User Permissions,关系和代理键将阻止DBMS直接强制执行(您必须编写自定义触发器) PRODUCT.PUBLIC的使用-您必须在客户端代码中将此字段视为“魔术”。另一种方法是简单地用所有可能的组合填充用户组产品,但这种方法在添加新用户的情况下是脆弱的-除非您也更新用户组产品,否则它不会自动看到产品,但是如果您没有诸如PRODUCT.PUBLIC之类的字段,您如何知道您需要更新它?因此,如果您无法避免PRODUCT.PUBLIC,为什么不特别对待它并在数据库中保存一些存储空间呢 它是一个项目的属性,所以在项目中添加

关系和代理键将阻止DBMS直接强制执行(您必须编写自定义触发器)
  • PRODUCT.PUBLIC的使用-您必须在客户端代码中将此字段视为“魔术”。另一种方法是简单地用所有可能的组合填充用户组产品,但这种方法在添加新用户的情况下是脆弱的-除非您也更新用户组产品,否则它不会自动看到产品,但是如果您没有诸如PRODUCT.PUBLIC之类的字段,您如何知道您需要更新它?因此,如果您无法避免PRODUCT.PUBLIC,为什么不特别对待它并在数据库中保存一些存储空间呢

  • 它是一个项目的属性,所以在项目中添加一个bit/bool列
    AnyGroup
    。在查询中使用该字段可将该项包含在所有组中。是的,将“所有组”扩展到具体的组列表以单独添加组是不允许的。但至少在界面上,现在我必须检查实体是否有“IsVisibleToAllGroups”字段,以确定是否显示复选框(或类似选项)。这意味着更复杂的界面渲染。@poop-deck-如果您需要这样的功能,那么无论发生什么情况,界面都不需要更新来适应它吗?例如,我的答案中有一种替代方法,它采用不同的观点(从您编写的查询的角度),但即使这样,您也需要一种方法来更新实体是否对所有组可见。(简言之,您如何设想避免对UI进行这样的更改?)使用MySQL,但可能会弄虚作假。您添加的内容很有趣:)像@Dems suggestion一样使用我一直倾向的“全球”组。额外组的一点是,该接口可以显示相同的组列表而不做任何更改(除了可能将全局组排序到顶部,或者如果需要,在选择全局组时取消所有其他组的选择)@poop deck-MySQL不支持递归分层查询。分层方法的优点是,您不必担心显式地将用户添加到全局组(尽管您确实需要确保为新组设置父组)但是考虑到MySQL缺乏支持,您需要一个自连接而不是递归查询,并且您无法处理任意层次结构深度。3,4,5中的组维护是否可以通过添加组和实体之间的连接条件来执行,以扩展任何用户组以加入全局实体,并通过处理重复来执行我想我知道你的意思<代码>组链接实体上的内部联接组链接实体。组链接id=用户链接实体。组链接id或组链接实体。组链接id=全局组id。这确实是可能的,但有几个直接的含义:如果用户是10个组的成员,那么所有组实体都将与用户关联10倍,从而增加重复数据消除工作负载。a.id=b.id或b.id=0上的
    等谓词往往会显著影响性能。这种行为混合在表中的数据和代码中的角落案例之间——这是一场维护噩梦。是的,这正是我所想的:)我不认为一个更大的谓词会不公平地影响性能,但我准备相信你的话。而重复数据消除将花费大量成本。至于逻辑/行为,是的,特殊情况是在SQL中,通过直接检查数据(连接到名为“global”的组可能会给出提示,可能是以所有组都可以看到的方式),但任何一种方式都只能在阅读代码后才能理解完整的行为。我需要“附加逻辑”来处理这个新列也没有?但不检查标志和加入额外的表,只加入额外的表。这减少了查询中混乱逻辑的数量。啊,好的,那会更好。这是否意味着每个项目只链接到一个组?这取决于您的要求。如果您可以接受”一个项目只属于一个授权组”,并且“一个用户只属于一个授权组”“,你回来了。如果您的数据需要多对多关系,那么它会变得更加困难。我不知道你的数据。是的,一个项目可以被分配组。另外一个产品领域是否与martin之前提出的产品领域及其特殊处理类似?而
    user\u group\u product
    关系本质上不是DEM提出的查询中的最终联接?“我不确定我是否会有这样一种关系,比如一个表,或者一个视图。@在你的问题中,你说:“如果用户在指定的组中,他们可以看到该项。”。我的理解是,似乎用户能够但不需要看到它。如果您需要这种粒度,那么您需要用户组产品是一个真正的表,而不是一个视图。如果没有,那么这可能是一个视图。顺便说一句,是的,私有外观与Martin建议的相当。哇,“可以但不需要”将是非常精细的,但用户可能会选择他们希望定期查看的项目(作为所有允许查看的项目的子集)。如果是这样,那么似乎需要一张桌子。谢谢。
    GroupId     ParentGroupId Name
    ----------- ------------- ----------
    0           NULL          Base Group
    1           0             Group 1
    2           0             Group 2
    
    WITH GroupsForUser
         AS (SELECT G.GroupId,
                    G.ParentGroupId
             FROM   UserGroups UG
                    JOIN Groups G
                      ON G.GroupId = UG.GroupId
             WHERE  UserId = @UserId
             UNION ALL
             SELECT G.GroupId,
                    G.ParentGroupId
             FROM   Groups G
                    JOIN GroupsForUser GU
                      ON G.GroupId = GU.ParentGroupId)
    SELECT IG.ItemId
    FROM   GroupsForUser GU
           JOIN ItemGroups IG
             ON IG.GroupId = GU.GroupId  
    
    SELECT DISTINCT -- If both user and entity relate to multiple groups, de-dupe them
      entity.*
    FROM
      user
    INNER JOIN
      user_link_group
        ON user.id = user_link_group.user_id
    INNER JOIN
      group_link_entity
        ON group_link_entity.group_id = user_link_group.group_id
    INNER JOIN
      entity
        ON entity.id = group_link_entity.entity_id
    WHERE
      user.id = @user_id
    
    <ORIGINAL QUERY>
    
    UNION       -- Not UNION ALL, as the next query may duplicate results from above
    
    SELECT
      entity.*
    FROM
      entity
    WHERE
      EXISTS (SELECT * FROM user_link_group WHERE user_id = @user_id)
      AND isVisibleToAllGroups != 0
    
    -- NOTE: This also implies the need for an additional index on [isVisibleToAllGroups]