gpt4 book ai didi

c# - 如何在Azure表存储中使用整数RowKey?

转载 作者:太空狗 更新时间:2023-10-29 22:55:04 24 4
gpt4 key购买 nike

我希望通过 Azure 表服务保留连续编号的实体,但 RowKey 列的类型有问题。实体的编号应该存储在 RowKey 列中,这样我就可以快速查询实体( PK = '..' && RowKey = 5 )、获取最新实体( RowKey > 10 )以及查询某个实体集( RowKey > 5 && RowKey < 10 )。

由于 RowKey 必须是字符串,因此小于比较会出现问题 ( "100" < "11" )。我考虑过在数字前面添加零(这样 "100" > "011" ),但我无法预测实体的数量(以及零的数量)。

我知道我可以创建一个整数列,但我会失去索引 RowKey 列的性能优势(加上我没有任何其他适合 RowKey 的信息)。以前有人遇到过这个问题吗?

最佳答案

我遇到了类似的问题,但需要注意的是,我还想支持 RowKey 按降序排序。就我而言,我并不关心支持数万亿个可能的值,因为我正确地使用了 PartitionKey,并且在需要进一步分段 RowKey 时还使用了范围前缀(例如“scope-id”->“12-8374”)。

最终我确定了 enzi 建议的一般方法的具体实现。我使用了 Base64 编码的修改版本,生成了一个四个字符的字符串,它支持超过 1600 万个值,并且可以按升序或降序排序。这是代码,它已经过单元测试,但缺乏范围检查/验证。

/// <summary>
/// Gets the four character string representation of the specified integer id.
/// </summary>
/// <param name="number">The number to convert</param>
/// <param name="ascending">Indicates whether the encoded number will be sorted ascending or descending</param>
/// <returns>The encoded string representation of the number</returns>
public static string NumberToId(int number, bool ascending = true)
{
if (!ascending)
number = 16777215 - number;

return new string(new[] {
SixBitToChar((byte)((number & 16515072) >> 18)),
SixBitToChar((byte)((number & 258048) >> 12)),
SixBitToChar((byte)((number & 4032) >> 6)),
SixBitToChar((byte)(number & 63)) });
}

/// <summary>
/// Gets the numeric identifier represented by the encoded string.
/// </summary>
/// <param name="id">The encoded string to convert</param>
/// <param name="ascending">Indicates whether the encoded number is sorted ascending or descending</param>
/// <returns>The decoded integer id</returns>
public static int IdToNumber(string id, bool ascending = true)
{
var number = ((int)CharToSixBit(id[0]) << 18) | ((int)CharToSixBit(id[1]) << 12) | ((int)CharToSixBit(id[2]) << 6) | (int)CharToSixBit(id[3]);

return ascending ? number : -1 * (number - 16777215);
}

/// <summary>
/// Converts the specified byte (representing 6 bits) to the correct character representation.
/// </summary>
/// <param name="b">The bits to convert</param>
/// <returns>The encoded character value</returns>
[MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
static char SixBitToChar(byte b)
{
if (b == 0)
return '!';
if (b == 1)
return '$';
if (b < 12)
return (char)((int)b - 2 + (int)'0');
if (b < 38)
return (char)((int)b - 12 + (int)'A');
return (char)((int)b - 38 + (int)'a');
}

/// <summary>
/// Coverts the specified encoded character into the corresponding bit representation.
/// </summary>
/// <param name="c">The encoded character to convert</param>
/// <returns>The bit representation of the character</returns>
[MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
static byte CharToSixBit(char c)
{
if (c == '!')
return 0;
if (c == '$')
return 1;
if (c <= '9')
return (byte)((int)c - (int)'0' + 2);
if (c <= 'Z')
return (byte)((int)c - (int)'A' + 12);
return (byte)((int)c - (int)'a' + 38);
}

您可以将 false 传递给升序参数,以确保编码值按相反方向排序。我选了!和 $ 来完成 Base64 集,因为它们对于 RowKey 值有效。该算法可以轻松修改以支持其他字符,但我坚信较大的数字对于 RowKey 值没有意义,因为表存储键必须有效分段。以下是一些输出示例:

0 -> !!!!升序和 zzzz 降序

1000 -> !!Dc 升序和 zzkL 降序

2000 -> !!TE 升序和 zzUj 降序

3000 -> !!是 asc & zzF5 desc

4000 -> !!yU 升序 & zz$T 降序

5000 -> !$C6 asc & zylr desc

6000 -> !$Rk 升序和 zyWD 降序

7000 -> !$hM asc & zyGb desc

8000 -> !$x!升序和 zy0z 降序

9000 -> !0Ac 升序 & zxnL 降序

关于c# - 如何在Azure表存储中使用整数RowKey?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5218739/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com