关于UUID和GUID,教你如何使用JDK自带的UUID生成主键。

guid: 采用数据库底层的guid算法机制,对应MYSQL的uuid()函数,SQL Server的newid()函数,ORACLE的rawtohex(sys_guid())函数等。

uuid.hex: 看uuid,建议用uuid替换。


UUID是一个由4个连字号(-)将32个字节长的字符串分隔后生成的字符串,总共36个字节长。比如:550e8400-e29b-41d4-a716-446655440000

http://gohands.blogbus.com/logs/147479174.html

GUID 是微软对UUID这个标准的实现。UUID是由开放软件基金会(OSF)定义的。UUID还有其它各种实现,不止GUID一种。比如我们这里在Java中用到的。

http://baike.baidu.com/view/1052579.htm

COMB(combine)型是数据库特有的一种设计思想,可以理解为一种改进的GUID,它通过组合GUID和系统时间,以使其在索引和检索事有更优的性能。
http://blog.csdn.net/happyflystone/article/details/1903854

数据库中没有COMB类型,它是Jimmy Nilsson在他的“The Cost of GUIDs as Primary Keys”一文中设计出来的。

COMB数据类型的基本设计思路是这样的:既然UniqueIdentifier数据因毫无规律可言造成索引效率低下,影响了系统的性能,那么我们 能不能通过组合的方式,保留UniqueIdentifier的前10个字节,用后6个字节表示GUID生成的时间(DateTime),这样我们将时间 信息与UniqueIdentifier组合起来,在保留UniqueIdentifier的唯一性的同时增加了有序性,以此来提高索引效率。

http://hi.baidu.com/%CA%AB%D5%B9/blog/item/407fd23f77d5eacf7c1e7122.html


Foreground Knowledge About GUID and UUID.

UUID

通用惟一标识符(UUID)是128位比特的数字,用来惟一地标识因特网上的某些对象或者实体。

A Universally Unique Identifier is an identifier standard used in software construction, standardized by the Open Software Foundation (OSF) as part of the Distributed Computing Environment (DCE). The intent of UUIDs is to enable distributed systems to uniquely identify information without significant central coordination. Thus, anyone can create a UUID and use it to identify something with reasonable confidence that the identifier will never be unintentionally used by anyone for anything else. Information labelled with UUIDs can therefore be later combined into a single database without need to resolve name conflicts. The most widespread use of this standard is in Microsoft's Globally Unique Identifiers (GUIDs) which implement this standard.

一个UUID 是一个标识符标准用于软件架构,是由开放软件基金会(OSF)作为分布式计算环境(DCE)的一部分而制定的标准。UUIDs的目的就是使分布式系统可以不需要重要的中央调合系统而能唯一地标识信息。这样,任何人能创造一个UUID 和使用它来标识一些东西,而且,你有足够的信心来确定这个标识是永远不会被任何人无意地使用在任何东西上。因此,信息加上了UUID标签就能合并到单个数据库中而不用去解决命名冲突的问题。这个标准的广泛应用在微软的全球唯一标识符(GUIDs)上,GUID实现了这个标准。

A UUID is essentially a 16-byte number and in its canonical form a UUID may look like this:

:550E8400-E29B-11D4-A716-446655440000

And has this structure in the C programming language:

typedef struct {
unsigned32 time_low;
unsigned16 time_mid;
unsigned16 time_hi_and_version;
unsigned8 clock_seq_hi_and_reserved;
unsigned8 clock_seq_low;
byte node6;
} uuid_t;

The J2SE 5.0 release of Java provides a class that will produce 128-bit UUIDs. The API documentation for the class refers to ISO/IEC 11578:1996.

关于UUID的定义,详细内容可参考http://www.ietf.org/rfc/rfc4122.txt,文档里面还有C语言对UUID标准的各种实现。

GUID

A Globally Unique Identifier or GUID is a pseudo-random number used in software applications. While each generated GUID is not guaranteed to be unique, the total number of unique keys (2128 or 3.4028×1038) is so large that the possibility of the same number being generated twice is very small.

一个全球唯一标识符 或 GUID 是一个假随机数用于软件中。虽然每个产生的GUID是不保证唯一的,但不同的标识符总数是(2128 也就是3.4028×1038)如此之大,以至于相同的数字被产生两次的机率是很相当小的。

The GUID is an implementation by Microsoft of a standard called Universally Unique Identifier (UUID), specified by the Open Software Foundation (OSF).

GUID 是微软对UUID这个标准的实现。UUID是由开放软件基金会(OSF)定义的。

UUID还有其它各种实现,不止GUID一种,其它的在此不详细说明。


介绍完了,那么在我们自己的程序 中怎么使用呢。很简单。

使用方法如下:

package com.sinoglobal.utils;
import java.util.UUID;

/**
 * 生成UUID随机字符串的工具类
 * 
 * @author lz
 * 
 */
public class UUIDUtils
{

	/**
	 * 获得一个UUID
	 * 
	 * @return String UUID
	 */
	public static String getUUID()
	{
		return UUID.randomUUID().toString().replaceAll("-", "");
	}

	/**
	 * 获得指定数目的UUID
	 * 
	 * @param number
	 *            int 需要获得的UUID数量
	 * @return String[] UUID数组
	 */
	public static String[] getUUID(int number)
	{
		if (number < 1)
		{
			return null;
		}
		String[] ss = new String[number];
		for (int i = 0; i < number; i++)
		{
			ss[i] = getUUID();
		}
		return ss;
	}

	public static void main(String[] args)
	{
		System.out.println("::" + UUIDUtils.getUUID());
		String[] ss = getUUID(10);
		for (int i = 0; i < ss.length; i++)
		{
			System.out.println(ss[i]);
		}
	}
}
控件台打印如下:

::2e54a4a02f634ceda0dba5ebb60e9a37
cf6ef857a16c4cc9a7383342e9ef9542
17ba6479198041c0ad614a700dbb2bb0
6466053a4af148449a08eaeebbf936ff
26a5d190e71f405f8fa2701223317e3c
f2781866129244dc83d49f03075711d6
20ef4c4e92374ab59095a292635ddc2c
b27226eb131c41b7a1cb307c72b6c139
60f3af219caa4d739ae4dad12c67b8be
3bae0612534a4692a3f00775065d7425
66de7ac626f94368a390e8024fb1fe39

当然,SQL,Oracle,MySQL都有类似这样的东东,SQL中使用newid()函数就可以得到。

不过一般情况我们会这么做。那就是给表的主键设置默认值。

如下:

(lower(replace(newid(),'-','')))

它的作用很简单,就是去掉了中间的-,把所有字母的都变为小写而已。


有兴趣的话可以研究下下面的东东。

Implementation in Java.

Before JDK 5.0

1.http://jug.safehaus.org

JUG is a pure java UUID generator, that can be used either as a component in a bigger application, or as a standalone command line tool (a la 'uuidgen').

org.safehaus.uuid.UUID _uuid = UUIDGenerator.getInstance().generateTimeBasedUUID();
System.out.println(_uuid + " the length is:" + _uuid.toString().length());

_uuid = UUIDGenerator.getInstance().generateRandomBasedUUID();
System.out.println(_uuid + " the length is:" + _uuid.toString().length());

2.jakarta commons sandbox id

//not avaliable in binary release in Jul 18, 2007

3.UUIDHexGenerator in Hibernate.

//havn't tried it.

4.A widely source code based on the MD5 hashing algorithm in the internet.

/**
* @author Administrator
*
* TODO To change the template for this generated type comment go to
* Window - Preferences - Java - Code Style - Code Templates
*/
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Random;

public class RandomGUID extends Object {
protected final org.apache.commons.logging.Log logger = org.apache.commons.logging.LogFactory
.getLog(getClass());

public String valueBeforeMD5 = "";
public String valueAfterMD5 = "";
private static Random myRand;
private static SecureRandom mySecureRand;

private static String s_id;
private static final int PAD_BELOW = 0x10;
private static final int TWO_BYTES = 0xFF;

/*
* Static block to take care of one time secureRandom seed.
* It takes a few seconds to initialize SecureRandom. You might
* want to consider removing this static block or replacing
* it with a "time since first loaded" seed to reduce this time.
* This block will run only once per JVM instance.
*/

static {
mySecureRand = new SecureRandom();
long secureInitializer = mySecureRand.nextLong();
myRand = new Random(secureInitializer);
try {
s_id = InetAddress.getLocalHost().toString();
} catch (UnknownHostException e) {
e.printStackTrace();
}

}


/*
* Default constructor. With no specification of security option,
* this constructor defaults to lower security, high performance.
*/
public RandomGUID() {
getRandomGUID(false);
}

/*
* Constructor with security option. Setting secure true
* enables each random number generated to be cryptographically
* strong. Secure false defaults to the standard Random function seeded
* with a single cryptographically strong random number.
*/
public RandomGUID(boolean secure) {
getRandomGUID(secure);
}

/*
* Method to generate the random GUID
*/
private void getRandomGUID(boolean secure) {
MessageDigest md5 = null;
StringBuffer sbValueBeforeMD5 = new StringBuffer(128);

try {
md5 = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException e) {
logger.error("Error: " + e);
}

try {
long time = System.currentTimeMillis();
long rand = 0;

if (secure) {
rand = mySecureRand.nextLong();
} else {
rand = myRand.nextLong();
}
sbValueBeforeMD5.append(s_id);
sbValueBeforeMD5.append(":");
sbValueBeforeMD5.append(Long.toString(time));
sbValueBeforeMD5.append(":");
sbValueBeforeMD5.append(Long.toString(rand));

valueBeforeMD5 = sbValueBeforeMD5.toString();
md5.update(valueBeforeMD5.getBytes());

byte[] array = md5.digest();
StringBuffer sb = new StringBuffer(32);
for (int j = 0; j < array.length; ++j) {
int b = array[j] & TWO_BYTES;
if (b < PAD_BELOW)
sb.append('0');
sb.append(Integer.toHexString(b));
}

valueAfterMD5 = sb.toString();

} catch (Exception e) {
logger.error("Error:" + e);
}
}

/*
* Convert to the standard format for GUID
* (Useful for SQL Server UniqueIdentifiers, etc.)
* Example: C2FEEEAC-CFCD-11D1-8B05-00600806D9B6
*/
public String toString() {
String raw = valueAfterMD5.toUpperCase();
StringBuffer sb = new StringBuffer(64);
sb.append(raw.substring(0, 8));
sb.append("-");
sb.append(raw.substring(8, 12));
sb.append("-");
sb.append(raw.substring(12, 16));
sb.append("-");
sb.append(raw.substring(16, 20));
sb.append("-");
sb.append(raw.substring(20));

return sb.toString();
}


// Demonstraton and self test of class
public static void main(String args[]) {
for (int i=0; i< 100; i++) {
RandomGUID myGUID = new RandomGUID();
System.out.println("Seeding String=" + myGUID.valueBeforeMD5);
System.out.println("rawGUID=" + myGUID.valueAfterMD5);
System.out.println("RandomGUID=" + myGUID.toString());
}
}


}


  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值