chinesisch - vereinfacht   deutsch   Englisch (USA)   französisch   holländisch   portugiesisch - iberisch   spanisch  

Home




Usenet Posting #11 - Trigeminal Software, Inc. (German)

Betreff: INFO: Replikation und GUIDs, the Good, the Bad, and the Ugly
(ursprünglich gepostet 26.7.99)
Globally Unique Identifiers... oder GUIDs (auszusprechen wie engl. "Geoduck" mit dem "uck" oder wie engl. "Gooo-id" für Leute, die den anderen Ton nicht herausbringen) sind grundsätzlich einzigartig in Raum und Zeit. Sie werden querdurch COM verwendet, und sie werden von der Jet-Replikation verwendet, um eine ID für Datensätze zu erzeugen, die stets konstant und einzigartig bleibt, egal welche anderen Werte (z.B. Schlüsselwerte) sich ändern mögen.

Viele Leute überlegen, GUIDs für ihre Primärschlüssel/Fremdschlüssel-Felder zu verwenden, weil sie Einzigartigkeit garantieren. Es gibt jedoch viele Gründe, sich zweimal zu überlegen, ob man diesen Weg geht:

1) In einer Anwendung mit "ReplikationsID Autowert-Feld" (d.h. einer Autowert-GUID), die dann in ein Replikat umgewandelt wird, verwendet Jet Ihre Spalte statt eine s_Guid-Spalte zu erzeugen. Leider setzen der Konfliktlöser von Access 95 und 97 und der Konflikt-Viewer von Access 2000 eine s_Guid-Spalte voraus und deshalb funktioniert die Konfliktlösung durch den Assistenten nicht, d.h. sie müssen sich selber darum kümmern.

2) Eine GUID wird buchstäblich als ein Binärwert von 16 Byte gespeichert. Sie hat auch eine kanonische (Text-) Form und ebenso eine DAO/Jet-spezifische Form, nämlich {guid {xxx}}, wobei xxx der "kanonische" Wert ist. Dieses letzte Format ist jenes, das Jet stets anzeigt, wenn Sie ein Select-Statement von einem GUID-Feld mit DAO ausführen... das kanonische Format wird verwendet, wenn Sie direkt über Jet gehen (z.B. mit Access-Datenblättern) oder über ADO per Jet OLE DB Provider. Die Regeln für DAO- gegenüber ADO-Filter, Finds, Access Domänen-Funktionen, formularbasierte Filter in Access, Formular/Unterformular-Verknüpfungen, .Text gegenüber .Value für Steuerelemente, die an GUID-Felder gebunden sind, und alle Such-Methoden sind sehr schwer zu verstehen und ändern sich mit jeder Version. Access hat eingebaute Funktionen, namens StringFromGUID und GUIDFromString, die beim Konvertieren zwischen binärer und kanonischer Form helfen, aber leider verwenden sie die DAO-Syntax, obwohl bei COM und anderen Quellen die direkte kanonische bevorzugt wird. Dieser ganze Mischmasch bedeutet, der Versuch, ein GUID-Feld für diese Operationen zu verwenden, heißt, ein bewegliches Ziel zu treffen.

3) Die Regeln in #2 ändern sich mit jeder Version und zerstören fast alles, was in der vorherigen Version funktioniert hat. Daher müssen sie bei einem Upgrade praktisch immer wieder alles überprüfen.

4) Autowerte werden oft für den Anwender sichtbar gemacht, ob gut oder schlecht, und das ist ganz offensichtlich bei GUIDs sehr unpraktisch, sogar wenn die Myriaden von Problemen mit dem Suchen etc. wie o.a. nicht existieren würden. GUIDs verwirren Anwender einfach und niemand lässt sich gerne von einer GUID identifizieren. :-)

Es stimmt, dass alle Probleme, die in #2 angedeutet wurden, durch die Verwendung vieler Techniken umgangen werden können. Dazu zählen:

1) Experimentieren mit der Verwendung der echten kanonischen Form gegenüber der {guid {xxx}} kanonischen Form

2) Konvertieren mithilfe der beiden Access-Funktionen

3) Verwenden von CStr() bei den Feldwerten in SELECT-Statements, die GUIDs zurückliefern, um das echte kanonische Format zu erhalten

4) Notizen machen zu allen Stellen, an denen Sie Änderungen vornehmen, damit Sie bei einem evtl. Update alles überprüfen können (da das meiste in der nächsten Version geändert wird und nicht mehr funktioniert).

5) Verstehen, dass das zugrundeliegende Feld im DAO-Fall vom Typ dbGuid ist und im ADO-Fall vom Typ adGuid... ungeachtet der Tatsache, dass beide ein Feld vom Typ "Text" zurückliefern, wenn man nur auf den Feldwert achtet, hilft ihre großen Bemühungen zu unterstreichen, flexibel zu erscheinen...Das ist der Hauptgrund, warum alle Punkte in #2 so schwer vorhersehbar sind.

Hier sind (übrigens) die Nicht-Access-Funktionen für die Konvertierung Guid/String und String/Guid, falls sie mit VB arbeiten. Einfach in ein Modul kopieren etc.

Type GUID 
    Data1 As Long 
    Data2 As Integer 
    Data3 As Integer 
    Data4(7) As Byte 
End Type 

Private Declare Function _ 
 StringFromGUID2 Lib "ole32.dll" _ 
 (rclsid As GUID, ByVal lpsz As Long, _ 
 ByVal cbMax As Long) As Long 

Private Declare Function _ 
 CLSIDFromString Lib "ole32.dll" _ 
 (pstCLS As Long, clsid As GUID) As Long 

Function GuidFromStGuid(stGuid As String) As GUID 
    Call CLSIDFromString(ByVal StrPtr(stGuid), _ 
     GuidFromStGuid) 
End Function 

Function StGuidFromGuid(rclsid As GUID) As String 
    Dim stGuid As String 
    Dim cch As Long 

    ' 39 chars  for the GUID plus room for the Null char 
    stGuid = String$(40, vbNullChar) 
    cch = StringFromGUID2(rclsid, StrPtr(stGuid), 39) 
    StGuidFromGuid = Left$(stGuid, cch) 
End Function 

SCHLUSSEMPFEHLUNG:

Es ist zwar möglich, die Probleme in #2 und #3 zu überwinden, aber #2 ist sehr problematisch und im Lichte von #3 kaum als durchführbar zu betrachten. Das Risiko, sich Bugs und Schwierigkeiten einzuhandeln oder Upgrade-Probleme zu provozieren, lohnt sich grundsätzlich nicht. Es gibt bessere Wege, Primärschlüssel zu wählen, die nicht solche Risken inkludieren.... deshalb ist es fast immer ratsam, diese Wege zu gehen, wenn Sie saubere und einfach wartbare Datenbank- und Replikations-Anwendungen schreiben möchten.

MichKa
ReplicaID: {E5D50A9B-33D2-11D3-AAB3-00104BA31425}

Home

Probleme mit dieser Seite? Bitte kontaktieren Sie den webmaster@trigeminal.com
mit Ihren Kommentaren, Fragen oder Vorschlägen.