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

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

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

我想到了两种方法,并且很好奇哪种方法对 SQL Server 的性能更好。

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

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

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

想法?

有帮助吗?

解决方案

如果只是允许/拒绝,那么用户和资源之间的简单链接表就可以正常工作。如果链接表中存在针对用户资源的条目,则允许访问。

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)上的聚集索引,即使有数百万条记录,查询也会快得令人眼花缭乱。

其他提示

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

在很多情况下,您希望将用户锁定,但又不想完全销毁他们的帐户。其中一个实例(不一定与您的用例相关)是当您未能付款时,他们会切断您的帐户,直到您再次开始付款。他们不想删除该记录,因为他们仍然希望在您再次付款时启用它,而不是从头开始重新创建帐户并丢失所有用户历史记录。

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

此外,表大小只应考虑到您知道将包含许多记录(如 100,000 条以上)的表。您甚至花时间在这个问题中输入表大小考虑因素,其成本已经超过了它所占用的额外硬盘空间。

方法 A,但除了隐式拒绝之外,我还会包括显式拒绝。我会制作一些用例来确保您的最终逻辑有效,但这里有一些示例。

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 会被允许。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top