2017-01-27 5 views
3

У меня есть приложение C#, которое генерирует Sequential GUID для каждой строки, которую я вставляю в таблицу. Я ожидаю, что вставленные GUID будут последовательными, но иногда прерывают последовательность (в кусках).Сгенерированные последовательные GUID иногда не являются последовательными

Пример:

Break in sequence

Эти идентификаторы GUID показаны в том порядке, что они вставлены.

Почему эти «последовательные» GUID создаются с таким большим прерыванием последовательности?


Код, используемый для создания последовательного GUIDs:

class NativeMethods 
{ 
    [DllImport("rpcrt4.dll", SetLastError = true)] 
    public static extern int UuidCreateSequential(out Guid guid); 
} 

public static Guid CreateSequentialGuid() 
    { 
     const int RPC_S_OK = 0; 

     Guid guid; 
     int result = NativeMethods.UuidCreateSequential(out guid); 
     if (result == RPC_S_OK) 
      return guid; 
     else 
      return Guid.NewGuid(); //<--In debugging, this statement never runs. 
    } 

кода, используемого в цикле для вставки нового GUIDs и информации в таблицу:

Guid mySequentialGUID = CreateSequentialGuid(); 
string[] row = { item1, 
       item2, 
       item3, 
       sourceText, 
       encoding.ToString(), 
       mySequentialGUID.ToString() 
      }; 
var listViewItem = new ListViewItem(row); 
myListView.Items.Add(listViewItem); 

Edit: Пожалуйста, смотрите на этот вопрос для понимания Последовательные идентификаторы GUID:

+4

GUID существует, чтобы быть уникальным номером. Не больше, не меньше. Хотя для их генерации существуют разные алгоритмы, вы не должны полагаться на конкретные свойства конкретных реализаций. Нарисуйте GUID как GUID, не более того. Если вам нужно увеличивать число, то * получите число и увеличивайте его *, вместо использования GUID, который * только * представляет собой способ генерации * уникальных * чисел. – Servy

+3

Я никогда не слышал о последовательном GUID, но это кажется совершенно неправильным. Вы это сделали? GUID по самой своей природе уникален, и вы не можете контролировать, как он создан. Если вы * знаете, какой следующий GUID будет сгенерирован (потому что он следующий по порядку от вашего последнего), то это не уникально, потому что кто-то другой может сделать то же самое, начиная с того же стартового значения. –

+1

@ rory.ap Я не составлял последовательный GUID. Существует даже встроенный метод для создания последовательных GUID в Transact-SQL под названием NewSequentialID(). https://msdn.microsoft.com/en-us/library/ms189786.aspx –

ответ

4

Я думаю, проблема заключается в том, что вы предполагаете, что «последовательный» означает «увеличивать на единицу». Хотя ваш пример показывает, что это иногда случается, фактическая гарантия в документации отсутствует. Мы могли бы утверждать, определение «последовательности» или что, возможно, эта функция называется слабо или даже неправильно, но в конце дня, в соответствии с документацией, что, как представляется, будет работать на 100% точно, как определено:

Создает GUID, который больше, чем любой GUID ранее сгенерированного этой функция

Для людей, у которых есть проблемы с общей концепцией «последовательного GUID» использовать определение «последовательность», что вот-вот «после логического порядка» а также попытайтесь вспомнить вирус Мелиссы.Это было mildly document by this line:

По соображениям безопасности, UuidCreate был модифицирован таким образом, что он больше не использует MAC-адрес машины для генерации UUID,. UuidCreateSequential был введен для создания UUID с использованием MAC-адреса Ethernet-карты устройства.

Таким образом, «последовательность» основывает идентификатор GUID на MAC-адресе.

Обратно к вопросу OP, мое лучшее предположение, почему у вас есть GUID, которые не увеличиваются на единицу каждый раз, является простым фактом, что вы, вероятно, не единственный, кто вызывает эту функцию. Это основная функция Windows, и там будут использоваться другие компоненты, программы, службы и т. Д., Которые ее используют.

+0

Этот ответ верен, но я бы просто хотел добавить, что если OP пытается использовать результат для вставки строк в SQL Server, ей должно быть известно, что UuidCreateSequential не является полностью последовательным в отношении сортировки SQL Server и необходимо выполнить некоторое количество байтов : https://blogs.msdn.microsoft.com/dbrowne/2012/07/03/how-to-generate-sequential-guids-for-sql-server-in-net / – martin

1

В NewSequentialId() начинается снова, когда система перезапускается. См. here.

Создает идентификатор GUID, который больше, чем любой GUID, ранее сгенерированный этой функцией на указанном компьютере с момента запуска Windows. После того, как перезапустит Windows, GUID может начать снова с более низкого диапазона, но по-прежнему уникален по всему миру. Когда столбец GUID используется в качестве идентификатора строки , использование NEWSEQUENTIALID может быть быстрее, чем использование функции NEWID . Это связано с тем, что функция NEWID вызывает случайную активность и использует меньше кэшированных страниц данных. Использование NEWSEQUENTIALID также помогает полностью заполнять страницы данных и индексирования.

+0

Благодарим вас за ответ. Я понимаю, что это может произойти после перезагрузки Windows. Мой метод 'CreateSequentialGuid()' вызывается в одном быстром цикле 'for', и моя машина не перезапускается. –

Смежные вопросы