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

1. C# 对Guid结构类型的处理:

  声明Guid变量,并设置初始值:
    Guid varGuid = Guid.NewGuid(); //具体的值
    Guid varGuid = Guid.Empty;     //各位都是0. 注意: Guid是值类型,所以不能设置成null.除非设置成Guid?(Guid可空类型)

  把字符串转换成Guid:
    string guidStr = Guid.NewGuid().ToString();  //把Guid转换成字符串
    Guid varGuid = new Guid(guidStr);            //把字符串转换成Guid

  把字节数组转换成Guid:
    Guid varGuid = new Guid(byteArray);


2. GUID 在数据库中的两种存储方式 和 OpenFx框架对Guid类型的处理方式:

   对于GUID类型数据(是一个128位的整数(16字节)),在数据库中有两种存储方式,

   MS SQL Server: 可以是uniqueidentifier,也可以是Varchar(36)。
       所以对于不是GUID的varchar类型,长度不要设成36,可设成40等。
       MS SQL Server可以用newid()系统函数给uniqueidentifier类型字段设置默认值.
       最好用uniqueidentifier,一则节省存储空间,二则计算机对整数的处理比对字符串的处理速度更快。

   Oracle: 可以是RAW(16),也可以是Varchar2(36) 。
       所以对于不是GUID的RAW类型,长度不要设成16,可设成20等; 对于不是GUID的varchar2类型,长度不要设成36,可设成40等。
       最好用RAW(16),一则节省存储空间,二则计算机对整数(2进制)的处理比对字符串的处理速度更快。

   ORACLE 可以用SYS_GUID()系统函数取得一个Guid, 但是字符顺序跟windows系统不一样.

   Oracle中如果存为RAW(16)类型,里面没有”-“符号,且字符顺序跟windows系统不一样,数据不能直接转换成MS SQL的uniqueidentifier类型,
   但是占用空间少(16bytes)。如果存为varchar2(36)类型,且用C#的Guid.NewGuid()赋值,则能直接转换成MS SQL的uniqueidentifier类型,但是占用空间稍多(36bytes)。

3. 另外一点Oracle的使用经验: Oracle中字段的默认值 可以设置成系统函数,但是不能设置成用户自定义函数();
   Oracle中如果GUID字段存为RAW(16)类型,则可以设置默认值为SYS_GUID()。(推荐用这种方式)
如果GUID字段存为varchar2(36)类型,如果要跟windows的GUID格式相同,则不能把字段的默认值设置成
   pkg_common.To_Win_Guid(SYS_GUID()),
   只能在前台用C# 给Guid字段赋值,或者用上面的函数pkg_common.To_Win_Guid(SYS_GUID()) 在SQL语句中赋值。

4. 另外,设置数据库的默认值,必须同时设置字段NOT NULL,默认值才起作用! 我发现这个规则很多同仁不知道,结果设了默认值没有作用!

5. 用GUID类型的列(Column)作主键的表,建立主键时,不要建立成簇索引(Clustered index),而是建成普通的唯一索引。
   因为表中数据行是按照簇索引的顺序存储的,而GUID没有固定顺序,如果对GUID字段建立簇索引,则会频繁的往表的中间
   插入数据行,挤得后面的数据页迁移而导致性能降低。而建成普通的唯一索引则不会引起此问题。

   如果设置成Primary Key,要把Create As Clustered选项设置成No!(即不要建立成簇索引)

   
 6.另外特别提醒一下:Oracle产生的GUID类型的字符串排列顺序 跟Windows系统的GUID不同,两者不能直接转换,于是在
   OpenFx.CommonUtil类中定义了一个方法来转换: To_Win_Guid(string oracleGuidString),从Oracle的GUID类型的字符串
   返回Windows的Guid结构类型。

   同时提供两个将Oracle GUID 转换成Windows系统的Guid的自定义函数:

   (注意:internet网上也可以搜到这样的函数,但是是错误的,大家不要以讹传讹,以我下面经过工程检验的为准)

CREATE OR REPLACE PACKAGE BODY pkg_common IS

  /*===========================================================================
  Author:      LiuFuhuang
  Create date: 2010-09-15
  Description: 产生一个Windows格式的GUID字符串{8-4-4-4-12}(将Oracle的SYS_GUID()返回的GUID 转换成Windows格式的GUID字符串)
               注意:Oracle的GUID类型的字符串排列顺序 跟Windows系统的GUID不同,两者不能直接转换.
  Parameter:
  To Call  : select pkg_common.ufn_get_win_guid() from dual
  ===========================================================================*/
function ufn_get_win_guid return varchar2 is
  v_guid varchar(32);
  v_winGuidStr varchar(36);
begin
  v_guid := SYS_GUID();
 
  --注意:Oracle的SUBSTR(startPosition,length),startPosition是从1开始的,而C#是从0开始的
  v_winGuidStr :=
    substr(v_guid,7,2) ||
    substr(v_guid,5,2) ||
    substr(v_guid,3,2) ||
    substr(v_guid,1,2) || '-' ||
    substr(v_guid,11,2) ||
    substr(v_guid,9,2) || '-' ||
    substr(v_guid,15,2) ||
    substr(v_guid,13,2) || '-' ||
    substr(v_guid,17,4) || '-' ||
    substr(v_guid,21,12);
  return v_winGuidStr;
end ;

  /*===========================================================================
  Author:      LiuFuhuang
  Create date: 2010-09-15
  Description: 将Oracle产生的GUID字符串 转换成Windows格式的GUID字符串{8-4-4-4-12}
               注意:Oracle的GUID类型的字符串排列顺序 跟Windows系统的GUID不同,两者不能直接转换.
  Parameter:
  To Call  : select pkg_common.ufn_to_win_guid(SYS_GUID()) from dual
  ===========================================================================*/
function ufn_to_win_guid (oracleGuidStr   VARCHAR2) return varchar2 is
  v_guid varchar(32);
  v_winGuidStr varchar(36);
begin
  v_guid := oracleGuidStr;
 
  --注意:Oracle的SUBSTR(startPosition,length),startPosition是从1开始的,而C#是从0开始的
  v_winGuidStr :=
    substr(v_guid,7,2) ||
    substr(v_guid,5,2) ||
    substr(v_guid,3,2) ||
    substr(v_guid,1,2) || '-' ||
    substr(v_guid,11,2) ||
    substr(v_guid,9,2) || '-' ||
    substr(v_guid,15,2) ||
    substr(v_guid,13,2) || '-' ||
    substr(v_guid,17,4) || '-' ||
    substr(v_guid,21,12);
  return v_winGuidStr;
end ;

end;

7.  C#代码:
    /// <summary>
    /// 从Oracle 的RAW(16)类型存储的GUID值,取出到DataTable或者DataReader之后是字节数组,转成Guid。
    /// 或者MS SQL的Guid,取出到DataTable之后转成Guid。
    /// </summary>
    /// <param name="guidValue"></param>
    /// <returns>如果不是合法的Guid值,则返回Guid.Empty</returns>
    public static Guid GetGuid(object guidValue) {
        if (guidValue is byte[]) {
            return new Guid((byte[])guidValue);
        }
        else if (guidValue is Guid){
            return (Guid)guidValue;
        }
        else if (guidValue is string) {
            return new Guid(guidValue.ToString());
        }
        else {
            return Guid.Empty;
        }
    }

8. 在MS Accesss2003数据库中,要使用GUID数据,有三种存储方式:
   方式1: 设计表时,如列名User_Guid,数据类型设置成AutoNumber, FieldSize设置成Replication ID(同步复制ID),
          这样该列数据的默认值就会是GUID值,对应的实体类属性类型为Guid。一般用来表示GUID型的唯一索引值。

   方式2: 设计表时,如列名Dept_Guid,数据类型设置成Number, FieldSize设置成Replication ID(同步复制ID),
          不会有默认值,对应的实体类属性类型为Guid。一般表示GUID型的外键关联字段。

   方式3: 用Text(36)来保存GUID值。只能通过编程方式从前端插入GUID值。

9. Java中,在java.util.UUID是1.5中新增的一个类:
   import java.util.UUID;
   UUID uuid = UUID.randomUUID();  //生成一个随机的GUID/UUID(Universally Unique Identifier)

10.MySQL中用BINARY(16)来保存GUID,插入数据库时,要先转成字节数组。

    在数据库中,查询出来时,可以先用hex(),函数转成16进制的字符串,这个字符串的排列形式跟Oracle中的GUID相同。

    在C#中用DataTable/DataReader查询出来时,是字节数组,可以用Guid varGuid = new Guid(column["guid_col_name"]);的方式转换成C#的GUID.

 


=========================
GUID是一个128位长的数字,一般用16进制表示。算法的核心思想是结合机器的网卡、当地时间、一个随即数来生成GUID。从理论上讲,如果一台机器每秒产生10000000个GUID,则可以保证(概率意义上)3240年不重复。

UUID是指在一台机器上生成的数字,它保证对在同一时空中的所有机器都是唯一的。通常平台会提供生成UUID的API。UUID按照开放软件基金会(OSF)制定的标准计算,用到了以太网卡地址、纳秒级时间、芯片ID码和许多可能的数字。由以下几部分的组合:当前日期和时间(UUID的第一个部分与时间有关,如果你在生成一个UUID之后,过几秒又生成一个UUID,则第一个部分不同,其余相同),时钟序列,全局唯一的IEEE机器识别号(如果有网卡,从网卡获得,没有网卡以其他方式获得),UUID的唯一缺陷在于生成的结果串会比较长。关于UUID这个标准使用最普遍的是微软的GUID(Globals Unique Identifiers)。

UUID含义是通用唯一识别码 (Universally Unique Identifier),这 是一个软件建构的标准,也是被开源软件基金会 (Open Software Foundation, OSF) 的组织在分布式计算环境 (Distributed Computing Environment, DCE) 领域的一部份。UUID 的目的,是让分布式系统中的所有元素,都能有唯一的辨识资讯,而不需要透过中央控制端来做辨识资讯的指定。如此一来,每个人都可以建立不与其它人冲突的 UUID。在这样的情况下,就不需考虑数据库建立时的名称重复问题。目前最广泛应用的 UUID,即是微软的 Microsoft's Globally Unique Identifiers (GUIDs),而其他重要的应用,则有 Linux ext2/ext3 档案系统、LUKS 加密分割区、GNOME、KDE、Mac OS X 等等。


-----------------
  UUID由以下几部分的组合:

  (1)当前日期和时间,UUID的第一个部分与时间有关,如果你在生成一个UUID之后,过几秒又生成一个UUID,则第一个部分不同,其余相同。

  (2)时钟序列

  (3)全局唯一的IEEE机器识别号,如果有网卡,从网卡MAC地址获得,没有网卡以其他方式获得。

  UUID的唯一缺陷在于生成的结果串会比较长。关于UUID这个标准使用最普遍的是微软的GUID(Globals Unique Identifiers)。在ColdFusion中可以用CreateUUID()函数很简单的生成UUID,其格式为:xxxxxxxx-xxxx- xxxx-xxxxxxxxxxxxxxxx(8-4-4-16),其中每个 x 是 0-9 或 a-f 范围内的一个十六进制的数字。而标准的UUID格式为:xxxxxxxx-xxxx-xxxx-xxxxxx-xxxxxxxxxx (8-4-4-4-12),可以从cflib 下载CreateGUID() UDF进行转换。

  使用UUID的好处在分布式的软件系统中(比如:DCE/RPC, COM+,CORBA)就能体现出来,它能保证每个节点所生成的标识都不会重复,并且随着WEB服务等整合技术的发展,UUID的优势将更加明显。根据使用的特定机制,UUID不仅需要保证是彼此不相同的,或者最少也是与公元3400年之前其他任何生成的通用惟一标识符有非常大的区别。

  通用惟一标识符还可以用来指向大多数的可能的物体。微软和其他一些软件公司都倾向使用全球惟一标识符(GUID),这也是通用惟一标识符的一种类型,可用来指向组建对象模块对象和其他的软件组件。第一个通用惟一标识符是在网罗计算机系统(NCS)中创建,并且随后成为开放软件基金会(OSF)的分布式计算环境(DCE)的组件。

posted on 2013-04-14 11:13  tonyliu889  阅读(3141)  评论(0)    收藏  举报