비슷한 문제가 있습니다. RowKey가 내림차순으로 정렬되도록 지원하고 싶다는 경고가 추가되었습니다. 필자는 PartitionKey를 올바로 사용하고 있으며, "scope-id"-> "12-8374"와 같이 RowKey를 더 세분화 할 필요가있을 때 범위 지정 접두사를 사용하기 때문에 가능한 많은 수의 값을 지원하는 데 신경 쓰지 않았습니다.
마지막으로 나는 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
-> !!입니다 오름차순 & zzF5 내림차순
4000 -> !! yU asc &zz $ T desc
5000 ->! $ C6 asc & zylr desc
,451,515,
6000 -> $ Rk를 오름차순 & zyWD 내림차순
7000 -!!!> $의 X -> $ HM 오름차순 & zyGb
8000 DESC! 오름차순 & zy0z 내림차순
9000! -> 0Ac 오름차순 & zxnL 내림차순 코드
포스트 업, 바퀴에게 매력 같은 –