2017-01-27 5 views
3

Ich habe eine C# -Anwendung, die eine sequenzielle GUID für jede Zeile generiert, die ich in eine Tabelle einfügen. Ich erwarte, dass die eingefügten GUIDs sequenziell sind, aber manchmal sie brechen die Sequenz (in Chunks).Generierte sequenzielle GUIDs sind manchmal nicht sequenziell

Beispiel:

Break in sequence

Diese GUIDs werden in der Reihenfolge gezeigt, dass sie eingesetzt werden.

Warum werden diese 'sequentiellen' GUIDs mit einem so großen Sequenzbruch erzeugt?


-Code verwendet sequenziellen GUIDs zu generieren:

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. 
    } 

-Code in einer Schleife verwendet, um neue GUIDs und Informationen in die Tabelle einfügen:

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

Edit: Bitte sehen Sie diese Frage Sequentielle GUIDs verstehen:

+4

Eine GUID existiert als eindeutige Nummer. Nicht mehr und nicht weniger. Es gibt zwar verschiedene Algorithmen, mit denen Sie diese generieren können, aber Sie sollten sich nicht auf bestimmte Eigenschaften bestimmter Implementierungen verlassen. Führe eine 'GUID' als GUID aus, nicht mehr. Wenn Sie eine inkrementierende Zahl benötigen, dann * erhalten Sie eine Zahl und erhöhen Sie sie *, anstatt eine GUID zu verwenden, was * nur * eine Darstellung einer Möglichkeit zur Erzeugung von * eindeutigen * Zahlen ist. – Servy

+3

Ich habe noch nie von einer sequentiellen GUID gehört, aber das scheint völlig falsch zu sein. Hast du das erfunden? Eine GUID ist von Natur aus einzigartig und Sie können nicht steuern, wie sie generiert wird. Wenn Sie * wissen *, was die nächste GUID ist, die erzeugt wird (weil es die nächste GUID ist, die Sie erzeugt haben), dann ist es nicht eindeutig, da jemand anders dasselbe tun kann, beginnend mit dem gleichen Startwert. –

+1

@ rory.ap Ich habe keine sequentielle GUID erstellt. Es gibt sogar eine eingebaute Methode, um sequentielle GUIDS in Transact-SQL zu erzeugen, genannt NewSequentialID(). https://msdn.microsoft.com/en-us/library/ms189786.aspx –

Antwort

4

Ich denke, das Problem ist, dass Sie davon ausgehen, dass "sequenziell" bedeutet "um eins erhöhen". Obwohl Ihr Beispiel zeigt, dass dies manchmal passiert, gibt es in der Dokumentation keine Garantie dafür. Wir könnten argumentieren die Definition von "Sequenz" oder dass diese Funktion vielleicht schlecht oder gar falsch benannt wird, aber am Ende des Tages, nach der Dokumentation scheint es zu 100% genau wie definiert arbeiten:

Erstellt eine GUID, die zuvor größer als jede GUID durch diese Funktion

Für Menschen erzeugt wird, die ein Problem mit dem allgemeinen Konzept einer „sequenziellen GUID“ hat die Definition von „Sequenz“ verwenden, die über „eine logische Reihenfolge folgenden“ sind Versuchen Sie auch, sich an den Melissa-Virus zu erinnern.Das war mildly document by this line:

Aus Sicherheitsgründen UuidCreate wurde so modifiziert, dass es nicht mehr verwendet ein MAC-Adresse des Geräts UUID zu erzeugen. UuidCreateSequential wurde eingeführt, um die Erstellung von UUIDs mithilfe der MAC-Adresse der Ethernet-Karte eines Computers zu ermöglichen.

Also die "Sequenz" basiert die GUID von der MAC-Adresse.

Zurück zur OP-Frage, meine beste Vermutung für warum Sie GUIDs haben, die nicht jedes Mal um eins erhöht werden, ist die einfache Tatsache, dass Sie wahrscheinlich nicht der einzige sind, der diese Funktion aufruft. Dies ist eine Kern-Windows-Funktion und es gibt andere Komponenten, Programme, Dienste usw., die es verwenden.

+0

Diese Antwort ist korrekt, aber ich möchte nur hinzufügen, dass, wenn das OP sucht, um das Ergebnis zum Einfügen von Zeilen in SQL Server verwenden, sollte sie wahrscheinlich bewusst sein, dass UuidCreateSequential ist nicht vollständig sequenziell in Bezug auf SQL Server sortieren Bestellung und müssen einige Byte Suffling durchführen: https://blogs.msdn.microsoft.com/dbrowne/2012/07/03/how-to-generate-sequential-guids-for-sql-server-in-net / – martin

1

Die NewSequentialId() beginnt über, wenn das System neu gestartet. Siehe here.

Erstellt eine GUID, die größer ist als jede zuvor von generierte GUID auf einem angegebenen Computer seit Windows gestartet wurde. Nach Neustart von Windows kann die GUID erneut aus einem niedrigeren Bereich starten, aber ist immer noch global eindeutig. Wenn eine GUID-Spalte als Zeile Bezeichner verwendet wird, kann die Verwendung von NEWSEQUENTIALID schneller sein als die Verwendung der NEWID -Funktion. Dies liegt daran, dass die NEWID-Funktion die zufällige Aktivität verursacht und weniger zwischengespeicherte Datenseiten verwendet. Mit NEWSEQUENTIALID hilft auch die Daten- und Indexseiten vollständig zu füllen.

+0

Vielen Dank für Ihre Antwort. Ich weiß, dass dies nach dem Neustart von Windows auftreten kann. Meine 'CreateSequentialGuid()' Methode wird in einer schnellen 'for'-Schleife aufgerufen und mein Rechner wird nicht neu gestartet. –