构造SQL表以使其匹配或返回无结果更好

时间:2008-08-22 20:28:39

标签: sql sql-server optimization

我有一个有趣的设计问题。我正在设计项目的安全方面,允许我们针对不同的成本使用不同版本的程序,并允许Manager类型的用户向其他用户授予或拒绝访问程序的某些部分。它将基于网络并托管在我们的服务器上。

我正在为每个“资源”或屏幕使用简单的“允许”或“拒绝”选项。

我们将拥有大量资源,用户可以设置许多不同的组来让用户控制访问。每个用户只能属于一个组。

我有两种方法可以考虑到这一点,并且好奇这对于SQL服务器而言在性能方面会更好。

选项A 访问表中存在条目意味着允许访问。这不需要数据库中的列来存储信息。如果没有返回结果,则拒绝访问。

我认为这意味着一个较小的表,但会查询整个表以确定没有匹配?

选项B 数据库中包含一个位列,用于控制允许/拒绝。这意味着总会找到一个结果,并且可以制作更大的表格。

思想?

4 个答案:

答案 0 :(得分:4)

如果它只是允许/拒绝,那么用户和资源之间的简单链接表就可以正常工作。如果在链接表中有一个键入User-Resource的条目,则允许访问。

UserResources
-------------
UserId FK->Users
ResourceId FK->Resources

,sql就像

if exists (select 1 from UserResources 
where UserId = @uid and ResourceId=@rid)
set @allow=1;

使用聚合索引(UserId和ResourceId),即使有数百万条记录,查询也会非常快。

答案 1 :(得分:1)

我会选择选项B.如果你选择选项A并假设如果用户存在,他们可以进入,那么你最终会遇到你想要拒绝访问用户的问题,而不删除用户记录。

在很多情况下,您需要锁定用户,但不希望完全销毁他们的帐户。一个这样的例子(不一定与你的用例有关)就是当你没有付款时,他们会切断你的帐户,直到你再次开始付款为止。他们不想删除记录,因为他们仍然希望在您再次付款时启用它,而不是从头开始重新创建帐户,并丢失所有用户历史记录。

答案 2 :(得分:0)

B中。它可以更好地检查数据是否完整(例如,当您添加允许/可拒绝的功能时)。

此外,表格大小应仅作为您知道将包含许多记录的表格的考虑因素(如100,000+)。您甚至花时间在这个问题中输入表格大小的考虑因素已经超出了它需要的额外硬盘空间。

答案 3 :(得分:0)

方法A,但除了隐式deney之外,我还会包含一个明确的拒绝。我会做一些用例以确保你的结束逻辑有效,但这里有一些例子。

User1 is in group1 and group2.  
User2 is in group1  
User3 is in group2 

Folder1 allows group1 and deny group2.  
User1 is denied.  
User2 is allowed.  
User3 is denied. 

我相信你的方法users1是允许的。