Mongodb ObjectId генератор как процесс SQL Server - PullRequest
3 голосов
/ 08 декабря 2011

У меня есть гибридное приложение, в котором часть данных (в основном устаревшая) хранится в SQL Server, а другая - в Mongodb.Я просто преобразовал все типы первичных ключей в SQL Server, чтобы использовать ObjectId, который я генерирую в приложении при вставке новых записей в SQL Server.Теперь я обнаружил, что мне нужно клонировать некоторые записи шаблона (около 10-20 записей за раз), и для этого мне нужно иметь возможность генерировать значения ObjectId с помощью функции SQL Server или хранимой процедуры.Возможно ли это и есть ли код?

Ответы [ 2 ]

1 голос
/ 08 декабря 2011

Я думаю, вы можете использовать функцию NEWID , которая генерирует 16-байтовый уникальный идентификатор .

Но в MongoDB BSON ObjectId Datatype является 12-байтовым двоичным значением.

Попробуйте это

SELECT LEFT(REPLACE(CAST(NEWID() as varchar(36)),'-',''),24)

Надеюсь, это поможет.

EDITED

В статье Идентификаторы объектов описана спецификация BSON ObjectID. Формат включает в себя:

  1. TimeStamp. Это метка времени в стиле Unix. Это число со знаком, представляющее количество секунд до или после 1 января 1970 года. (UTC).
  2. машина. Это первые три байта (md5) хэша имени хоста компьютера, или адреса mac / network, или виртуального Идентификатор машины.
  3. Pid. Это 2 байта идентификатора процесса (или идентификатора потока) процесса, генерирующего идентификатор объекта.
  4. Increment. Это постоянно увеличивающееся значение или случайное число, если счетчик не может использоваться в языке / среде выполнения.

Сам сервер и почти все драйверы используют вышеуказанный формат.

Итак, невозможно создать объектный идентификатор MongoDB в SQL Server.

Единственный способ решить эту проблему - изменить логику приложения.

0 голосов
/ 21 мая 2013

Этот вопрос старый, но я пытался сделать то же самое. Это то, что я придумал на SQL Server 2012.

Create Function NewObjectId(@counter binary(3))
returns binary(12)
begin

    declare @epoch datetime2, @seconds binary(4), @process binary(2), @hostname binary(3)
    set @epoch = '1/1/1970'

    select @seconds = cast(Datediff(ss, @epoch, getutcdate()) as binary(4))
    select @hostname = cast(HashBytes('MD5', HOST_NAME()) as binary(3))
    select @process = cast(@@SPID as binary(2))

    declare @objectId binary(12)
    select @objectId = (@seconds + @hostname + @process + @counter)

    return @objectId
end

Это можно назвать так:

select NewObjectId(CRYPT_GEN_RANDOM(3))

Причина, по которой передается CRYPT_GEN_RANDOM (3), заключается в том, что вызов этой функции, по-видимому, имеет побочные эффекты и не может использоваться внутри другой функции. Я бы предпочел использовать инкрементную последовательность для части счетчика, но случайное число также работает.

Также я заметил, что вы сказали, что используете char (24) для хранения значения. Это возвращает двоичный код (12), поскольку это то, что и есть ObjectIds MongoDB. Использование двоичного кода (12) также требует половины пространства для хранения значения.

Я уверен, что сейчас это бесполезно, но решить проблему было весело.

Я попытаюсь взять мой код ObjectID C # и посмотреть, смогу ли я загрузить его как функцию CLR в SQL Server. Это может дать лучшие результаты и производительность.

...