登录名:  密码:  验证码: 3173
设为首页 收藏本站 联系站长
2008年7月5日
农历戊子年(鼠)
六月初三
 首页 | 最新上传 | 新闻 | 购物商场 | 招聘求职 | HTML学习 | java学习 | IT新闻 | 黑客技术 | 域名和空间 | 流量统计 | 故事小说
 GIF动画制作 | 图片素材 | 源码下载 | 书籍下载 | 视频资料 | ASP | 数据库 | PHP | 基本电脑知识 | 迅雷资源 | 兼职 | 组网工程
 英语学习 | FLASH专区 | ASP.NET | VB | 综合资源网 | 驱动下载 | 游戏下载 | 网站模板网页美工 | 韩文学习 | 论坛
 特别推荐:漂亮网站网址  图片素材
  我要查找:  
欢迎您来这里。每天学一点,每天进步一点!
Google
 当前位置:首页 >> ASP.NET  >> ASP.NET
关于如何得到新增记录的自动编号字段数值方法三
来源:http://access911.net  发表日期:2008年5月12日 作者: 

 编辑:admin 级别: 司令 浏览次数:68
】    
在阅读本文前,我想读者都应该已经读过我的关于取得新增记录的自动编号字段的值的文章
 
    关于如何得到新增记录的自动编号字段数值方法二

那么现在我们来考虑一下,为什么需要获取新增记录的自动编号字段呢?一般都是类似罗斯文示例数据库 NORTHWIND.MDB 中的订单表,在创建订单头后,在订单明细中需要引用某张订单的订单ID,当然,这个ID 是内置ID,并不显示给客户看。那么它是否只起到一个唯一标识记录的作用呢?如果真是这样,那我们为什么一定要让系统指定某个ID呢?我们完全可以利用自动编号在 ADODB.RECORDSET.ADDNEW 或者 CurrentProject.Connection.Execute("insert into 表名 (自动编号字段名) values('GUID值')") 时可以由用户随意指定这一特性来手动指定。具体方法请参考:

    如何更改数据类型为“自动编号”“同步复制ID”的值?《查询》

这样根本就没有必要去再次获取新增记录自动编号字段的必要。我们唯一要保证的就是这个由我们生成的 ID 必须是唯一的。VBA 完全可以保证做到这点。具体如何生成 GUID 请参考:

    如何获取 GUID 字符串?《VBA》《API》3
如何获取 GUID 字符串?《VBA》《API》
小议数据库主键选取策略 
作者:吕震宇 来源:315safe.com http://www.csai.cn 2006年03月16日 
  我们在建立数据库的时候,需要为每张表指定一个主键,所谓主键就是能够唯一标识表中某一行的属性或属性组,一个表只能有一个主键,但可以有多个候选索引。因为主键可以唯一标识某一行记录,所以可以确保执行数据更新、删除的时候不会出现张冠李戴的错误。当然,其它字段可以辅助我们在执行这些操作时消除共享冲突,不过就不在这里讨论了。主键除了上述作用外,常常与外键构成参照完整性约束,防止出现数据不一致。所以数据库在设计时,主键起到了很重要的作用。 
  常见的数据库主键选取方式有:

  ●自动增长字段 

  ●手动增长字段 

  ●UniqueIdentifier 

  ●“COMB(Combine)”类型

  一、自动增长型字段

  很多数据库设计者喜欢使用自动增长型字段,因为它使用简单。自动增长型字段允许我们在向数据库添加数据时,不考虑主键的取值,记录插入后,数据库系统会自动为其分配一个值,确保绝对不会出现重复。如果使用SQL Server数据库的话,我们还可以在记录插入后使用@@IDENTITY全局变量获取系统分配的主键键值。

  尽管自动增长型字段会省掉我们很多繁琐的工作,但使用它也存在潜在的问题,那就是在数据缓冲模式下,很难预先填写主键与外键的值。假设有两张表:

Order(OrderID, OrderDate)
OrderDetial(OrderID, LineNum, ProductID, Price)

  Order表中的OrderID是自动增长型的字段。现在需要我们录入一张订单,包括在Order表中插入一条记录以及在OrderDetail表中插入若干条记录。因为Order表中的OrderID是自动增长型的字段,那么我们在记录正式插入到数据库之前无法事先得知它的取值,只有在更新后才能知道数据库为它分配的是什么值。这会造成以下矛盾发生:

  首先,为了能在OrderDetail的OrderID字段中添入正确的值,必须先更新Order表以获取到系统为其分配的OrderID值,然后再用这个OrderID填充OrderDetail表。最后更新OderDetail表。但是,为了确保数据的一致性,Order与OrderDetail在更新时必须在事务保护下同时进行,即确保两表同时更新成功。

  听棠.NET指出:主档放在事务中提交时,通过@@IDENTITY 就可以取到生成值的,因此可以传给明细当外键用,而且在事务发生错误回滚时,主档记录也会被回滚取消的。

  吕震宇补充:使用自动增长字段会增加网络的roundTrip。尽管可以使用@@IDENTITY取得主键的值,但在更新过程中,不得不增加一次数据往返(以C/S结构为例): 

  1、客户端发送开始事务命令 
  2、客户端提交主表更新 
  3、服务器返回@@IDENTITY 
  4、客户端根据返回的主键更新从表缓冲 
  5、客户端将从表提交服务器更新 
  6、客户端提交事务 

  在这里多了一次往返就会增加了事务处理的时间。降低并发性能。 

  如果不用自动增长型字段,将是以下情景: 

  1、客户端发送开始事务命令 
  2、客户端提交主表更新 
  3、客户端提交从表更新 
  4、客户端提交事务 

  因此我不赞成使用自动增长型字段作为主键与外键链接的纽带。

  除此之外,当我们需要在多个数据库间进行数据的复制时(SQL Server的数据分发、订阅机制允许我们进行库间的数据复制操作),自动增长型字段可能造成数据合并时的主键冲突。设想一个数据库中的Order表向另一个库中的Order表复制数据库时,OrderID到底该不该自动增长呢?

  ADO.NET允许我们在DataSet中将某一个字段设置为自动增长型字段,但千万记住,这个自动增长字段仅仅是个占位符而已,当数据库进行更新时,数据库生成的值会自动取代ADO.NET分配的值。所以为了防止用户产生误解,建议大家将ADO.NET中的自动增长初始值以及增量都设置成-1。此外,在ADO.NET中,我们可以为两张表建立DataRelation,这样存在级联关系的两张表更新时,一张表更新后另外一张表对应键的值也会自动发生变化,这会大大减少了我们对存在级联关系的两表间更新时自动增长型字段带来的麻烦。

  二、手动增长型字段

  既然自动增长型字段会带来如此的麻烦,我们不妨考虑使用手动增长型的字段,也就是说主键的值需要自己维护,通常情况下需要建立一张单独的表存储当前主键键值。还用上面的例子来说,这次我们新建一张表叫IntKey,包含两个字段,KeyName以及KeyValue。就像一个HashTable,给一个KeyName,就可以知道目前的KeyValue是什么,然后手工实现键值数据递增。在SQL Server中可以编写这样一个存储过程,让取键值的过程自动进行。代码如下:

CREATE PROCEDURE [GetKey]

@KeyName char(10), 
@KeyValue int OUTPUT 

AS
UPDATE IntKey SET @KeyValue = KeyValue = KeyValue + 1 WHERE KeyName = @KeyName
GO

  这样,通过调用存储过程,我们可以获得最新键值,确保不会出现重复。若将OrderID字段设置为手动增长型字段,我们的程序可以由以下几步来实现:首先调用存储过程,获得一个OrderID,然后使用这个OrderID填充Order表与OrderDetail表,最后在事务保护下对两表进行更新。

  使用手动增长型字段作为主键在进行数据库间数据复制时,可以确保数据合并过程中不会出现键值冲突,只要我们为不同的数据库分配不同的主键取值段就行了。但是,使用手动增长型字段会增加网络的RoundTrip,我们必须通过增加一次数据库访问来获取当前主键键值,这会增加网络和数据库的负载,当处于一个低速或断开的网络环境中时,这种做法会有很大的弊端。同时,手工维护主键还要考虑并发冲突等种种因素,这更会增加系统的复杂程度。

  三、使用UniqueIdentifier

  SQL Server为我们提供了UniqueIdentifier数据类型,并提供了一个生成函数NEWID( ),使用NEWID( )可以生成一个唯一的UniqueIdentifier。UniqueIdentifier在数据库中占用16个字节,出现重复的概率非常小,以至于可以认为是0。我们经常从注册表中看到类似

{45F0EB02-0727-4F2E-AAB5-E8AEDEE0CEC5}

的东西实际上就是一个UniqueIdentifier,Windows用它来做COM组件以及接口的标识,防止出现重复。在.NET里管UniqueIdentifier称之为GUID(Global Unique Identifier)。在C#中可以使用如下命令生成一个GUID:


Guid u = System.Guid.NewGuid();

  对于上面提到的Order与OrderDetail的程序,如果选用UniqueIdentifier作为主键的话,我们完全可以避免上面提到的增加网络RoundTrip的问题。通过程序直接生成GUID填充主键,不用考虑是否会出现重复。

  UniqueIdentifier字段也存在严重的缺陷:首先,它的长度是16字节,是整数的4倍长,会占用大量存储空间。更为严重的是,UniqueIdentifier的生成毫无规律可言,要想在上面建立索引(绝大多数数据库在主键上都有索引)是一个非常耗时的操作。有人做过实验,插入同样的数据量,使用UniqueIdentifier型数据做主键要比使用Integer型数据慢,所以,出于效率考虑,尽可能避免使用UniqueIdentifier型数据库作为主键键值。

  四、使用“COMB(Combine)”类型

  既然上面三种主键类型选取策略都存在各自的缺点,那么到底有没有好的办法加以解决呢?答案是肯定的。通过使用COMB类型(数据库中没有COMB类型,它是Jimmy Nilsson在他的“The Cost of GUIDs as Primary Keys”一文中设计出来的),可以在三者之间找到一个很好的平衡点。

分页: [1] [2]
(编辑:网站学习网)
 ·上一篇文章: NetBeans技术案例和开发技巧专题
 ·下一篇文章: ASP与SQL数据库连接代码
 该篇文章的评论
 暂无相关评论
 姓名:  邮箱:
 内容:
                
 相关文章
 · Microsoft Data Access
 · 请问Microsoft Data Acc
 · 在XP下配置ASP.net的运行
 · resx是什么文件
 · asp.net C#连接SQL
 · asp.net调用Console程序
 · Visual studio&nbs
 · 怎样安装和使用Visual&n
 · resx是什么文件?
 · Asp.net简单会员管理系统
 · 关于如何得到新增记录的
 最新上传文章
 · 对宁波市鄞州区溪下村委
 · dlink无线路由设置
 · 无线路由器的无线加密设
 · 18岁黑客开博卖病毒&nbs
 · D-Link 无线路由器
 · 无线路由器密钥破解!
 · 把excel表格导入到acces
 · 金超群版包青天共有哪几
 · 一个黑客眼里的隐私(下
 · 网页与网站的基本知识
 · FrontPage建立超级连接书

服务说明 | 关于网站 | 联系我们 | 友情链接
网站学习网欢迎您!
http://www.studywebgood.com
浙ICP备07030755号 
联系邮箱:shuizhilang@126.com 如本网站侵犯了您的版权,请马上通知我.