代码之家  ›  专栏  ›  技术社区  ›  cethegeek

产品组-更好的数据模型?新的实施模式?

  •  1
  • cethegeek  · 技术社区  · 15 年前

    为不太理想的头衔道歉;很难想出办法。

    三个实体: Products , Clients Client_Product_Authorization .

    Client 可以访问许多 产品 .

    A Product 被许多人访问 客户 .

    客户产品授权 授权A 顾客 访问一个 产品 .

    我们有10万+ 产品 (虚拟商品)和管理 Client_Product_Authorizations 成为一项非常劳动密集的任务。所以我们有 产品 那是一个装其他东西的容器 产品 . 例子:

    产品X是产品1到2000的容器。

    因此,通过创建 客户产品授权 授予 顾客 这个 产品 X,我们间接地为客户提供访问产品1到2000的服务。请注意,产品1可能包含在不同的容器产品中(因此,是的,它是一种多对多的自我关系)。

    以下是实体级数据模型:

    alt text http://i50.tinypic.com/2zqempf.png

    优势 这种机制是我们可以改变 产品 X(添加或删除其他产品)并自动调整授权客户可使用的产品列表 产品 x.管理对我们大型产品基地的授予访问权是选择几个集装箱产品的问题。

    劣势 现在(在创建SQL语句方面,由于多对多的自我关系)更难知道 顾客 实际授权查看(如单个非集装箱产品)。如:

    产品Z是产品X和产品Y的容器

    产品X是产品1到2000的容器

    产品Y是产品2001至5000的容器

    授权给产品Z的客户可以看到哪些实际的非集装箱产品?

    产品1到2000和2001到5000。

    我想列出一个客户被授权以某种方式实现的非集装箱产品清单。所以问题如下:

    应该 顾客 ABC可以看到 产品 78?

    什么产品 顾客 ABC授权看?

    可以很容易地用查询来响应。

    目标 是使软件的工作试图确定一个客户端可访问的产品列表成为一个简单的机制,而不是要求遍历所有容器产品、其子容器产品等。

    三个问题:

    a)对于这种情况,是否有更好的数据模型?

    b)是否有不同的机制来简化对这一大型产品集的访问授权管理?

    c)您将如何尽可能简单地为客户提供非集装箱产品清单?

    我感谢集体的投入。事先谢谢!


    更新: 出于业务原因,不能选择限制嵌套产品的数量。

    2 回复  |  直到 15 年前
        1
  •  3
  •   Tom H    15 年前

    因为您使用的是SQL 2005,所以应该可以访问公共表表达式(CTE),这使得递归查找产品的子级变得容易得多。你可能想看看CTE,看看这是否足以满足你的要求。

    另外,我不记得这个特定的场景,我的书在家里,但是乔·塞尔科写了一篇 very good book on modeling hierarchies and trees in an RDBMS . 可能值得一看是否有更好的模型。他有一些相当巧妙的场景,用于其他场景,这些场景起初看起来并不明显,但非常有效。即使没有直接的匹配,他使用的一些技术也可能是有用的。

    您所拥有的模型就是所谓的邻接列表模型。Celko还演示了如何使用所谓的嵌套集模型和路径枚举模型对层次结构进行建模。

    嵌套集模型起初看起来有点复杂,但实际上在某种程度上很简单。它的更新成本更高,但从中进行选择与任何其他建模层次结构的方法相比都非常快。你可以找到它的简短描述 here . 因为一个产品可以包含在多个树中,所以您必须对它稍作调整以适应您的情况。

    路径枚举模型基本上只是使用一个带分隔符(或XML)的字符串,从树的根开始列出指向相关行的路径。然后使用string(或xquery)函数来查找父级的子级等。据我所知,它只对具有单个根的树非常有用,所以我认为在您的情况下不能使用它。

        2
  •  1
  •   Adam Robinson    15 年前

    从纯关系的角度(和我个人的角度),你所拥有的是最合乎逻辑的表达方式。当然,缺点是SQL不太适合递归。还有其他一些存储树结构的范例(这在RDBMS讨论中是一个长期存在的问题),但是我不会去研究它们,因为我通常认为它们牺牲了可读性和可维护性,而有利于查询的容易性。这可能是你需要的,但我不知道。

    因为您运行的是2005,所以可以很容易地使用公共表表达式(CTE的;请参见 this MSDN article )。否则,您要么将其转换为一个多步骤过程(存储过程可能是一个很好的候选者,因为您可以从调用代码中隐藏实现的复杂性),要么通过为每个级别添加左联接来限制您愿意查看的级别数(即,产品只能嵌套3个级别深度)。