Alemão   Chinês - Simplificado   Espanhol   Francês   Holandês   Inglês (E.U.A.)   Português - Ibérico  

Home




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

Assunto: INFO: Replicação e GUIDs, o Bom, o Mau, e o Feio
(Originalmente escrita em 26/7/99)
Globally Unique Identifiers... ou GUIDs (pronunciado como Geoduck como o "uck" ou como "Gooo-id" para as pessoas que não consigam efectuar a outra pronúncia) são basicamente únicos através do tempo e do espaço. Eles são usados em toda a COM, e são usados pela replicação do Jet como a maneira de criar um identificador para os registos que se manterá constante e único apesar de outros valores (como as chaves) possam ser alterados.

Muitas pessoas consideram a possiblidade de utilizar GUIDs como as suas chaves primárias/chaves estrangeiras, porque estes vão garantir que elas serão únicas. Contudo, existem diversas razões para pensar duas vezes antes de optar por esta solução:

1) Numa aplicação, um "campo ReplicationID Autonumber" (um autonumber GUID), que por sua vez é tornado numa réplica, o Jet vai utilizar o teu campo em vez de criar um novo campo s_Guid. Infelizmente, o Assistente de Resolução de Conflitos do Access 95 e 97 e o Visualizador de Conflitos do Access 2000 estão a assumir um campo s_Guid e como tal as resoluções dos conflitos não vão funcionar correctamente através dos assistentes, e então estás por tua conta.

2) Um GUID é literalmente guardado como um valor binário de 16-byte. Tem também uma parte canónica (texto) e uma parte específica ao DAO/Jet também, constituída por {guid {xxx}} onde xxx é o valor "canónico". Este último formato é o que o Jet vai mostrar de qualquer das vezes que selecionares um campo GUID através do DAO... a forma canónica vai ser utilizada se utilizares o Jet directamente (como por exemplo através da folhas de dados do Access) ou ADO através do Jet OLE DB provider. Adicionando a isto, as regras do DAO vs. ADO como filtros, pesquisas, Funções Access Domain, Access filter by form, form/subform links, .Text vs. .Value para controles ligados (bound) a campos GUID, e todos os metódos de pesquisa, são muito difíceis de acompanhar e alterar com cada versão. O Access tem funções built-in para ajudar a converter entre o formato binário e o canónico nomeadas StringFromGUID e GUIDFromString, mas infelizmente elas usam a sintaxe do DAO, mesmo que em toda a COM e a maioria de outas fontes prefiram o formato simplesmente canónico. Toda esta confusão significa que a tentar utilizar um campo GUID para estas operações significa que estás a tentar atingir um alvo em movimento.

3) As regras do #2 mudam em quase todas as versões e quase universalmente quebram o que funcionava na versão anterior. Portanto no essencial tu terás de rever de novo todo o trabalho quando estiveres a efectuar uma actualização de versão.

4) Muitas vezes Autonumbers estão visíveis para os utilizadores, para o melhor e o pior, e isto é obviamente muito pouco prático com os GUIDs, mesmo que a grande quantidade de maus assuntos com as pesquisas e outros listados acima não fossem efectivamente problemas. Os GUIDs simplesmente confundem os utilizadores e ninguém quer um GUID para o identificar.

Agora, é verdade que todos os problemas abordados no #2 podem ser ultrapassados utilizando diversas técnicas, incluindo:

1) Experimentar, utilizar o verdadeiro formato canónico vs. o formato canónico {guid {xxx}}

2) Conversão utilizando as duas funções do Access

3) Utilizar CStr() no comando SELECT para os valores dos campos que devolvam GUIDs de modo a obteres o verdadeiro formato canónico

4) Anotar todos os lugares onde fizeste qualquer alteração para que se/quando fizeres uma actualização de versão possas rever todos eles (pois a maioria estará estragada e alterada com a próxima versão).

5) Perceber que o campo por trás do DAO é um campo do tipo dbGuid e ue o campo por trás do ADO é um campo do tipo adGuid... apesar do facto que ambos devolvem um campo do tipo "texto" quando estás simplesmente a visualizar os valores dos campos ajuda a perceber o grande esforço que todos tiveram de maneira a tentarem parecer flexiveis... é a principal razão porque todo o #2 é tão difícil de prever.

Aqui está (por falar nisso) as funções não-Access para fazer manipulação de Guid/String e String/Guid se estás a trabalhar através do VB. Simplesmente copia-as para um módulo, 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 

RECOMENDAÇÃO FINAL:

Enquanto é possível evitar ambos os problemas descritos em #2 e #3, os do #2 são muito problemáticos e é muito difícil considerar a manutenção face ao descrito em #3.  Na generalidade não vale o risco de erros e problemas ou dos problemas de actualização de versões. Existem maneiras melhores de escolher PKs que não envolvem estes riscos.... é portanto quase sempre mais aconselhável seguir esse rumo se pretendes construir bases de dados que possam ser facilmente mantidas e aplicações que possam ser replicadas. MichKa
ReplicaID: {E5D50A9B-33D2-11D3-AAB3-00104BA31425}

Home

Problemas com este site? Por Favor contactar o webmaster@trigeminal.com
com os teus comentarios, questoes ou sugestoes.