2012-11-09 5 views
0

ASP.NET C# 및 MySQL을 사용하여 자체 샤딩 솔루션을 구축하고 있습니다. 각 행의 ID를 나는 다음과 같은 사용 : - 지능 (65535) 코드에서 긴 숫자의 세 자리 숫자 추출

  • 표 유형 ID -

    • 파편 이드가 작은 지능 (65535)
    • 증분 번호 (1-4294967295)

    그래서 예를 들어, ID는이 같은 URL에 있어야합니다 :

    http://mywebsite.com/folders/65535655354294967297 
    

    내가 알고 싶은 것은 큰 N에 숫자를 결합하는 방법입니다 umber. 나중에 데이터를 추출 할 수 있습니다. 그래서 예를 들어, 1을 샤드 ID로 사용하지 않을 것입니다. 아마도 나중에 00001을 필요로 할 것입니다. 왜냐하면 나중에 전체 숫자로 나누어서 그 숫자를 추출하기가 쉬울 것이기 때문입니다.

    어떻게 그렇게 할 수 있습니까? 세 개의 별도의 숫자 값으로 긴 숫자를 만든 다음 코드로 다시 추출 할 수있는 가장 좋은 방법은 무엇입니까?

    나는 C#으로

    감사를 할 수있는 가장 효율적인 방법을 찾습니다.

  • +0

    각 URL을 URL의 별도 부분에 넣지 않아도되는 이유가 있습니까? 예 : http://mywebsite.com/folders/65535/65535/4294967297 –

    +0

    네, massy, ​​facebook, pinterest 및 모든 대형 플레이어는 긴 폴더를 사용하지 않으므로 추세를 따라 가며 더 좋아집니다. 내 생각에 –

    답변

    1

    당신은 헥스 represantations를 사용 숫자

    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); 
    
    +0

    흥미 롭습니다. 확인하겠습니다. 성능면에서 효과적입니까? –

    +0

    "00001000020000000015"와 같은 문자열을 얻고 [1, 2, 15]의 배열을 반환하는 함수가 필요합니다 (예 : 1은 샤드 ID, 2는 테이블 유형 ID, 15는 증분). 위의 예제에서 숫자는 볼 수있는 것처럼 10 진수 형식의 문자열에 포함됩니다. –

    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")); 
    
    그런 다음 사용 정규식 (AN 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 
    } 
    

    정규식을하지만, 구현하려면 시작/종료 슬래시 또는 문자열 끝 ($)을 사용하여 입력 값이 원하는 값으로 제한되도록 조정해야합니다.

    +0

    왼쪽으로 이동 비트를 사용하는 솔루션을 보았습니다. 그래서 나는 이것이 이것이 최선의 방법임을 알기 원했으며, 내가 어떤 종류의 문제가 있는지, 내가 모르고있는 것인지를 알고 싶었습니다. –

    +0

    가장 똑똑한 방법입니다. 바이너리 분석을 사용하면 얻을 수있는 모든 효율성은 다음에 작업해야하는 사람을 위해 응용 프로그램을 엄청나게 복잡하게 만듭니다. –

    +0

    나는 여기서주의해야한다.'int' /'long'으로 입력을하면 누군가가 너무 긴 값을 전달할 수 있고 20 자리 이상 있으면'regex'가 실패하지 않습니다. 결과 문자열, 그래서 당신은 다른 가치를 얻을거야. – Rawling

    0

    여러 가지 옵션, 약 (대부분의 읽을?) 긴, 그것은 하이픈 (00001000010000000001)

  • 별도의 숫자가 될 수있는 가장 긴에 제로로 (적어도 읽을 수)

    • 패드 각 숫자를 최단까지 또는 슬래시 (1-1-1 또는 1/1/1)
    • ulong로 두 ushort들과 uint을 결합하고 URL에 것을 을 넣어
    • 가 배열에 8 바이트를 결합, Base64로 URL에

    내가 두 번째로 갈 거라고을 인코딩하고 를 넣어 - 아마 시간의 짧은 대부분이 될 것 대부분의 인간이야 읽을 수있는.

  • 1

    해결책은 이진수를 사용하여 함께 추가하여 하나의 숫자로 만들 수 있습니다.

    • 파편 아이디 - 지능 (65535)
    • 표 유형 ID - 작은 지능 (65535)
    • 증분 번호 (1-4294967295)

    Shard Id와 Table Id는 모두 16 비트를 필요로하고 Incremental number는 16 비트를 필요로합니다. 즉, 데이터를 64 비트로 나타낼 수 있습니다.

    예 :

    파편 이드

    12 월 : 7

    빈 : 0000 0000 0000 0111

    표 유형 ID

    12 월 : 2,435

    ,451,515,

    빈 : 0,000 1,001 1,000 0,011

    증분 번호

    12 월 : 23,456,457

    빈 : 0,001 0,110 0,101 1,110 1,010 1,100 1,001

    CONCAT 연 최종 번호

    이진 값은

    와 같습니다. 15,

    파편 ID + 테이블 형식 ID + 증분 번호

    빈 : 0,000 0,000 0,000 0,111 0,000 1,001 1,000 0,011 0,000 0,001 0,110 0,101 1,110 1,010 1,100 1,001

    12 월 : 1980783105796809

    +0

    이 솔루션은 불필요하게 복잡하며 값을 비 직렬화하면 직렬화 프로세스에서 얻은 성능을 쉽게 보상 할 수 있습니다. –

    +0

    나는 Pinterest가 그들의 해결책으로 비트 이동을 사용했기 때문에 비트 이동이 성능면에서 가장 빠른 것이라고 생각했다. –

    +0

    이것이 10 년 전이거나 귀하의 사이트가 Pinterest만큼 많은 트래픽을 얻고 있다면 나는 고려 가치가있다. –