2012年7月28日星期六

再谈数据库主键选取策略

再谈数据库主键选取策略

INT和GUID,究竟选谁?

关于数据库主键的选取策略,大家都是在INT和GUID两者中徘徊。忘了那些喋喋不休的争论吧!毕竟鱼与熊掌,不可兼得。在这篇文章中,我们不再关注两者的优缺点,所以请阅读自行做做功课。

话说回来,如果真要选,我会选谁?明确地说,我会选GUID,又或者说两者都选上。在两者都选的情况下,使用GUID做主键、INT做小二,这样呈现给前端的将是INT。如果想要让用户记忆或反馈那32个字符(去连接字符),你可以直接去死了!

INT和GUID,究竟谁快?

使用INT或GUID做主健,究竟谁更快?为回答这个问题,我们先看下面的表格数据:

主键类型字段类型存储长度(字节)
Intint4
Intbigint8
GUIDuniqueidentifier16
GUIDchar(36)36
GUIDvarchar(36)40
GUIDnchar(36)72
GUIDnvarchar(36)76

解释一下:

  1. uniqueidentifier存储为二进制值,那么为什么是16字节呢?0~f共16种表示,便有16*16=256,也有2^8=256(值域为0~255),去掉四个连接字符,即表示为16字节。
  2. varchar和nvarchar属变长型,存储时会增加一个int类型(四个字节)来记录当前字符长度。
  3. nchar和nvarchar类型存储为Unicode数据,存储时会占用两个字节,所以字节数是成双倍的。


谁会更快?

  1. 不用置疑,Int肯定是最快的,甚至你应该选择int而不是bigint。
  2. 其次,谁会更快?当选uniqueidentifier。
  3. 实际项目中,你选用了varchar、nchar、nvarchar这三种类型?只怕你是神,不是人或妖了。


INT和GUID,谁主沉浮?

如果你的项目中,是使用INT做主健,那么接下来的内容,你可以略过?因为你已经得到了答案。

其实,写这篇随笔的主要目的,是要告诉大家,使用GUID做主键时,要注意记录的索引与排序问题。

使用GUID做主键,字段类型选取为char(36),数据记录索引与排序肯定是从左到右,即:12345678-0000-0000-0000-000000000000

使用GUID做主键,字段类型选取为uniqueidentifier,数据记录索引与排序依据将是后六字节,即:00000000-0000-0000-0000-1234567890ab

为什么会这样?这是因为存储为uniqueidentifier时,数据会体现为SqlGuid 结构(详见MSDN中SqlGuid 结构描述)。

MSDN中有这样的描述:SqlGuid使用 SQL Server行为实现CompareTo,该行为只计算值的最后6个字节。Guid 计算全部 16 个字节。(详见:比较 GUID 和 uniqueidentifier 值 (ADO.NET))。

结束语

这篇随笔的文字描述,个人觉得表达并不是十分好。为了验证所说,你可以这样做:建表并添加uniqueidentifier字段类型,随便插入几万条记录,然后观察后十二位字符的排列情况(不要问为什么是后12位哦),参考下面的截图!

GUID


TAG: