新标识符的使用,

来源:互联网 发布:好玩的软件 编辑:程序博客网 时间:2024/05/01 14:06

纯技术视点

PTV-Pure Technology View

  首页 :: 联系 :: 聚合  :: 登录
    201 随笔 :: 9 文章 :: 2249 评论 :: 126引用

公告

TurboSMS - 企业短消息应用平台


bCentra l计数器


<script src="http://www.google-analytics.com/urchin.js" type="text/javascript"></script>
我的译作:
《没有任何漏洞-信息安全实施指南》


《数据库加密-最后的防线》

文章分类

  • 博客加油站
  • 同业评论
  • 我的文章
  • 技术参考
  • 新技术展望
  • 标准化研究
  • 经济与金融

存档

  • 2006年11月 (2)
  • 2006年10月 (7)
  • 2006年9月 (7)
  • 2006年8月 (4)
  • 2006年7月 (6)
  • 2006年6月 (2)
  • 2006年4月 (1)
  • 2006年3月 (3)
  • 2006年2月 (2)
  • 2006年1月 (1)
  • 2005年12月 (3)
  • 2005年11月 (2)
  • 2005年10月 (5)
  • 2005年9月 (3)
  • 2005年8月 (2)
  • 2005年6月 (1)
  • 2005年4月 (3)
  • 2005年3月 (1)
  • 2005年2月 (2)
  • 2005年1月 (3)
  • 2004年12月 (5)
  • 2004年11月 (11)
  • 2004年10月 (4)
  • 2004年9月 (6)
  • 2004年8月 (1)
  • 2004年7月 (1)
  • 2004年6月 (5)
  • 2004年5月 (10)
  • 2004年4月 (1)
  • 2004年3月 (4)
  • 2004年2月 (2)
  • 2004年1月 (8)
  • 2003年12月 (10)
  • 2003年11月 (26)
  • 2003年10月 (47)

随笔分类

  • rss .Text 研究
  • rss IT 人生
  • rss XML/Web Service
  • rss 程序设计
  • rss 系统管理
  • rss 组织/项目管理
  • rss 行业观察
  • rss 软件技术

相册

  • Longhorn 酷图
  • 幽默图片
  • 我的相册
  • 自然景观

中文博客

  • rss 呼呼堂
  • 小气的神

技术资源

     

英文博客

  • rss Don Box's Spoutlet
ASP.NET开发经验(3) --- 使用 GUID 值来作为数据库行标识

GUID(Global unique identifier)全局唯一标识符,它是由网卡上的标识数字(每个网卡都有唯一的标识号)以及 CPU 时钟的唯一数字生成的的一个 16 字节的二进制值。

GUID 的格式为“xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx”,其中每个 x 是 0-9 或 a-f 范围内的一个十六进制的数字。例如:6F9619FF-8B86-D011-B42D-00C04FC964FF 即为有效的 GUID 值。

世界上的任何两台计算机都不会生成重复的 GUID 值。GUID 主要用于在拥有多个节点、多台计算机的网络或系统中,分配必须具有唯一性的标识符。在 Windows 平台上,GUID 应用非常广泛:注册表、类及接口标识、数据库、甚至自动生成的机器名、目录名等。

在这次开发 ASP.NET 应用时,我大量使用了类型为 GUID 的 ID 列作为各实体表的关键字(键)。由于其唯一、易产生的特性,给应用程序处理带来诸多好处。

1、在 SQL Server 中使用 GUID

如果在 SQL Server 的表定义中将列类型指定为 uniqueidentifier,则列的值就为 GUID 类型。

SQL Server 中的 NewID() 函数可以产生 GUID 唯一值,使用此函数的几种方式如下:

1) 作为列默认值

将 uniqueidentifier 的列的默认值设为 NewID(),这样当新行插入表中时,会自动生成此列 GUID 值。

2)使用 T-SQL

在 T-SQL 中使用 NewID()函数,如“INSERT INTO Table(ID,... ) VALUES(NewID(),...)”来生成此列的 GUID 值。

3)提前获取 GUID 值

由于特殊功能需要,需要预先获知新行的 ID 值,也可以使用如下 C# 代码提前获得 GUID 的值,再存储到数据库中:

 SqlCommand cmd = New SqlCommand();
 cmd.CommandText = "SELECT NewID()";
 string rowID = (string) cmd.ExecuteScalar();
 cmd.CommandText = "INSERT INTO Table(ID,...) VALUES(@ID,...)
 cmd.Parameters.Add("@ID",SqlDbType.UniqueIdentifier).Value = new Guid(rowID);
 cmd.ExecuteNoQuery();

uniqueidentifier 值不能进行算术运算,但可以进行(意义不大的)比较操作和 NULL 检查;它不能象 IDENTITY 列一样,可以获知每行的增加时间的先后顺序,只能通过增加其它时间或时间戳列来完成此功能。

2、在 .NET 中使用 GUID

GUID 在 .NET 中使用非常广泛,而且 .NET Framework 提供了专门 Guid 基础结构。

Guid 结构的常用法包括:

1) Guid.NewGUID()

生成一个新的 GUID 唯一值

2) Guid.ToString()

将 GUID 值转换成字符串,便于处理

3)构造函数 Guid(string)

由 string 生成 Guid 结构,其中string 可以为大写,也可以为小写,可以包含两端的定界符“{}”或“()”,甚至可以省略中间的“-”,Guid 结构的构造函数有很多,其它构造用法并不常用。

同时,为了适用数据库中使用 GUID 的需要,.NET Framework 也提供了 SqlGUID 结构,它和 Guid 结构类似,只是两者对排序(CompareTo)的处理方式不同,SqlGuid 计算值的最后 6 个字节。而 Guid 计算全部 16 个字节,这种差异可能会给 SQL Server 中 uniqueidentifier 列的排序带来一定影响,当然这种排序意义也不大。

.NET Framework 中可以使用类 GuidConverter 提供将 Guid 结构与各种其他表示形式相互转换的类型转换器。


3、GUID 的优缺点

1) 优点

  • 同 IDENTITY 列相比,uniqueidentifier 列可以通过 NewID() 函数提前得知新增加的行 ID,为应用程序的后续处理提供了很大方便

  • 便于数据库移植,其它数据库中并不一定具有 IDENTITY 列,而 Guid 列可以作为字符型列转换到其它数据库中,同时将应用程序中产生的 GUID 值存入数据库,它不会对原有数据带来影响。

  • 便于数据库初始化,如果应用程序要加载一些初始数据, IDENTITY 列的处理方式就比较麻烦,而 uniqueidentifier 列则无需任何处理,直接用 T-SQL 加载即可。

  • 便于对某些对象或常量进行永久标识,如类的 ClassID,对象的实例标识,UDDI 中的联系人、服务接口、tModel标识定义等。

2) 缺点

  • GUID 值较长,不容易记忆和输入,而且这个值是随机、无顺序的,所以使用时要注意场合,最好不要尝试用它来作为你的电子邮件地址 J

  • GUID 的值有 16 个字节,与其它那些诸如 4 字节的整数相比要相对大一些。这意味着如果在数据库中使用 uniqueidentifier 键,可能会带来两方面的消极影响:存储空间增大;索引时间较慢。


综合来说, GUID 的优点带来的便利远超出其缺点带来的影响,随着诸如 WebService 等系统互联与整合技术的不断发展,其唯一标识的特性使得其应用越来越广,在您的应用程序中也应考虑使用它了。

2004年3月23日 10:57

评论

便于EAI:)

# 回复: ASP.NET开发经验(3) --- 使用 GUID 值来作为数据库行标识 2004-3-23 12:14 南002
第一句话,使用网络标示什么的,因为涉嫌暴露秘密而被XX掉了。

# 回复: ASP.NET开发经验(3) --- 使用 GUID 值来作为数据库行标识 2004-3-23 12:25 progame
我一直纳闷的是 如果没有装网卡 那么GUID如何生成?

# 回复: ASP.NET开发经验(3) --- 使用 GUID 值来作为数据库行标识 2004-3-23 13:07 JGTM'2004 [MVP]
Windows 2000之后已经不使用网卡地址作为生成GUID的参数了,现在用的是第四代算法,使用的是安全子系统的随机数生成器(RNG),因此安全性没有什么问题了。

@progame:

如果没有网卡,系统会使用其它的一些具有随机特征的数字作为种子来生成GUID。

# 回复: ASP.NET开发经验(3) --- 使用 GUID 值来作为数据库行标识 2004-3-23 13:23 moslem
UUIDs and GUIDs (DRAFT) 02/04/98

Node IDs when no IEEE 802 network card is available

If a system wants to generate UUIDs but has no IEE 802 compliant
network card or other source of IEEE 802 addresses, then this section
describes how to generate one.

The ideal solution is to obtain a 47 bit cryptographic quality random
number, and use it as the low 47 bits of the node ID, with the most
significant bit of the first octet of the node ID set to 1. This bit
is the unicast/multicast bit, which will never be set in IEEE 802
addresses obtained from network cards; hence, there can never be a
conflict between UUIDs generated by machines with and without network
cards.

If a system does not have a primitive to generate cryptographic
quality random numbers, then in most systems there are usually a
fairly large number of sources of randomness available from which one
can be generated. Such sources are system specific, but often
include:

- the percent of memory in use
- the size of main memory in bytes
- the amount of free main memory in bytes
- the size of the paging or swap file in bytes
- free bytes of paging or swap file
- the total size of user virtual address space in bytes
- the total available user address space bytes
- the size of boot disk drive in bytes
- the free disk space on boot drive in bytes
- the current time
- the amount of time since the system booted
- the individual sizes of files in various system directories
- the creation, last read, and modification times of files in various
system directories
- the utilization factors of various system resources (heap, etc.)
- current mouse cursor position
- current caret position
- current number of running processes, threads
- handles or IDs of the desktop window and the active window
- the value of stack pointer of the caller
- the process and thread ID of caller
- various processor architecture specific performance counters
(instructions executed, cache misses, TLB misses)

(Note that it precisely the above kinds of sources of randomness that
are used to seed cryptographic quality random number generators on
systems without special hardware for their construction.)

In addition, items such as the computer's name and the name of the
operating system, while not strictly speaking random, will help
differentiate the results from those obtained by other systems.

The exact algorithm to generate a node ID using these data is system
specific, because both the data available and the functions to obtain

them are often very system specific. However, assuming that one can
concatenate all the values from the randomness sources into a buffer,
and that a cryptographic hash function such as MD5 [3] is available,
then any 6 bytes of the MD5 hash of the buffer, with the multicast
bit (the high bit of the first byte) set will be an appropriately
random node ID.

Other hash functions, such as SHA-1 [4], can also be used. The only
requirement is that the result be suitably random _ in the sense that
the outputs from a set uniformly distributed inputs are themselves
uniformly distributed, and that a single bit change in the input can
be expected to cause half of the output bits to change.


# 回复: ASP.NET开发经验(3) --- 使用 GUID 值来作为数据库行标识 2004-3-23 16:20 jiangsheng
比较郁闷的是Access里面使用GUID很麻烦

# 回复: ASP.NET开发经验(3) --- 使用 GUID 值来作为数据库行标识 2004-3-24 23:19 色盲
Hey,堂主,今晚不知不觉又逛到你这来了,再看看这篇文章,发现昨晚我发的FEEDBACK被DEL了,好纳闷啊。。。我的FEEDBACK没有非法博客堂的规章制度,更没有违法,也没有任何对你的攻击啊。。。。只不过是我的观点和你的不一致而已。
BLOG意义何在呢?

# 回复: ASP.NET开发经验(3) --- 使用 GUID 值来作为数据库行标识 2004-3-25 9:21 moslem
TO 色盲:

我希望多些有意义的反馈,观点不一致是是可以的,但要说出你自己的理由,说出自己的观点,不能什么都不说,就“我强烈反对你的观点,或者根本不能称为观点”之类的话,这样让人怀疑你的动机。

希望我们能继续共同交流关于 GUID 的一些优缺点。



# 回复: ASP.NET开发经验(3) --- 使用 GUID 值来作为数据库行标识 2004-3-25 18:02 Forks
Guid.NewGuid()直接可以生成Guid,不需要通过sql server来生成吧,效率不高。

SqlCommand cmd = New SqlCommand();
cmd.CommandText = "SELECT NewID()";
string rowID = (string) cmd.ExecuteScalar();
cmd.CommandText = "INSERT INTO Table(ID,...) VALUES(@ID,...)
cmd.Parameters.Add("@ID",SqlDbType.UniqueIdentifier).Value = new Guid(rowID);
cmd.ExecuteNoQuery();


# 回复: ASP.NET开发经验(3) --- 使用 GUID 值来作为数据库行标识 2004-3-27 14:06 色盲
;)


# 回复: ASP.NET开发经验(3) --- 使用 GUID 值来作为数据库行标识 2004-3-30 12:04 关门放狗
好文章
我觉得唯一的缺点就是位数太长了并且无意义,每个项目,都为Row ID发愁........

# 回复: ASP.NET开发经验(3) --- 使用 GUID 值来作为数据库行标识 2004-4-7 13:28 小莫
我正在为ASP如何生成GUID烦着了,哪位大大有过这方面的经验

# 回复: ASP.NET开发经验(3) --- 使用 GUID 值来作为数据库行标识 2004-4-14 0:16 greysnake
Guid在应用中的用处大吗? 这样的一串随机数字不好记忆,也不好应用,不知道用处在什么地方。请指点 。

# 回复: ASP.NET开发经验(3) --- 使用 GUID 值来作为数据库行标识 2004-4-15 5:20 moslem
TO greysnake:

GUID 主要用在需要永久的,保持唯一的,固定长度的标识上。

例如,想在网站上发布新闻,用 news.asp?id=GUID 就可以很好地保持唯一性,如果用整数的话,会越来越大,不便于管理,而且易被非法利用(如别人可以利用程序自动里从你这里获取数据)

这次 MVP 会议的时候,MS 的自夸,他们就是大量利用 GUID 来保证了网站上不会有链接失效(Link break)。

# 回复: ASP.NET开发经验(3) --- 使用 GUID 值来作为数据库行标识 2004-4-16 23:19 greysnake
ok,thx
明白了。 为了保证应用的唯一性的方法。

# 回复: ASP.NET开发经验(3) --- 使用 GUID 值来作为数据库行标识 2004-5-14 9:56 雷俊强
若把guid列设为主键,新增加的行会按guid列的大小插入到表中的相应位置,而不是直接放在最后,当表中的大量的行时,是否影响insert性能(页分裂)?

# 回复: ASP.NET开发经验(3) --- 使用 GUID 值来作为数据库行标识 2004-5-14 10:19 雷俊强
对这个问题,我以前都是用一个表保存一个int数据,然后做一个存储过程来每次加1,这样需要先知道唯一值时通过这个存储过程取得它,然后可以再做其他处理。

这样int值都是从小到大生成的,且int处理要比string快的多。

# 回复: ASP.NET开发经验(3) --- 使用 GUID 值来作为数据库行标识 2004-5-17 15:41 Henry Wu
什么时候能共享出来学习就好呀

# 回复: ASP.NET开发经验(3) --- 使用 GUID 值来作为数据库行标识 2004-7-1 21:44 ray_linn
网卡也不保险,我这里已经发生过几次供应商刷错MAC Addres的错误了,导致有些网卡的MAC ADDRESS完全一样。 :(

# re: ASP.NET开发经验(3) --- 使用 GUID 值来作为数据库行标识 2005-1-17 13:50 ccrx
GUID 无法进行 Count() 等 SQL 计算,这个就不是很方便。

# re: ASP.NET开发经验(3) --- 使用 GUID 值来作为数据库行标识 2005-5-3 18:09 sa
SA

# re: ASP.NET开发经验(3) --- 使用 GUID 值来作为数据库行标识 2005-5-18 17:07 MA
dim GuidID as guid = guid.newguid()
请问为什么我这样生成的GUIDID会有重复值?

# re: ASP.NET开发经验(3) --- 使用 GUID 值来作为数据库行标识 2005-12-17 18:37 水泓
GUID是很好的主键标识的解决方案,可能有的程序员没有遇见过系统移植,比如以前我做过一个项目,JAVA+SqlServer架构,因一些原因需将之移植到Linux下,得用JAVA+MySQL,而很要命,在SqlServer中用到了自动编号类型的主键,移植中必须将数据导入MySQL,遇上很多的刺手问题,还好数据库的数据还不是很多,用了程序导入,数据库设计总的来说依据3范式,所以必须要程序相应解决了数据的完整性,最后幸不辱使命。

整个移植工作完毕之后,考虑了好多在数据库设计阶段的思路,总结了一些经验。
尽量运用各种常用数据库支持的通用的数据类型,尽量少用或不用自动编号数据库类型;
管理员代号+日期+时间+随机数并不是很好的解决方案,因为同样是损失的索引消耗资源,且程序实现反而不如GUID来得干脆;
不用自动编号字段做主键标识时,尽量少用/不用存储过程根据表中记录的Max(XX)获取当前的最大Int,在你往返查询-->插入数据过程中,时间好象很短,对系统来说已经过了很长时间了,可能你获取了当前应该是100,当你插入数据时,已经又条佬不知什么时候占了100了,这就存在并发的问题;
利用GUID还是解决分布式系统的好方案,在多层分布系统中,多个服务器,多个数据库,如用自动编号,则当你需要汇总数据的时候,会发现麻烦来了,主键重复,系统崩溃。

# re: ASP.NET开发经验(3) --- 使用 GUID 值来作为数据库行标识 2006-2-1 11:47 单凯
获益匪浅,但仍不知如何使用

# re: ASP.NET开发经验(3) --- 使用 GUID 值来作为数据库行标识 2006-2-14 11:45 小灰
还是比较迷惑,如果GUID做了索引究竟能比自动增长的效率低多少?还有在开发的时候要注意哪些问题,楼主没有交代呀?

# re: ASP.NET开发经验(3) --- 使用 GUID 值来作为数据库行标识 2006-6-16 11:37 五根草
请教
STRING 转换为GUID 的方法

# re: ASP.NET开发经验(3) --- 使用 GUID 值来作为数据库行标识 2006-6-21 16:18 YapEro
string strIn = "..........";
Guid guid = new Guid(strIn);

# 使用 GUID 值来作为数据库行标识(zz) 2006-7-15 9:16 stu_acer
转载自:http://blog.joycode.com/moslem/archive/2004/03/23/16930.aspx GUID(Globaluniqueidentifier)全局唯一...

# re: ASP.NET开发经验(3) --- 使用 GUID 值来作为数据库行标识 2006-9-1 13:44 zcj
同1台机器产生的guid会相同码?

# 使用 GUID 值来作为数据库行标识 2006-9-19 11:35 Scott
GUID(Global unique identifier)全局唯一标识符,它是由网卡上的标识数字(每个网卡都有唯一的标识号)以及 CPU 时钟的唯一数字生成的的一个 16 字节的二进制值。

# re: ASP.NET开发经验(3) --- 使用 GUID 值来作为数据库行标识 2006-11-13 23:51 过客
说一下自已的一点想法:
(1)对于程序员来说,可能系统移植是很少碰到的,因为开发系统时应该事先都定好了相关开发环境及安装环境,环境改变的情况应该比较少
(2)引用:便于数据库初始化,如果应用程序要加载一些初始数据, IDENTITY 列的处理方式就比较麻烦,而 uniqueidentifier 列则无需任何处理,直接用 T-SQL 加载即可
观点:不会麻烦,因为SQL SERVER中有一个全局的参数@@IDENTITY 可以使用,另外水泓所说的数据并发问题,可以用事务来解决这个问题
(3)几个问题:1、如果GUID做了索引究竟能比自动增长的效率低多少?
2、如果是大型的系统,如电信、烟草之类的,他们的数据库中的唯一标识字段是否是用GUID?

# re: ASP.NET开发经验(3) --- 使用 GUID 值来作为数据库行标识 2006-11-14 17:59 llafei
分布式系统中作为ID应为一个很好的选择
我觉得简单的讲应为:如你有一个系统,即可联机服务器操作,也可脱机服务器工作站操作,并可随时把脱机数据上传到服务器,也可随时把服务器的数据下载更新到工作站机,那么在关系数据表中关联ID就需要一个唯一的ID,不论是那个工作站产生的ID,都需唯一,以便相互关联,在数据上传服务器的库中也可以用这个ID作为唯一关联ID使用,即使数据库合并也不会有ID重复和或关联丢失的出现.............算了,我是菜鸟,我也讲不明白了...只是这样理解...................

增加评论

标题: 姓名: Url: 校验码 评论: 
   
<script src="http://www.google-analytics.com/urchin.js" type="text/javascript"></script> # 回复: ASP.NET开发经验(3) --- 使用 GUID 值来作为数据库行标识 2004-3-23 11:39 开心就好