基本上,任务是查询数据,以隔离哪些用户对项目具有一定的权限范围。
select ssm.user_id,s.scope
from user_available_scope_sets uass
join scope_set_masks ssm
on ssm.user_id = uass.user_id
and ssm.scope_set_id = uass.scope_set_id
join scopes s
on case floor(s.bitmask_index / 64)
when 0 then bucket_0
when 1 then bucket_1
when 2 then bucket_2
when 3 then bucket_3
when 4 then bucket_4
when 5 then bucket_5
else 0
end & (1 << (s.bitmask_index % 64)) != 0
where uass.user_id in (1, 2, 3)发布于 2020-12-28 15:19:15
假设bitmask_index包含两个有效字节,例如:
┌ bit 15 bit 0 ┐
byte 1 byte 0
┌──────┐┌──────┐
0000000011000101
└────────┘└────┘
y xbitmask_index / 64与bitmask_index >> 6相同(将位右移到6位)-在本例中为y,即二进制00000011,十进制3
bitmask_index % 64是掩码,与bitmask_index & 63相同(所有比5高的位都是0)-在本例中是x,即二进制00000101,十进制5
因此,实际上,bitmask_index字段包含两个值。
接下来,1 << (s.bitmask_index % 64) (将1左移到指定值)表示“第x位且仅第x位为1的值”,在我们的示例中是
bit 5 ┐
0000000000100000最后,value1 & value2 != 0的意思是"value1和value2“有共同之处。
显然,bucket_0 - bucket_5是表中的字段(可能是scope_set_masks?)
所有的一切:
根据Check值的不同,get bucket_<n>字段和= 1字段中的第x位
你可以使用PostgreSQL bit string types来操作它
select
'0000000011000101'::bit(16) as "Binary value",
'0000000011000101'::bit(16)::int as "Decimal value",
(197 / 64)::bit(16) as "197 / 64",
(197 >> 6)::bit(16) as "197 >> 6",
(197 % 64)::bit(16) as "197 % 64",
(197 & 63)::bit(16) as "197 & 63",
(1 << 5)::bit(16) as "1 << 5",
(1 << (197 % 64))::bit(16) as "1 << (197 % 64)";
┌─[ RECORD 1 ]────┬──────────────────┐
│ Binary value │ 0000000011000101 │
│ Decimal value │ 197 │
│ 197 / 64 │ 0000000000000011 │
│ 197 >> 6 │ 0000000000000011 │
│ 197 % 64 │ 0000000000000101 │
│ 197 & 63 │ 0000000000000101 │
│ 1 << 5 │ 0000000000100000 │
│ 1 << (197 % 64) │ 0000000000100000 │
└─────────────────┴──────────────────┘https://stackoverflow.com/questions/65472797
复制相似问题