Database design 可扩展安全数据模型

Database design 可扩展安全数据模型,database-design,architecture,data-modeling,Database Design,Architecture,Data Modeling,在过去,我会使用以下简单的数据模型在我的应用程序中实现安全性。我会有一个隐式拒绝、显式允许和显式拒绝,后者可以超越前面的一个 我现在面临的问题是,我当前的应用程序需要可扩展到数千万条记录。在上面的数据模型中,对于每个记录,我可能有许多ACL条目。因此,如果我的记录表(acltest_uspaceData)有1000万行,我的acl安全表可能会有更多行 对于我们计划存储的记录量来说,这是一个合适的数据模型吗?如果不是,我可以对该数据模型做些什么以使其具有可扩展性? 我正在使用PostGIS作为数

在过去,我会使用以下简单的数据模型在我的应用程序中实现安全性。我会有一个隐式拒绝、显式允许和显式拒绝,后者可以超越前面的一个

我现在面临的问题是,我当前的应用程序需要可扩展到数千万条记录。在上面的数据模型中,对于每个记录,我可能有许多ACL条目。因此,如果我的记录表(acltest_uspaceData)有1000万行,我的acl安全表可能会有更多行

对于我们计划存储的记录量来说,这是一个合适的数据模型吗?如果不是,我可以对该数据模型做些什么以使其具有可扩展性?

我正在使用PostGIS作为数据库

更新-规则:
  • 这应该意味着,如果有,任何人都无法访问任何东西 没有为该记录建立安全关联
  • 要允许用户或组访问,必须明确允许他们访问 通过一些安全协会记录下来的
  • 要拒绝已通过组成员身份进行访问的人访问, 您必须通过安全关联明确拒绝此人访问该记录

  • 我不是这方面的权威,但我认识的一位为国内最大的CDN提供商之一开发云平台服务的人强烈支持在涉及可伸缩性的情况下使用云平台。我不确定它是否能满足您的ACL要求,但一点研究就能说明问题。

    根据您的安全规则,
    acltest\u role\u ACL.allowed
    看起来是多余的-如果存在角色ACL条目,则可以暗示
    allowed==true
    。当然,除非您确实希望能够“撤销”整个组,而不仅仅是单个用户

    除此之外,您的模型看起来不错,您应该集中精力将其高效地存储在数据库中

    如果您的DBMS支持,最好将ACL存储为:

    • 如果您想有效地回答“给定记录有哪些ACL条目”的问题,那么集群表中PK列的顺序对于用户ACL应该是
      {record\u id,user\u id}
      ,对于角色ACL应该是
      {record\u id,role\u id}
    • 如果您想有效地回答“给定用户或角色有哪些ACL条目”的问题,那么PK列的顺序应该颠倒(即
      {user\u id,record\u id}
      {role\u id,record\u id}
    • 如果你想有效地回答这两个问题,你需要在两个“方向”上建立索引。不幸的是,二次索引在群集表中是昂贵的,所以在这种情况下,您可以考虑使用堆型表和两个普通索引。
    如果您的DBMS支持它,您可以压缩集群索引的前缘(在Oracle下,这称为压缩索引组织表)。这将消除重复ACL产生的一些冗余(从您的评论中:“通常有许多人具有相同的权限”和“有许多行具有相同的权限”)


    另一方面,如果您主要担心存储成本(和/或使用不支持压缩的DBMS),但不要介意增加的复杂性和潜在的性能影响,那么您可以考虑这样的事情:

    由于许多记录共享相同的ACL(根据您的评论),因此此模型将避免大部分重复

    例如,如果N个记录具有相同的5个ACL条目:

    • 旧型号需要N*5个ACL条目
    • 新模型只需要6行+N字段,这在存储方面要便宜得多(6行=5个ACL条目+1个组,字段是:
      acltest\u uspaceData.ACL\u group\u id
    问题是:插入新记录时,如何查找“匹配”ACL组?这个问题大致可以这样解决,但效率不高:

    SELECT *
    FROM acltest_aclGroup
    WHERE
        NOT EXISTS (
            SELECT user_id, allowed
            FROM acltest_users_acl
            MINUS -- Or EXCEPT, depending on the DBMS.
            SELECT user_id, allowed
            FROM <user_acl_tmp>
        )
        AND NOT EXISTS (
            SELECT user_id, allowed
            FROM <user_acl_tmp>
            MINUS
            SELECT user_id, allowed
            FROM acltest_users_acl
        )
        AND NOT EXISTS (
            SELECT role_id
            FROM acltest_role_acl
            MINUS
            SELECT role_id
            FROM <role_acl_tmp>
        )
        AND NOT EXISTS (
            SELECT role_id
            FROM <role_acl_tmp>
            MINUS
            SELECT role_id
            FROM acltest_role_acl
        )
    
    选择*
    来自acltest\U aclGroup
    哪里
    不存在(
    选择允许的用户id
    来自acltest\u用户\u acl
    减——或除,取决于DBMS。
    选择允许的用户id
    从…起
    )
    而且不存在(
    选择允许的用户id
    从…起
    减
    选择允许的用户id
    来自acltest\u用户\u acl
    )
    而且不存在(
    选择角色\u id
    来自acltest\u角色\u acl
    减
    选择角色\u id
    从…起
    )
    而且不存在(
    选择角色\u id
    从…起
    减
    选择角色\u id
    来自acltest\u角色\u acl
    )
    

    首先,您为用户和角色ACL(
    )创建一个临时表,然后将新记录应具有的ACL条目插入其中,然后执行上面的查询,搜索现有ACL组,以查找与临时ACL相等的集合。

    谢谢,但不是我要查找的。我正在寻找一个数据库设计,而不是目录服务。不过还是要谢谢你,“隐性否认”和“显性否认”有什么区别?它是否“协调”角色和用户之间的冲突?如果是,具体规则是什么?我只是想知道这两个
    允许的
    字段是否都是必需的……还有,有很多具有相同权限的记录是常见的吗?@BrankoDimitrijevic谢谢你的评论。隐式拒绝意味着如果记录没有任何安全条目,则任何人都无法访问它们。这意味着,除非您明确允许任何人访问任何内容,否则任何人都无权访问任何内容。然后使用显式拒绝覆盖显式允许。因此,当我想让一个组访问除该组中的一个人之外的记录时,我可以显式允许该组并显式拒绝该成员。@BrankoDimitrijevic至于你的下一个问题,是的,通常有许多人具有相同的权限。实际上,我关于许可的问题