您的位置:首页 > 产品设计 > UI/UE

关于使用GUID和Identity做主键的一些思考

2008-07-03 22:38 567 查看
通常,给数据库中的表都添加一个“无意义”的主键,能够大大地简化程序的开发。这个主键用什么类型呢?其实各种类型,只要大小不超过900字节都可以,但我们最常面临的两种选择是——GUID(UniqueIdentifity)和Identity INT。

《ADO.NET 2.0高级编程》一书的“5.2.2 选择主键”一节,对此进行了一些对比,并推荐使用GUID类型作为主键的类型。但本文中老刘将介绍自己在实际开发中的一些感触。

老刘在公司写程序时,面对的数据库绝大多数都是用Identity做主键;而回家自己写程序玩的时候,因为迷信《ADO.NET 2.0高级编程》,所以设计的数据库都采用GUID做主键类型。所以,对这两种主键类型都有些想法。

GUID优于Identify的方面



首先,对于GUID类型的主键,通常在创建新的数据条目时可以采用Guid.NewGuid()方法为其生成主键;而对于Identify类型的主键,只有当数据条目被真正插入数据库后才能得到其主键值。当需要在同一个事务中,向多个相关表中插入数据时,若采用GUID主键,就能使用一次提交动作插入所有数据;而如果使用Identify类型做主键,就必须先插入主键列所在表的数据,再插入外键列所在表的数据。如下面两段代码所示。

// 使用GUID作为主键类型

using(MyDataContext db = new MyDataContext())

// 使用Identity作为主键类型

using(MyDataContext db = new MyDataContext())

{

Category c = new Category // 由于才用Identity类型作为主键,所以无需也不能明确指定主键值

{

Name = "分类2"

};

db.Categories.InsertOnSubmit(c);

db.SubmitChanges(); // 提交后才能得到确定的ID值

Article a = new Article

{

Title = "标题又来了",

Body = "没有内容",

CategoryId = c.Id

};

db.Articles.InsertOnSubmit(a);

db.SubmitChanges(a); // 第二个提交,如果出错,分类c也会留在数据库中

}
正如注释中所述,当发生错误时,一次提交可以简单干净地回滚;但多次提交,就得采取一些手段了。

Identify优于GUID的方面



首先,Identify根本上说是一个int,只占4字节;而GUID要占16字节。这当然不算什么,可以忽略。

其次,要知道,主键就是一个簇索引(聚集索引),这意味着数据在磁盘上的物理排列顺序是和主键顺序一样的。这就存在一个问题,每次生成的GUID并不是按照时间顺序从小到大的,换句话说,第二次生成的GUID可能比第一次小,而第三次可能又比第二次小。这就导致每次插入一行数据时,都要对表中整行整行的数据进行排序。而Identify类型的字段,可以明确保障后生成的值比之前生成的值都大,因此新插入的数据会简单地追加在表的尾部。所以,对于频繁插入新数据的表来说,Identify主键的性能要好一些。(注意,本条纯属老刘推测,没有进行过测试。)

最后,Identify主键更便于人类阅读。嗯……给大家各场景吧。在公司,我没有查看生产环境数据库的权限,所以当客户提交来bug之后,我会朝我老板喊:帮我把服务器上ID是1234的用户的数据取出来我看看~~ 想想吧,如果采用了GUID主键,我该怎么喊?

-----

注,写到这里,就完了。但我发现好像有些倾向于Identify主键。希望大家不要有这样的偏见,好好看看《ADO.NET 2.0高级编程》,考虑考虑。欢迎大家在这里探讨。

-----

最后还是广告:欢迎访问[.NET正则表达式库] http://regex-lib.net
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: