我要在Azure表中存储记录,并使用分区键和/或表示整数值的行键。
由于分区键和行键必须存储为字符串,因此我需要选择一种在字符串和整数之间进行转换的编码方案。
键的范围介于0和2 63 之间,但大多数键的值都很低(通常小于10 6 )。
我正在寻找具有以下属性的编码方案:
字符串的排序顺序必须与相应的整数相同。
为常见(低)值避免使用过长的字符串。
编码必须支持两种模式;为升序排序顺序生成字符串的字符串;并且为降序排序顺序生成字符串。
思路:
只需使用16个十六进制字符对密钥进行编码,然后使用反向字母表来实现降序排序。
虽然这是一种简单直接的方法,但它的缺点是它会为常见(低)值生成过长的字符串。
使用类似于Unicode的7位编码方案为低值生成较小的字符串。
使用Azure似乎在密钥中支持16位Unicode字符的事实。虽然有些字符是reserved和buggy,但我认为应该可以为每个字符存储至少14个有效位,从而可以表示所有只有5个字符的键。
< / LI>有什么建议吗?
答案 0 :(得分:0)
不要这样做(见下文)
我决定支持60位密钥并创建一个每个字符包15位的类就足够了。
通过这种方式,我可以用四个字符存储所有可能的键(0到2 60 - 1)。
为避免与保留字符和错误字符冲突,我决定使用Unicode范围0x4000到0x9fff(Unified CJK Han)和0xb000到0xcfff(东亚脚本)中的字符。
示例:
Integer: String:
0x0 "䀀䀀䀀䀀"
0x123 "䀀䀀䀀䄣"
0x1000 "䀀䀀䀀倀"
0x123456 "䀀䀀䀂捅"
0x100000000 "䀀䀄䀀䀀"
此编码生成以下键:
为什么不应该使用此编码:
虽然我一开始很开心,因为这种编码确实满足了我的所有要求。当我追踪API请求时,我对Azure Table缺乏经验。
由于分区键和行键内置于请求URI中,因此任何使用必须进行百分比编码的字符的编码方案都是错误的编码方案。
这个方案完全基于这样的角色。典型的请求URI看起来像这样:
http://myaccount.table.core.windows.net/MyTable(PartitionKey='',RowKey='%EC%AE%8A%E5%BC%B0%EC%92%BD%E6%B0%AB')
我们可以看到漂亮的四个字符的行键以 37个字符发送!
答案 1 :(得分:0)
这就是我最终要做的事情:
我决定让密钥被标记为64位整数,这样我就可以使用负值按降序排列密钥。
我创建了一个基于Base-64的编码方案,只做了一些修改:
所有64位(8字节)值将编码为12 Base-64字符,最后一个字符将始终为=
填充字符。因此,删除它是安全的。
我需要保留自然(序数)排序顺序,原始的Base-64字母表没有此属性。
原始的Base-64字母表是:A
到Z
,a
到z
,0
到9
,最后是{{ 1}}和+
。
网址友好的Base-64字母表只是将/
替换为+
,将-
替换为/
。
我决定使用这些字符,但重新排列字母表,以便按顺序值排序。
我的字母表是:_
,-
到0
,9
到A
,Z
,_
到a
。
低绝对值使用许多前导z
或A
字符进行编码。我决定将它们打包成一个领先的标志字符,如下所示:
/
<强>实施例强>
'A': Negative value with no leading '/' characters
'B': Negative value with 1 leading '/' character
'C': Negative value with 2 leading '/' characters
...
'K': Negative value with 10 leading '/' characters
'Z': Zero (11 `A` characters)
'a': Positive value with 10 leading 'A' characters
'b': Positive value with 9 leading 'A' characters
...
'j': Positive value with 1 leading 'A' character
'k': Positive value without leading 'A' characters
代码
-9223372036854775807 = "AV----------"
-2147483648 = "Frzzzzw"
-100000 = "HyTKw"
-10000 = "IqDw"
-1020 = "J-B"
-1000 = "J0R"
-100 = "Jtg"
-19 = "Jyk"
-10 = "KJ"
0 = "Z"
10 = "ac"
19 = "b0B"
100 = "b5F"
1000 = "byV"
1020 = "bzk"
10000 = "c8l-"
100000 = "d0We-"
2147483647 = "f6zzzzw"
9223372036854775807 = "kUzzzzzzzzzw"