0

我正在使用 ASP.NET C# 和 MySQL 构建自己的分片解决方案。对于每一行的 Id,我使用以下内容:

  • 分片 ID - 整数 (1-65535)
  • 表类型 ID - Small Int (1-65535)
  • 递增编号 (1 - 4294967295)

例如,一个 ID 应该在 url 中,如下所示:

http://mywebsite.com/folders/65535655354294967297

我想知道的是如何将这些数字组合成一个大数字,以便稍后提取数据。例如,我不会使用 1 作为分片 ID,我可能需要你 00001 因为稍后通过对整数进行除法来提取该数字会更容易。

那么我该怎么做呢,用三个单独的数值构建一个长数字然后能够在代码中提取它们的最佳方法是什么?

我在 C# 中寻找最有效的方法

谢谢。

4

4 回答 4

2

你几乎描述了你的问题的答案。为每个数字定义一个固定宽度。

int iShardId = 12; // Fixed width of 5
int iTableTypeId = 840; // Fixed width of 5
long lIncremental = 967295; // Fixed width of 10

string sMyId = String.Concat(iShardId.ToString("00000"), iTableTypeId.ToString("00000"), lIncremental.ToString("0000000000"));

然后,您可以稍后(通过 iHttpModule 或其他)使用 RegEx 解析字符串:

RegEx rMyText = new RegEx(@"/(?<shard>[0-9]{5})(?<table>[0-9]{5})(?<inc>[0-9]{10})/?$");
Match mMyValues = rMyText.Match(Request.Url.AbsolutePath);

if (mMyValues.Success) {
    int iShardId = Convert.ToInt32(mMyValues["shard"].Value);
    int iTableTypeId = Convert.ToInt32(mMyValues["table"].Value);
    long lIncremental = Convert.ToInt64(mMyValues["inc"].Value);
}
else {
    //The input didn't match
}

RegEx 旨在作为解析数字的示例,但显然取决于您计划如何实施,您应该调整它以确保输入限制为您期望的值,方法是使用开始/终止斜杠或字符串结尾($)。

于 2012-11-09T09:43:32.397 回答
1

您可以使用数字的十六进制表示

ushort ShardId=1;
ushort TableTypeId = 100;
uint IncrementalNumber = 1000;

string url = ShardId.ToString("X4") + TableTypeId.ToString("X4")
                                    + IncrementalNumber.ToString("X8");

var i1 = Convert.ToUInt16(url.Substring(0, 4), 16);
var i2 = Convert.ToUInt16(url.Substring(4, 4), 16);
var i3 = Convert.ToUInt32(url.Substring(8, 8), 16);

或者

string url = (((ulong)ShardId << 48) | ((ulong)TableTypeId << 32) | IncrementalNumber)
             .ToString("X16");

var u  = Convert.ToUInt64(url,16);
var i1 = (ushort)(u >> 48);
var i2 = (ushort)((u >> 32) & 0xffff);
var i3 = (uint)(u & 0xffffffff);
于 2012-11-09T10:31:24.370 回答
1

一种解决方案可能是使用二进制数并将它们附加在一起以形成一个数字。

  • 分片 ID - 整数 (1-65535)
  • 表类型 ID - Small Int (1-65535)
  • 递增编号 (1 - 4294967295)

Shard Id 和 Table Id 都需要 16 bit,Incremental number 需要 16 bit。这意味着您可以用 64 位表示数据。

例子:

分片 ID

十二月:7

斌:0000 0000 0000 0111

表类型 ID

十二月:2435

斌:0000 1001 1000 0011

增量数

十二月:23456457

斌:0001 0110 0101 1110 1010 1100 1001

最终编号

连接二进制值,如

分片id + 表类型id + 增量数

仓:0000 0000 0000 0111 0000 1001 1000 0011 0000 0001 0110 0101 1110 1010 1100 1001

12月:1980783105796809

于 2012-11-09T10:01:53.837 回答
0

几个选项,大致从最长(最可读?)到最短(最不可读)

  • 用零填充每个数字,直到它可能是最长的 ( 00001000010000000001)
  • 用连字符或斜杠(1-1-11/1/1)分隔数字
  • 将你的两个ushorts 和组合uint成 aulong并将放在URL 中
  • 将这八个字节组合成一个数组,Base64编码并放入URL

我会选择第二个——它可能在大多数情况下都是最短的,并且是最易读的。

于 2012-11-09T09:45:15.433 回答