有时我们不依赖于数据库中自动递增的字段产生唯一ID,比如多表同一字段需要统一一个唯一ID,这时就需要用程序来生成一个唯一的全局ID,然后在数据库事务中同时插入到多章表中实现同步.

在java中有个类工具很好的实现产生唯一ID(UUID),但是由数字和字母及中划线组成的,故数据库字段应该设置为char 并相应的建立索引.

UUID是128位整数(16字节)的全局唯一标识符(Universally Unique Identifier).
指在一台机器上生成的数字,它保证对在同一时空中的所有机器都是唯一的.通常平台会提供生成UUID的API.UUID按照开放软件基金会(OSF)制定的标准计算,用到了以太网卡地址,纳秒级时间,芯片ID码和许多可能的数字.由以下几部分的组合:当前日期和时间(UUID的第一个部分与时间有关,如果你在生成一个 UUID之后,过几秒又生成一个UUID,则第一个部分不同,其余相同),时钟序列,全局唯一的IEEE机器识别号(如果有网卡,从网卡获得,没有网卡以其他方式获得),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的更多信息可以多google 一下.

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

JDK1.5
如果使用的JDK1.5的话,那么生成UUID变成了一件简单的事,以为JDK实现了UUID:
java.util.UUID, 直接调用即可.

UUID uuid = UUID.randomUUID();
String s = UUID.randomUUID().toString();//用来生成数据库的主键id非常不错..

 
Java代码 
  1. package com.taobao.tddl.client.util;
  2. import java.io.IOException;
  3. import java.io.UnsupportedEncodingException;
  4. import java.net.InetAddress;
  5. import java.security.MessageDigest;
  6. import java.security.NoSuchAlgorithmException;
  7. import java.security.SecureRandom;
  8. import java.util.HashMap;
  9. import java.util.Map;
  10. import java.util.Random;
  11. import java.util.concurrent.atomic.AtomicLong;
  12. import java.util.concurrent.locks.ReentrantLock;
  13. /**
  14. * @author huangshang
  15. *
  16. */
  17. public class UniqId {
  18. private static char[] digits = { '0', '1', '2', '3', '4', '5', '6', '7',
  19. '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
  20. private static Map<Character, Integer> rDigits = new HashMap<Character, Integer>(
  21. 16);
  22. static {
  23. for (int i = 0; i < digits.length; ++i) {
  24. rDigits.put(digits[i], i);
  25. }
  26. }
  27. private static UniqId me = new UniqId();
  28. private String hostAddr;
  29. private Random random = new SecureRandom();
  30. private MessageDigest mHasher;
  31. private UniqTimer timer = new UniqTimer();
  32. private ReentrantLock opLock = new ReentrantLock();
  33. private UniqId() {
  34. try {
  35. InetAddress addr = InetAddress.getLocalHost();
  36. hostAddr = addr.getHostAddress();
  37. } catch (IOException e) {
  38. hostAddr = String.valueOf(System.currentTimeMillis());
  39. }
  40. if (hostAddr == null || hostAddr.length() == 0
  41. || "127.0.0.1".equals(hostAddr)) {
  42. hostAddr = String.valueOf(System.currentTimeMillis());
  43. }
  44. try {
  45. mHasher = MessageDigest.getInstance("MD5");
  46. } catch (NoSuchAlgorithmException nex) {
  47. mHasher = null;
  48. }
  49. }
  50. /**
  51. * 获取UniqID实例
  52. *
  53. * @return UniqId
  54. */
  55. public static UniqId getInstance() {
  56. return me;
  57. }
  58. /**
  59. * 获得不会重复的毫秒数
  60. *
  61. * @return
  62. */
  63. public long getUniqTime() {
  64. return timer.getCurrentTime();
  65. }
  66. /**
  67. * 获得UniqId
  68. *
  69. * @return uniqTime-randomNum-hostAddr-threadId
  70. */
  71. public String getUniqID() {
  72. StringBuffer sb = new StringBuffer();
  73. long t = timer.getCurrentTime();
  74. sb.append(t);
  75. sb.append("-");
  76. sb.append(random.nextInt(8999) + 1000);
  77. sb.append("-");
  78. sb.append(hostAddr);
  79. sb.append("-");
  80. sb.append(Thread.currentThread().hashCode());
  81. return sb.toString();
  82. }
  83. /**
  84. * 获取MD5之后的uniqId string
  85. *
  86. * @return uniqId md5 string
  87. */
  88. public String getUniqIDHashString() {
  89. return hashString(getUniqID());
  90. }
  91. /**
  92. * 获取MD5之后的uniqId
  93. *
  94. * @return byte[16]
  95. */
  96. public byte[] getUniqIDHash() {
  97. return hash(getUniqID());
  98. }
  99. /**
  100. * 对字符串进行md5
  101. *
  102. * @param str
  103. * @return md5 byte[16]
  104. */
  105. public byte[] hash(String str) {
  106. opLock.lock();
  107. try {
  108. byte[] bt = mHasher.digest(str.getBytes("UTF-8"));
  109. if (null == bt || bt.length != 16) {
  110. throw new IllegalArgumentException("md5 need");
  111. }
  112. return bt;
  113. } catch (UnsupportedEncodingException e) {
  114. throw new RuntimeException("unsupported utf-8 encoding", e);
  115. } finally {
  116. opLock.unlock();
  117. }
  118. }
  119. /**
  120. * 对二进制数据进行md5
  121. *
  122. * @param str
  123. * @return md5 byte[16]
  124. */
  125. public byte[] hash(byte[] data) {
  126. opLock.lock();
  127. try {
  128. byte[] bt = mHasher.digest(data);
  129. if (null == bt || bt.length != 16) {
  130. throw new IllegalArgumentException("md5 need");
  131. }
  132. return bt;
  133. } finally {
  134. opLock.unlock();
  135. }
  136. }
  137. /**
  138. * 对字符串进行md5 string
  139. *
  140. * @param str
  141. * @return md5 string
  142. */
  143. public String hashString(String str) {
  144. byte[] bt = hash(str);
  145. return bytes2string(bt);
  146. }
  147. /**
  148. * 对字节流进行md5 string
  149. *
  150. * @param str
  151. * @return md5 string
  152. */
  153. public String hashBytes(byte[] str) {
  154. byte[] bt = hash(str);
  155. return bytes2string(bt);
  156. }
  157. /**
  158. * 将一个字节数组转化为可见的字符串
  159. *
  160. * @param bt
  161. * @return
  162. */
  163. public String bytes2string(byte[] bt) {
  164. int l = bt.length;
  165. char[] out = new char[l << 1];
  166. for (int i = 0, j = 0; i < l; i++) {
  167. out[j++] = digits[(0xF0 & bt[i]) >>> 4];
  168. out[j++] = digits[0x0F & bt[i]];
  169. }
  170. return new String(out);
  171. }
  172. /**
  173. * 将字符串转换为bytes
  174. *
  175. * @param str
  176. * @return byte[]
  177. */
  178. public byte[] string2bytes(String str) {
  179. if (null == str) {
  180. throw new NullPointerException("参数不能为空");
  181. }
  182. if (str.length() != 32) {
  183. throw new IllegalArgumentException("字符串长度必须是32");
  184. }
  185. byte[] data = new byte[16];
  186. char[] chs = str.toCharArray();
  187. for (int i = 0; i < 16; ++i) {
  188. int h = rDigits.get(chs[i * 2]).intValue();
  189. int l = rDigits.get(chs[i * 2 + 1]).intValue();
  190. data[i] = (byte) ((h & 0x0F) << 4 | (l & 0x0F));
  191. }
  192. return data;
  193. }
  194. /**
  195. * 实现不重复的时间
  196. *
  197. * @author dogun
  198. */
  199. private static class UniqTimer {
  200. private AtomicLong lastTime = new AtomicLong(System.currentTimeMillis());
  201. public long getCurrentTime() {
  202. return this.lastTime.incrementAndGet();
  203. }
  204. }
  205. }
 
 
 

java唯一ID生成的更多相关文章

  1. 关于全局唯一ID生成方法

    引:最近业务开发过程中需要涉及到全局唯一ID生成.之前零零总总的收集过一些相关资料,特此整理以便后用 本博客已经迁移至:http://cenalulu.github.io/ 本篇博文已经迁移,阅读全文 ...

  2. 【系统设计】分布式唯一ID生成方案总结

    目录 分布式系统中唯一ID生成方案 1. 唯一ID简介 2. 全局ID常见生成方案 2.1 UUID生成 2.2 数据库生成 2.3 Redis生成 2.4 利用zookeeper生成 2.5 雪花算 ...

  3. 分布式系统唯一ID生成方案

    分布式系统唯一ID生成方案汇总 数据库自增主键 最常见的方式.利用数据库,全数据库唯一. 优点: 1)简单,代码方便,性能可以接受. 2)数字ID天然排序,对分页或者需要排序的结果很有帮助. 缺点: ...

  4. 开源项目|Go 开发的一款分布式唯一 ID 生成系统

    原文连接: 开源项目|Go 开发的一款分布式唯一 ID 生成系统 今天跟大家介绍一个开源项目:id-maker,主要功能是用来在分布式环境下生成唯一 ID.上周停更了一周,也是用来开发和测试这个项目的 ...

  5. 分布式唯一ID生成服务

    SNService是一款基于分布式的唯一ID生成服务,主要用于提供大数量业务数据建立唯一ID的需要;服务提供最低10K/s的唯一ID请求处理.如果你部署服务的CPU资源达到4核的情况下那该服务最低可以 ...

  6. 分布式系统的唯一id生成算法你了解吗?

    在分库分表之后你必然要面对的一个问题,就是id咋生成? 因为要是一个表分成多个表之后,每个表的id都是从1开始累加自增长,那肯定不对啊. 举个例子,你的订单表拆分为了1024张订单表,每个表的id都从 ...

  7. 分布式系统唯一ID生成方案汇总【转】

    转自:http://www.cnblogs.com/haoxinyue/p/5208136.html 系统唯一ID是我们在设计一个系统的时候常常会遇见的问题,也常常为这个问题而纠结.生成ID的方法有很 ...

  8. 分布式唯一ID生成算法-雪花算法

    在我们的工作中,数据库某些表的字段会用到唯一的,趋势递增的订单编号,我们将介绍两种方法,一种是传统的采用随机数生成的方式,另外一种是采用当前比较流行的“分布式唯一ID生成算法-雪花算法”来实现. 一. ...

  9. (4.24)【mysql、sql server】分布式全局唯一ID生成方案

    参考:分布式全局唯一ID生成方案:https://blog.csdn.net/linzhiqiang0316/article/details/80425437 分表生成唯一ID方案 sql serve ...

随机推荐

  1. C++的虚函数

    1 多态产生的背景  希望同一个方法在派生类和基类中的行为是不同的,换句话来说,方法的行为取决于调用该方法的对象. 2 解决多态的两种方法  1)在派生类中重新定义基类的方法  2)使用虚方法 3 虚 ...

  2. Codeforces 1072 C - Cram Time

    C - Cram Time 思路:首先找到最大的x,使得x*(x+1)/2 <= a+b 那么一定存在一种分割使得 a1 <= a 且 b1 <= b 证明: 从x 到 1枚举过去, ...

  3. WPF程序开发方法小总结

    1.先做静态界面(静态界面带有 示例 数据---> 展示布局效果) 2.然后在VM写完之后,再对静态界面绑定数据源属性

  4. Entity Framework 学习

    Entity Framework 学习初级篇1--EF基本概况 Entity Framework 学习初级篇2--ObjectContext.ObjectQuery.ObjectStateEntry. ...

  5. 腾讯tOS死亡或注定,为何国内无自主ROM?

    http://tech.sina.com.cn/roll/2017-06-26/doc-ifyhmtrw4006354.shtml 腾讯OS死亡或注定,为何国内无自主ROM? 2017年06月26日 ...

  6. Div不用float布局

    CSS代码 .wrapper1_4 { width: 100%; /* 也可以固定宽度 */ height: 26px; } .wrapper1_4 > .left { display: inl ...

  7. 完整的Django入门指南学习笔记4

    前言 这一章节将会全面介绍 Django 的身份认证系统,我们将实现注册.登录.注销.密码重置和密码修改的整套流程. 同时你还会了解到如何保护某些试图以防未授权的用户访问,以及如何访问已登录用户的个人 ...

  8. Vue之单文件组件的数据传递,axios请求数据及路由router

    1.传递数据 例如,我们希望把父组件的数据传递给子组件. 可以通过props属性来进行传递. 传递数据三个步骤: 步骤1:在父组件中,调用子组件的组名处,使用属性值的方式往下传递数据 <Menu ...

  9. 20165309 实验三 敏捷开发与XP实践

    2017-2018-2 20165309实验三<Java面向对象程序设计>实验报告 一.实验内容 1. XP基础 2. XP核心实践 3. 相关工具 二.实验步骤 (一)代码规范 1.在I ...

  10. HTML(简介及常用标签)

    一.HTML简介 1.1 html是什么? 超文本标记语言(Hypertext Markup Language,HTML)通过标签语言来标记要显示的网页中的各个部分.一套规则,浏览器认识的规则. 浏览 ...