allemand   anglais - États-Unis   chinois - simplifié   espagnol   français   hollandais   portugais - ibérique  

Home




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


Sujet: INFO: Réplication et GUIDs, le Bon, le Mauvais et l'Affreux.
(Parution initiale, le 7/26/99)
Globally Unique Identifiers... ou GUIDs (prononcer comme Geoduck avec le "uck" ou  "Gou-ide" pour ceux qui ne peuvent attraper le premier son) sont intrinsèquement uniques dans l'espace-temps. Il sont fréquemment utilisés par COM ainsi que par la réplication de JET pour créer un repère, ID, des enregistrements qui demeureront constant peu importe ce qu'il arrive aux autres valeurs (tel un changement de la clé primaire).

Plusieurs utilisateurs considèrent l'utilisation de GUID comme clé primaire ou de référence, puisque ce sont des valeurs uniques. Cependant, il y a quelques raisons pour y songer à deux fois avant de s'engager sur cette voie:

1) Dans une application, un champ "ReplicationID Autonumber" (i.e. un autonumber GUID) est utilisé par JET, lorsque vous convertissez votre application à une réplication, au lieu de créer un champ  s_Guid dans les autres case. Malheureusement, le Conflict Resolver Wizard d'Access 95 et  97, de même que le Conflict Viewer d'Access 2000, présupposent un champ  s_Guid pour la résolution des conflits et ainsi, la résolution des conflits risque de ne pas fonctionner proprement, et vous êtes seuls avec ce désagrément.

2) Un GUID est emmagasiné comme une valeur 16-octets. Il possède également une représentation canonique (texte) et un format spécifique à DAO/Jet également, constitué de  {guid {xxx}} où  xxx est la valeur canonique. C'est ce dernier format que Jet affiche dans un champ de par un énoncé SELECT de par DAO... la forme canonique est utilisée si vous utilisez Jet directement pour voir une table (vue sous Access en mode "datasheet") ou ADO via Jet OLE DB provider. De plus les règles des filtres et des méthodes "find" de  DAO vs. ADO, de filtrage par formulaire sous Access, liens entre parents et sous-formulaires, propriété Text vs Value pour les contrôles reliés à des champs GUID sont difficiles à suivrent, tout en changeant entre chaque version. Access possède des fonctions qui permettent la conversion du mode binaire au mode canonique,  StringFromGUID et GUIDFromString, mais elles utilisent la syntaxe DAO, même si la plupart des autres produits utilisant COM préfèrent la forme canonique. Ce bourbier signifie qu'avec l'utilisation d'un champ GUID signifie que vous visez une cible mouvante.

3) Lès règles au point #2 changent à chaque version et brisent presque universellement tout ce qui fonctionnait bien auparavant. Essentiellement, une tâche de révision additionnelle lors d'une migration vers une nouvelle version.

4) Les autonumbers sont quelques fois visibles pour l'utilisateur, pour un bien ou pour un mal, et c'est évidemment peu pratique avec des GUID, et même si la myriade de points soulevés précédemment ne sont pas des problèmes, les GUID confondent les utilisateurs et personne ne veut être identifié à un  GUID. :-)

Il est vrai que les mentions au points #2 peuvent être manipulés par quelques techniques, incluant:

1) Expérimenter avec l'utilisation de la forme canonique réelle vs. la forme {guid {xxx}} 

2) Conversion utilisant les deux fonctions d'Access

3) Utiliser CStr() dans les énoncés SELECT pour convertir les champs GUIDS en leur forme canonique réelle

4) Bien prendre note des endroits où on en fait usage de sorte qu'on puisse facilement revisiter ces points lors d'une prochaine migration (changement de version).

5) Réaliser que le type de champ est dbGuid sous DAO et adGuid sous ADO, même si tous deux retournent du "texte" lorsque vous regardez la valeur, camouflant de grands efforts destinés à montrer une flexibilité, mais rendant le comportement des points du #2 difficile à prédire.

Incidemment, voici des fonctions permettant la conversion, en dehors d'Access, utiles dans le cas où vous travaillez en VB, par exemple. Simplement copier dans un module, 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 

RECOMMANDATION FINALE:

Même s'il est possible de surmonter les points mentionnés en  #2 et #3, #2 est essentiellement problématique et très difficile à maintenir, en particulier en considérant le  #3.  Les risques d'erreurs n'en valent généralement pas la peine et mieux vaut choisir une clé primaire présentant moins de potentiel problématique. Il est toujours bien avisé d'écrire du code pour votre base de données qui soit facile à maintenir et à répliquer.

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

Back to Usenet Musings


Un problème avec ce site? Contacter le webmaster@trigeminal.com

avec vos commentaires, questions, ou suggestions (en anglais, de préférence).