查询表已经彻底失效,不必费心。哈希算法看起来非常适合您的需求。您需要在15,000个唯一字符串之前将关键字拆分,以便为您提供足够的哈希密钥,使其值得努力。
因此,不是:
SET Vancouver:temp:1:Kelowna:high:0 10
您会使用
HSET Vancouver:temp:1 Kelowna:high:0 10
现在第一个 [1 or 0] 后面的所有内容都将成为哈希键,因此每个哈希键将有大约 150,000 种可能性。
我的计算结果与你的总密钥空间略有偏差:
15000 * 5 * 2 * 15000 * 5 * 2 == 22500000000 (22.5 billion)
这样做,您将拥有150,000个可能的键(Redis键),每个键有150,000个可能的哈希键。
在redis键和哈希键之间分割的位置越靠左,哈希键的数字就会更加倾斜。例如,如果您将其分割成如下形式:
HSET Vancouver:temp 1:Kelowna:high:0 10
您可能需要为哈希表创建75,000个Redis键,每个哈希表最多可能包含300,000个键值对。
另一种方法是使用整数作为键。如果您有两组分别由15,000个唯一字符串和5个唯一字符串构成的整数映射,则可以使用34位来表示任何键。例如:
0000000000000 000 0 0000000000000 000 0
| 13 | | 3 | |1| | 13 | | 3 | |1|
13个比特位可以表示0-16383的范围(覆盖所需的1-15000)
3个比特位可以表示0-7的范围(覆盖所需的1-5)
1个比特位可以提供二进制1或0的范围。
假设有以下虚构值:
温哥华 == 9,987
温度 == 3
基洛纳 == 3,454
高度 == 2
你将得到:
(9987 << 21) + (3 << 18) + (1 << 17) + (3454 << 4) + (2 << 1) + (0 << 0)
==
20945229796
要获取给定键的值,您只需进行位移和掩码操作。
20945229796 >> 20
9987
(20945229796 >> 4) & ((1 << 13) - 1)
3454
这是一个简单的Python脚本,可以将值转换为整数,并将整数转换为值:
values = [9987, 3, 1, 3454, 2, 0]
bits = [21, 18, 17, 4, 1, 0]
value_and_shift = zip(values, bits)
def key_from_values(values_and_shift):
return sum(x << y for x, y in value_and_shift)
def extract_values(values_and_shift):
last_shift = 35
for value, shift in value_and_shift:
print "Value should be:", value
print "Value extracted:", (key >> shift) & ((1 << (last_shift - shift)) - 1)
print
last_shift = shift
key = key_from_values(value_and_shift)
print "Using value of:", key
extract_values(value_and_shift)
输出
Using value of: 20945229796
Value should be: 9987
Value extracted: 9987
Value should be: 3
Value extracted: 3
Value should be: 1
Value extracted: 1
Value should be: 3454
Value extracted: 3454
Value should be: 2
Value extracted: 2
Value should be: 0
Value extracted: 0
array(1 => "foo", 2 => "bar", ..., 9987 => "Vancouver")
并拥有一个反向查找表来进行另一种方式的查找。我想我需要更多关于有效值存在的信息。 - sberryK(String) -> V(Integer)
应该可以解决问题,而且由于查找是O(1)
,所以我会坚持使用它。ArrayList查找将是O(N)
,我没有看到任何好处,因为您想将字符串转换为整数,而不是相反。 - sberry