r_h*_*ney 9 sql-server bit-manipulation
我有一个非常典型的情况.我们有一个名为Users的表,它有一个名为Branches(varchar 1000)的列.
该组织可以拥有1000个分支机构.因此,如果用户有权访问分支1,5和10,则分支字符串将如下所示:
1000100001000000000 ......
(即,根据分支的编号,用户具有分支访问权限的位置为1).请不要建议更好的数据存储选项,这是从遍布各大洲的遗留应用程序中找到的.
现在给出了这个背景(考虑到可以有> 10000个用户),我想搜索有权访问任何一组给定分支的所有用户,例如查找有权访问任何一个分支的所有用户10,65,90或125.
一个简单的解决方案是将所需的分支集(即10,65,90,125)转换为分支字符串(00000010100等),然后使用标量UDF迭代两个分支字符串并在第一次匹配出现时返回true 2个分支字符串有1个,如果在公共位置没有1,则为false.
除此之外,我还可以选择在C#中搜索应用程序.其中一些用户具有特权(大约1000或更多),并且他们的数据在应用程序中缓存,因为它经常被访问.但对于没有特权的其他用户,数据仅在db中.
我在这里有两个问题:1)对于数据库搜索,除了我提到的UDF方法之外,还有更好的方法.2)对于特权用户,在性能方面更好,在应用程序中搜索(进一步可以基于UDF中的分支字符串上的for循环,或者作为2个分支数组上的Linq Intersect运算符,即Linq Intersect在[1,5,9,50,80,200]和[6,90,256,300]等.)数据库搜索会产生更快的结果还是基于应用程序的搜索?
考虑在这两种情况下可能还有其他搜索参数,例如,姓氏以.开头.
我目前的方法是首先在其他参数(如Last name starts with)上为这两种情况过滤db中的行.然后使用标量UDF根据分支过滤此结果集,然后返回结果.
在SQL中执行它,它只比在C#或其他前端中执行它快100倍.
使用内置数字表将长字符串分成多个位置(数字系列最多可达2047).
样本表
create table users (userid int)
insert users select 1 union all select 2
create table permission (userid int, bigstr varchar(1000))
insert permission
select 1, REPLICATE('0', 56) + '1' -- 57th
+ REPLICATE('0', 32) + '1' -- 90th
+ REPLICATE('0', 64) + '1' -- 155th
+ REPLICATE('0', 845)
insert permission
select 2, REPLICATE('0', 66) + '1' -- 67th
+ REPLICATE('0', 98) + '1' -- 166th
+ REPLICATE('0', 657) + '1' -- 824th
+ REPLICATE('0', 176)
Run Code Online (Sandbox Code Playgroud)
示例显示列表的所有匹配权限
select *
from users u
inner join permission p on p.userid=u.userid
inner join master..spt_values v on v.type='p'
and SUBSTRING(p.bigstr,v.number,1) = '1'
and v.number between 1 and LEN(p.bigstr) -- or 1000 if it is always 1000
where v.number in (57,90,824)
Run Code Online (Sandbox Code Playgroud)
要查找有权访问列表中至少一个分支的用户:
select distinct u.userid
from users u
inner join permission p on p.userid=u.userid
inner join master..spt_values v on v.type='p'
and SUBSTRING(p.bigstr,v.number,1) = '1'
and v.number between 1 and LEN(p.bigstr) -- or 1000 if it is always 1000
where v.number in (57,90,824)
Run Code Online (Sandbox Code Playgroud)
等等..
| 归档时间: |
|
| 查看次数: |
10289 次 |
| 最近记录: |