« | October 2025 | » | 日 | 一 | 二 | 三 | 四 | 五 | 六 | | | | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | | |
|
|
|


| |
[DB-Developer]GUID概览与数据库运用-powerbuilder (收集整理) 软件技术
wood_knight 发表于 2005/3/2 21:54:51 |
数据表主健通常采用以下三种方式:
1. 自动递增值。
2. 唯一名称。这个是使用自己定义的算法来生成一个唯一序列号。
3. GUID(全局唯一标识符)。
GUID与自动递增值及唯一名称比较
GUID
在客户端生成,由GUID的特性决定,通过GUID生成的值可能出现重复的机会几乎等于零,因此保证在插入表的时候主键值唯一。
可以方便处理分布式数据的提交,比如:分店数据向总店提交――直接将该部分数据插入即可。
支持离线数据处理。对本地数据包进行新增记录时即可将该数据表的关键字段值赋值,其处理方法是与在线新增时是一致的。
自动递增值
在数据库服务器端生成,由于该值是由数据库系统内部处理的,亦保证其唯一性,但由于其是在数据库服务器端生成,因此必须将该值返回客户端,客户端通过该值过行其它操作。比如一张单据(主从表)是使用自动递增值,当插入单据抬头后,必须将单据抬头的关键字段值返回,再插入单据明细(单据明细是通过单据抬头关键字段进行关联的)。
不能很好处理分布式数据的提交,比如:分店数据向总店提交――提交数据时必须重新生成该数据表的关键字段值,以保证该字段值唯一。
要支持离线数据处理需要进行额外的处理,对本地数据包进行保存记录(保存到本地)时需要插入一个假设唯一值,在提交离线数据回数据服务器时再重新生成真正的唯一值,并重新进行相关的处理。
唯一名称
在客户端生成或在服务端生成,相对于自动递增值不同的地方就是自己维护生成唯一值的算法及所保存的临时值,容易造成出错或其它问题。如果是在客户端生成唯一值的话,还必须保证所生成的值是唯一的。
不能很好处理分布式数据的提交,比如:分店数据向总店提交――提交数据时必须重新生成(或预先处理)该数据表的关键字段值,以保证该字段值唯一
要支持离线数据处理需要进行额外的处理,对本地数据包进行保存记录(保存到本地)时需要插入一个假设唯一值,在提交离线数据回数据服务器时再重新生成真正的唯一值,并重新进行相关的处理。
实例说明
下面以一个新增单据保存比较GUID与自动递增值/唯一名称的差别
动作
GUID
自动递增值/唯一名称
单据抬头
新增
单据抬头关键字段值:获取并填写
单据抬头关键字段值:无
保存
直接保存
首先获取并填写关键字段值,然后再进行保存
返回
直接返回
返回时必须将关键字段值返回
单据明细
新增
关联单据抬头字段值:直接填写
单据明细关键字段值:获取并填写
关联单据抬头字段值:无
单据明细关键字段值:无
保存
直接保存
获取单据抬头关键字段值并填写到单据明细的关联单据抬头字段中;
然后获取并填写单据明细关键字段值;
再进行保存
综合以上所述,用GUID作为数据表的关键字段值是可以减轻关键字段相关的操作的,并且是最直接实用的方法。
简单的pb中生成GUID的函数编写如下:
全局函数 code
//--------------------------------------------- //Function f_get_GUID//得到全球唯一码 //Argument: <ref string> of_guid //全球唯一码 //Return: [None] //Create by 泥草鞋 2004-03-10 //---------------------------------------------- oleObject PBObject long ll_result PBObject = CREATE oleObject ll_result = PBObject.ConnectToNewObject("PowerBuilder.Application") IF ll_result < 0 THEN messagebox(gs_message,"连接失败:与PowerBuilder.Application连接出错!") return ELSE ll_result = PBObject.GenerateGUID(REF of_guid) END IF IF ll_result < 0 THEN messagebox(gs_message,"生成GUID失败:不能获得GUID!") return END IF of_guid = mid(of_guid,2,len(of_guid) - 2) //End of Fuction
好啦,以后不用为主键重复问题再烦恼了吧。 不过,请注意该函数需要的支持文件:(以PB7.0为例) pbappl.reg(执行它注册一遍,7.0以下必须此文件) Pbvm70.dll(不用多说了) Pbaen70.tlb(PB自动应用服务类库入口)附: GUID如何做到唯一? 要确保一个标识是唯一的,仅有两个方法: 1.通过一些机构组织来登记; 2.使用特别的算法来产生唯一的数字,这些数字可被认为在世界范围内是唯一的。 第一个方法很常见,比如身份证号码是国家制定的标识个人。它的问题是,制定这标识的机构组织自身存在执行偏差,而且手续繁琐,多数情况下你得花钱费时。 第二个方法更适合于开发者。如果你可以发明一个算法,每次调用它都可以产生一个可被认为是唯一的名字,那么这个问题就解决了。 事实上,开发软件基金会(Open Software Foundation,OSF)已经研究出一种能产生唯一标识符的算法,产生全球唯一标识符(Universally Unique Identifier,UUID)。在COM的命名标准上,微软使用同样的算法!在COM中微软将它重命名为Globally Unique Identifier(GUID)。 生成GUID的算法根据以下几个方面:1.当前日期和时间。2.网络适配器卡地址。3.时针序。4.自动递增计数器。其中,网卡地址是相互不同的,对没有网卡的机器,地址对使用中的机器保持唯一性。 GUID的记录通常采用16进制。不过这没有关系,一个典型的GUID类似为:"88AB240C-F761-49B8-B47F-94B0ABA4115A",略去"-",即为一个128位的唯一数字。2的128次方是一个非常大的数字。128位的接口标识符使得我们可能创建大约340282366920900000000000000000000000000个独立的接口,足够为将来10782897524560000000年每秒创建一万亿个接口。 这是个什么概念呢?就拿这几个数字中最小的“一万亿”来说。假如把银河系缩小一万亿倍,也就是把银河系直径缩小到一百万公里,这时太阳就变成一粒芝麻,那么最大的行星木星就变成了一粒灰尘。 即使地球毁灭了,它仍然是全球唯一。 |
|
|