如何处理SQL记录的许多标志
我需要有关如何处理SQL2k8表中相对较大的标志集的建议。
两个问题,请忍受我:)
假设我要存储20个标志,以用于一条记录。
例如:
CanRead = 0x1
CanWrite = 0x2
CanModify = 0x4
...
依此类推,直到最后一个标志2 ^ 20
现在,如果我设置一条记录的以下组合:权限= CanRead |可以写
我可以通过执行WHERE(Permissions&CanRead)= CanRead轻松检查该记录是否具有必需的权限
那个有效。
但是,我还想检索所有可以写入或者修改的记录。
如果我发出WHERE(Permissions&(CanWrite | CanModify))=(CanWrite | CanModify),我显然不会获得权限设置为CanRead |的记录。可以写
换句话说,如何找到与要发送到该过程的掩码中的任何标志匹配的记录?
第二个问题,SQL 2008中的性能如何?创建20位字段实际上会更好吗?
谢谢你的帮助
解决方案
关于什么
WHERE (Permissions & CanWrite) = CanWrite OR (Permissions & CanModify) = CanModify
?
WHERE(权限和CanWrite)= CanWrite
OR(权限和CanModify)= CanModify
我认为
拥有不同的权限模型会更好。
20个标志向我表明需要重新考虑,大多数文件系统可以通过12个基本标志来实现,ACLS可能具有单独的表,该表仅授予许可,或者对对象或者访问器进行分组以允许不同的控制。
我希望选择一个更快,有20个单独的字段,但我也不会添加20个字段来提高性能。
- 更新 -
原始查询写为
WHERE (Permissions & ( CanWrite | CanModify )) > 0
就足够了,但是听起来好像我们在数据库中拥有的是实体可以拥有的一组属性。在这种情况下,唯一明智的方式(以数据库术语而言)是与属性表建立一对多关系。
不,那是行不通的。
我只给手术发一个口罩
类似@filter的东西,在Ci中用@filter = CanModify |可以写
因此,该过程将OR-ed值用作过滤器。
哦,顺便说一句,它不是权限模型,我仅以它为例。
我确实有大约20个唯一标志,我的对象可以拥有。
它不像...那么简单吗?
WHERE (Permissions & ( CanWrite | CanModify )) > 0
...由于将任何"位"设置为1,将导致"&"运算符的值非零。
天已经很晚了,我要回家了,所以我的大脑可能工作效率低下了。
不要那样这就像将CSV字符串保存到备注字段中,并且破坏了数据库的用途。
为每个标志使用布尔值(位)。在此特定示例中,我们将找到可以读取,可以编写或者修改的所有内容:
WHERE CanRead AND (CanWrite OR CanModify)
简单的纯SQL,没有聪明的技巧。我们为每个标志浪费的额外7位不值得头疼。
我假设Permissions列是一个Int。如果是这样,我鼓励我们尝试下面提供的示例代码。这应该使我们清楚地了解该功能的工作方式。
Declare @Temp Table(Permission Int, PermissionType VarChar(20)) Declare @CanRead Int Declare @CanWrite Int Declare @CanModify Int Select @CanRead = 1, @CanWrite = 2, @CanModify = 4 Insert Into @Temp Values(@CanRead | @CanWrite, 'Read,write') Insert Into @Temp Values(@CanRead, 'Read') Insert Into @Temp Values(@CanWrite, 'Write') Insert Into @Temp Values(@CanModify | @CanWrite, 'Modify, write') Insert Into @Temp Values(@CanModify, 'Modify') Select * From @Temp Where Permission & (@CanRead | @CanWrite) > 0 Select * From @Temp Where Permission & (@CanRead | @CanModify) > 0
当我们使用逻辑和时,我们将根据情况适当地设置一个带有1的数字。如果不匹配,则结果将为0。如果匹配1个或者多个条件,则结果将大于0。
让我给你看一个例子。
假设CanRead = 1,CanWrite = 2,CanModify =4. 有效的组合是:
Modify Write Read Permissions ------ ----- ---- ----------- 0 0 0 Nothing 0 0 1 Read 0 1 0 Write 0 1 1 Read, Write 1 0 0 Modify 1 0 1 Modify, Read 1 1 0 Modify, Write 1 1 1 Modify, Write, Read
现在,假设我们要测试"读取"或者"修改"。从应用程序中,我们将传入(CanRead | CanModify)。这将是101(二进制)。
首先,让我们针对仅读取的表中的一行进行测试。
001 (Row from table) & 101 (Permissions to test) ------ 001 (result is greater than 0)
现在,让我们针对仅包含Write的行进行测试。
010 (Row from table) & 101 (Permission to test) ------ 000 (result = 0)
现在,针对具有所有3个权限的行进行测试。
111 (Row from table) & 101 (Permission to test) ------ 101 (result is greater than 0)
希望我们可以看到,如果AND运算的结果的值为= 0,那么没有经过测试的权限适用于该行。如果该值大于0,则至少存在一行。
仅当我们还通过其他键查询时,才执行此操作。
如果要通过标志组合进行查询,请不要执行此操作。对该列的索引通常对我们没有帮助。我们将只能进行表格扫描。