0

ASP.NET C#とMySQLを使用して独自のシャーディングソリューションを構築しています。各行のIDには、次を使用します。

  • シャードID-Int(1-65535)
  • テーブルタイプID-SmallInt(1-65535)
  • 増分番号(1-4294967295)

したがって、たとえば、IDは次のようにURLに含める必要があります。

http://mywebsite.com/folders/65535655354294967297

私が知りたいのは、後でデータを抽出できるように、数値を組み合わせて大きな数値にする方法です。したがって、たとえば、シャードIDとして1を使用しません。後で整数を除算することでその数を抽出する方が簡単になるため、00001が必要になる可能性があります。

では、どうすればそれを行うことができますか?3つの別々の数値を使用して長い数値を作成し、それらをコードに抽出できるようにするための最良の方法は何ですか?

私は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"));

その後、RegExを使用して(iHttpModuleなどを介して)文字列を解析できます。

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

解決策は、2進数を使用し、それらを足して1つの数値を形成することです。

  • シャードID-Int(1-65535)
  • テーブルタイプID-SmallInt(1-65535)
  • 増分番号(1-4294967295)

シャードIDとテーブルIDはどちらも16ビットを必要とし、インクリメンタル番号は16ビットを必要とします。これは、64ビットでデータを表現できることを意味します。

例:

シャードID

12月:7

ビン:0000 0000 0000 0111

テーブルタイプID

12月:2435

ビン:0000 1001 1000 0011

増分番号

12月: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 に答える
1

数値の16進表現を使用できます

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 に答える
0

おおよそ最長(最も読みやすい?)から最短(最も読みにくい)までのいくつかのオプション

  • 各数値にゼロを可能な限り長く埋めます(00001000010000000001
  • 数字はハイフン、またはスラッシュ(1-1-1または1/1/1)で区切ります
  • 2つのとushortuintaに結合し、それをURLにulong入れます
  • 8バイトを配列に結合し、Base64でエンコードして URLに入れます

私は2番目のものを選びます-それはおそらくほとんどの場合最短であり、最も人間が読める形式です。

于 2012-11-09T09:45:15.433 に答える