德语   法语   荷兰语   葡萄牙语 - 伊伯利亚   西班牙语   英语(美国)   中文 - 简体  

Home






主题: 信息: 复制与GUIDs, 好处,坏处和不妥处
(原始发布时间99年7月26日)
全局唯一标识符……即GUIDs(发音就象Geoduck,的“uck”或象“Gooo-id”,这是用于那些不能处理其他声音的人)基本上,整个时间和空间都是唯一的。它们被用于整个COM,也被Jet复制使用,作为一个创建记录ID的方法,不管其他值(如键值)会改变什么,这些记录都会保留不变和唯一。

许多人都考虑将GUIDs用于他们的主键码/外键码值,因为它们能保证唯一性。但是,这样进行下去之前,还有许多理由要再三考虑。

1) 在app中,“复制ID自动编号字段”(即,自动编号GUID)会转变成一个副本,Jet 将使用你的列,而不是创建s_Guid列。可惜的是,Access 95和97的冲突解算器向导和Access 2000冲突阅读器假设的是s_Guid列,这样,冲突解决就不能通过向导正确地工作。

2) GUID表面上是作为一个16字节值被存储。它也有一个规范(文本)形式和一个DAO/Jet指定形式,由{guid {xxx}}组成,其中,xxx是“规范”值。后者的形式是任何时候你通过DAO从GUID字段做选择语句时,Jet将要显示的……如果你直接通过Jet(如通过 Access数据表)或通过Jet OLE DB提供商的ADO,规范形式将会被使用。此外,DAO与ADO筛选器规则,查找,Access域函数, Access筛选,形式/子形式连接,限制在GUID字段控制的.文本(.Text) 与 .值(.Value),和所有搜索方法,都很难随着每个版本而改变。Access有内部功能来帮助在二进制和称为StringFromGUID和GUIDFromString的规范形式之间进行转换,但是,很可惜,它们使用的是DAO语法,虽然所有的COM和大多数其他的源是喜欢规范的。这整个混合意味着,为了这些操作而使用GUID字段将意味着你正在到达一个移动的目标。

3) #2中的规则随每个版本而改变,而且几乎打破过去版本的工作。因此,实质上,你必须重新审阅更新时所有的工作。

4) 对于用户来说,自动编码通常是可见的,不管怎么样,对于GUIDs来说,显然都是非常不切实际的,即使所有无数的糟糕问题,如搜索及以上列出的问题,都不是实际问题。GUIDs只是迷惑了用户,没有人想要GUID来鉴别自己。 :-)

现在,所有这些在#2中提到的问题都能通过使用许多技术进行工作,包括:

1) 对使用正确的规范形式与{guid {xxx}}规范形式进行实验

2) 通过两个Access功能的转化使用

3) 选择语句的返回GUIDs的字段值中使用CStr(),这样,你就能够获得正确的规范形式。

4) 注意你做改变的所有位置,以便于如果/当你更新时你可以再访问它们(因为大多数将被破坏和改变下一个版本)。

5) 要意识到 ,DAO状态中的基础字段是dbGuid类型字段,基础ADO状态是adGuid类型字段……尽管事实是,当你查看字段值帮助来强调进行的这些努力来使其灵活时,它们都会返回“文本”类型字段……这是为什么#2的一切都是那么难预测的主要原因。

如果你进行VB工作,这里(顺便)是非Access功能处理Guid/String 和 String/Guid资料。只须把它粘贴到模块中,等等即可。

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 

最后建议:

要克服#2和#3中的问题是可能的,#2是很有问题的,而且从#3来看,很难认为是可维持的。通常,它是不值得进行错误,问题或迫使更新问题的风险工作的。有更好的方法来选择PKs,它是不参与这些风险的……所以,如果你想写清除,简易维护数据库以及复制的应用程序,这样做是明智的。

MichKa
复制ID: {E5D50A9B-33D2-11D3-AAB3-00104BA31425}

Back to Usenet Musings


关于本站点的问题,评论和建议,请与 webmaster@trigeminal.com联系。