Гармонизировать protobuf-net bcl.Guid's HI / LO с уникальными идентификаторами sql для коррелированных подзапросов? - PullRequest
1 голос
/ 30 июня 2011

Существует ли какой-либо стандартный / стандартный способ преобразования уникальных идентификаторов SQL в те же блоки HI / LO, что и BCL.Guids протокола protobuf-net?

ОБНОВЛЕНИЕ:

Итакс учетом Guid, "4D1CE8BE-C36B-4FFA-A4C8-9056619E9967", ProtoBuf.NET будет сериализовать его как {"lo":5763133538796628158,"hi":7465171998244653220,"___error___":null}, что впоследствии будет сохранено в Hadoop.Таким образом, SQL-сервер имеет столбец с идентификатором Guid, и Hadoop в итоге получает отдельные значения id.lo и id.hi.Мне нужен запрос для поиска записи в Hadoop по идентификатору с сервера SQL.Приведенный ниже код C # дает мне переведенное значение, которое мне нужно, но требует, чтобы я запустил приложение промежуточного клиента, просто чтобы разделить Guid.Что я хочу, чтобы можно было получить id.lo и id.hi непосредственно из SQL-запроса, чтобы я мог перетащить их прямо в фильтр в следующем задании Hadoop Map-Reduce:

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]);
        }

ОРИГИНАЛЬНЫЙ ВОПРОС:

У меня есть тонна данных в SQL Server, которые мне нужно присоединить к данным, которые были экспортированы в Hadoop через protobuf-net.У нас общие ключи, но все они уникальные идентификаторы.Используя однородно отформатированные ключи, мы могли бы просто извлечь плоский файл из SQL, создать табличную ссылку поверх этого плоского файла в Hive, а затем использовать Hive для запуска объединенного запроса над этим и таблицами hadoop.Однако при наличии разнородных форматов uuid это кажется невозможным.

Нужен ли нам промежуточный процесс для согласования форматов uuid?Я надеюсь, что есть способ обойти это, то есть сделать это больше как простой процесс ETL.В конечном счете, мы просто хотим получить набор данных hadoop, в котором some_id (список идентификаторов sql).Данные Hadoop имеют неуправляемый размер, если извлекаются без фильтрации до соответствующих идентификаторов из sql.

Самый простой пример, который я могу придумать, чтобы описать то, что я пытаюсь сделать, это представить, что у меня есть две таблицыв SQL-сервере «a» и «b», где «a» содержал несколько полей uuid, а «b» был копией «a», за исключением того, что теперь uuids были 64-битными целыми числами, HI / LO, из protobuf-net's bcl.guid.Учитывая этот сценарий, я хочу выбрать * из 'b', где someid в (выберите someid из 'a', где интересно = истина).Чего мне не хватает, так это функции, позволяющей получить HI и / или LO для someid из 'a', чтобы предоставить предложение in для моего запроса из 'b'.

1 Ответ

2 голосов
/ 14 июня 2012

Преобразование в SQL из столбца SQL uniqueidentifier в те же hi / lo значения, сгенерированные protobuf-net:

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

Обратите внимание, что вы, вероятно, можете где-то заключить это в UDF...

...