2011-06-29 3 views
1

SQL uniqueidentifierをprotobuf-netのBCL.Guidsと同じHI/LOブロックに変換する標準的な方法はありますか?相関サブクエリのためにsql uniqueidentifiersを使用してprotobuf-net bcl.GuidのHI/LOをハーモナイズしますか?

UPDATE:

ので、GUID、"4D1CE8BE-C36B-4FFA-A4C8-9056619E9967"与えられ、ProtoBuf.NETは、それがその後のHadoopに保存されている取得する方法である、{"lo":5763133538796628158,"hi":7465171998244653220,"___error___":null}としてそれをシリアル化します。したがって、SQLサーバにはGuid IDを持つカラムがあり、Hadoopは別のid.lo値とid.hi値を持つことになります。私が必要とするのは、SQLサーバからIDを与えられたHadoopでレコードを検索するクエリです。以下のC#コードは翻訳後の値を示していますが、単にGuidを分割するために中間のクライアントアプリケーションを実行する必要があります。私はSQLクエリから直接id.loとid.hiを取得するので、私は、その後のHadoopの地図-削減の仕事にまっすぐフィルタにそれらをドロップすることができますことができるようにしたい:

static void TestGuidSplit() { 
      // Protobuf.Net serializes the following Guid as: 
      // {"lo":5763133538796628158,"hi":7465171998244653220,"___error___":null} 
      Guid testGuid = new Guid("4D1CE8BE-C36B-4FFA-A4C8-9056619E9967"); 
      Tuple<long, long> loHi = LoHi(testGuid); 
      Console.WriteLine("lo: {0}, Hi:{1}.", loHi.Item1,loHi.Item2); 
      Console.ReadLine(); 
     } 
     static Tuple<long, long> LoHi(Guid someGuid) { 
      byte[] bytes = someGuid.ToByteArray(); 
      long[] longs = new long[2]; 
      longs[0] = BitConverter.ToInt64(bytes, 0); // [0] = 5763133538796628158 = lo 
      longs[1] = BitConverter.ToInt64(bytes, 8); // [1] = 7465171998244653220 = hi 
      return new Tuple<long, long>(longs[0], longs[1]); 
     } 

オリジナルの質問:

私は、protobuf-net経由でHadoopにエクスポートされたデータに参加するために必要なSQL Serverのデータが大量にあります。鍵は共通していますが、すべて固有の識別子です。均質フォーマットのキーでは、SQLからフラットファイルを抽出し、そのフラットファイルをHiveで作成し、Hiveを使用して、そのハーフテーブルと結合されたクエリを実行できます。異種のUUIDフォーマットでは、これは可能ではないようです。

uuid形式を調和させるために中間プロセスが必要ですか?私は、これを回避する方法があることを望んでいます。つまり、簡単なETLプロセスのようにすることです。最終的には、some_id in(SQLのリスト)のハープ・データを取得したいだけです。 hadoopデータは、sqlから該当するidまでフィルタリングせずに抽出すると、管理不能なサイズになります。

私がしようとしていることを説明するために考えることができる最も単純な例は、SQLサーバーに2つのテーブル 'a'と 'b'があることを想像することです。 'b'はprotobuf-netのbcl.guidからのuuidsが64ビットの整数、HI/LOだったことを除いて 'a'のコピーです。そのシナリオを考えて、私はどこからどこかで(どこから「a」を選んで「興味深い=真」)「b」から*を選びたいと思う。私が欠けているのは、 'a'からsomeidのHIやLOを取得し、 'b'からのクエリのin節に供給するための関数です。いるProtobufネットによって生成された同じhi/lo値へのSQL uniqueidentifier列からSQLで

+0

...あなたはおそらくどこかUDFとしてこれをラップすることができますあなたがここで解決しようとしている問題のいくつかの種類の例が役に立ちます。また、私はここでprotobuf-netがどんな役割を果たしているのかはよく分かりません... –

+0

こんにちはマーク。 Protubuf-netは、Hadoopへの途中でデータをシリアル化します.Hadoopは、基本的にProtobuf形式で保存されます。 protobufメッセージは、いくつかのGUIDが追加されたIISログエントリに似ています(私たちがSQLで持っているデータの外部キーです)。 guidはbcl.guidとしてシリアル化されています。目標は、IDに基づいてログエントリのサブセットを抽出することです。すべてがSQLサーバーに入っていれば、 'select * from fooid in(select id from foo interesting = 1)'のようなものを見ているだけです。それはもう意味をなさないでしょうか? –

+0

@Paul私はhadoopに非常に精通していません。ただし、フィールドがフィールド1の場合は常に最初に書き込まれるため、バイナリセーフの「開始」演算子にアクセスできるかどうかを確認する必要があります。 –

答えて

2

変換:

declare @guid uniqueidentifier = convert(uniqueidentifier, '4D1CE8BE-C36B-4FFA-A4C8-9056619E9967') 
select @guid as 'guid' -- writes: 4D1CE8BE-C36B-4FFA-A4C8-9056619E9967, to prove it parsed correctly 
declare @blob binary(16) = CONVERT(binary(16), @guid) 
select CAST(SUBSTRING(@blob, 8, 1) + SUBSTRING(@blob, 7, 1) + SUBSTRING(@blob, 6, 1) + SUBSTRING(@blob, 5, 1) + 
     SUBSTRING(@blob, 4, 1) + SUBSTRING(@blob, 3, 1) + SUBSTRING(@blob, 2, 1) + SUBSTRING(@blob, 1, 1) as bigint) as 'lo', 
     CAST(SUBSTRING(@blob, 16, 1) + SUBSTRING(@blob, 15, 1) + SUBSTRING(@blob, 14, 1) + SUBSTRING(@blob, 13, 1) + 
     SUBSTRING(@blob, 12, 1) + SUBSTRING(@blob, 11, 1) + SUBSTRING(@blob, 10, 1) + SUBSTRING(@blob, 9, 1) as bigint) as 'hi' 
     -- writes: 5763133538796628158, 7465171998244653220 

が、私は疑う

+0

ニース!平易でシンプルで純粋なSQL。ありがとう、マーク! –

+0

@Paul私はあなたのためにできるようにTSQLでかなり精通していることを嬉しく思います! –

関連する問題