网站导航:首页 -> 软件水平考试 -> 系统工程师考试认证 -> 小议数据库主键选取策略

小议数据库主键选取策略

 我们在建立数据库的时候,需要为每张表指定一个主键,所谓主键就是能够唯一标识表中某一行的属性或属性组,一个表只能有一个主键,但可以有多个候选索引。因为主键可以唯一标识某一行记录,所以可以确保执行数据更新、删除的时候不会出现张冠李戴的错误。当然,其它字段可以辅助我们在执行这些操作时消除共享冲突,不过就不在这里讨论了。主键除了上述作用外,常常与外键构成参照完整性约束,防止出现数据不一致。所以数据库在设计时,主键起到了很重要的作用。

  常见的数据库主键选取方式有:

  ●自动增长字段

  ●手动增长字段

  ●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、客户端提交事务