为不太理想的标题道歉;我很难想出一些东西。
三个实体:Products
,Clients
和Client_Product_Authorization
。
Client
可以访问许多Products
。
许多Product
访问Clients
。
Client_Product_Authorization
授权Client
访问Product
。
我们有100,000多个Products
(虚拟商品),管理Client_Product_Authorizations
成为一项非常耗费人力的任务。所以我们Products
是其他Products
的容器。例如:
产品X是产品1至2000的容器。
因此,通过创建Client_Product_Authorization
授予Client
Product
X,我们间接地为客户提供访问1到2000的产品。请注意产品1可能包含在不同的容器产品(所以,是的,它是多对多的自我关系)。
以下是实体级数据模型:
此机制的优点是我们可以更改Product
X(添加或删除其他产品)的组成,并自动调整授权给客户的产品列表Product
X.管理对我们的大型产品基础的授予访问权限是选择一些容器产品。
缺点现在变得更难(在创建SQL语句方面,因为多对多的自我关系)来了解Client
实际上是什么有权查看(如在个别非容器产品中)。如:
产品Z是产品X和产品Y的容器
产品X是产品1到2000的容器
产品Y是产品2001至5000的容器
客户授权给产品Z的实际非容器产品有哪些?
产品1至2000和2001至5000。
我想让客户被授权以某种方式实现的非容器产品列表。这样的问题就像:
是否应允许
Client
ABC查看Product
78?OR
ABC有权查看哪些产品
Client
?
可以通过查询轻松回复。
目标是让软件的工作尝试确定客户端可访问的产品列表的简单机制,而不是要求遍历所有容器产品,他们的子容器产品,等等等。
a)这种情况是否有更好的数据模型?
b)是否有不同的机制来简化这一大型产品的访问授权管理?
c)您如何尽可能简单地获取客户可获得的非容器产品清单?
我很欣赏集体的意见。提前谢谢!
更新:出于商业原因,限制嵌套产品的数量不是一种选择。
答案 0 :(得分:3)
由于您使用的是SQL 2005,因此您应该可以访问公用表表达式(CTE),这使得查找产品子级的递归变得更加容易。您可能希望研究CTE,看看这对您正在做的事情是否足够。
另外,我不记得这个特定情况,我的书副本在家里,但Joe Celko写了very good book on modeling hierarchies and trees in an RDBMS。可能值得研究一下,看看是否有更好的模型。对于其他一些最初看起来不太明显的场景,他有一些相当巧妙的场景,但效率非常高。即使没有直接匹配,他使用的一些技术也可能有用。
您拥有的模型是所谓的邻接列表模型。 Celko还展示了如何使用所谓的嵌套集模型和路径枚举模型来建模层次结构。
嵌套集模型起初可能看起来有点复杂,但实际上它在某种程度上很简单。它的更新成本更高,但与其他任何模型层次结构相比,选择它都非常快。您可以找到它的简短描述here。由于产品可以包含在多个树中,因此您需要根据自己的情况稍微调整一下。
路径枚举模型基本上只使用分隔(或XML)字符串来列出相关行的路径,从树的根开始。然后你使用字符串(或XQuery)函数来查找父项的子项等。据我所知,它只对具有单根的树非常有用,所以我不认为你可以在你的情况下。
答案 1 :(得分:1)
从纯粹的关系角度(以及我个人的观点)来看,你拥有的是最合乎逻辑的代表方式。当然,缺点是SQL不太适合递归。还有其他用于存储树结构的范例(这是RDBMS讨论中一个长期存在的问题),但我不会深入研究它们,因为我们普遍认为它们牺牲了可读性和可维护性,有利于查询的简易性。这可能是你需要的,但我不知道。
由于你正在运行2005,你可以很容易地使用常见的表表达式进行递归(CTE;参见this MSDN article)。否则,您必须将其转换为多步骤过程(存储过程可能是一个很好的选择,因为您可以隐藏调用代码的实现复杂性)或限制您愿意查看的级别数(即,通过为每个级别添加左连接,产品只能嵌套3级深度。