全局主键生成器  
介绍: 
相对于DB自增序列的全局主键生成器,性能更高,同时保留业务需求的业务含义, 
对于有分库分表需求的业务同时可以存储分库和分表的信息,对于高并发的互联网企业分库分表生成主键来说是一种很好的方法 

1. package
2.   
3. import
4. import
5. import
6.   
7. public class
8.       
9. public static void main(String[] args) throws
10.           
11. /**
12.          * 项目:交易单分表
13.          * 
14.          *  需求
15.          *  查询需求: 1. userId维度
16.          *           2. 产品维度
17.          *           3. 商户维度
18.          *           4. 时间区间维度
19.          *  
20.          *  预计订单量:
21.          *        一单平均10000, 一年交易额5000亿, 需要成功订单量 = 500000000000 / 10000 = 50000000 5000万订单
22.          *       购买加回款应该是1亿订单量, 所以, 单表2000万, 一年需要5张表
23.          *  
24.          *      最后扩展64库 + 64表, 共64*64 = 4096表, 4096 * 2000万 = 819亿订单够用了, 819亿 * 10000 = 8190000亿  819万亿,够用了
25.          *  
26.          *  全局唯一主键:
27.          *      15位时间戳 + 自增序号四位 + 机器后两段IP,6位 + 备用1位 + 分库信息两位 + 分表信息两位  共30位,  回款改造前
28.          *      15位时间戳 + 自增序号四位 + 机器后两段IP,6位 + 备用3位 + 分库信息两位 + 分表信息两位  共32位,  回款改造后
29.          *      
30.          *      单JVM支持最多1s  1000 * 9999 = 9999000, 999万9千笔订单,后续还可以扩展。
31.          *  
32.          *  分库规则:
33.          *      寻找到数据库  (userId/100) % 64 + 1 找到数据库    订单最多64个库    目前一个库   二分法裂变扩容
34.          *  分表规则:
35.          *      寻找到表信息  userId % 64 + 1 找到表信息    一个库最多64个表   目前分8张表    以后二分法裂变扩容
36.          *  
37.          *  迁移规则:
38.          *      迁移方案同步写, 目前用动态表名, 以后分表中间件稳定后, 迁移过去
39.          *  
40.          *  查询改造:
41.          *      原接口不变,对用户无感知, 底层钩子遍历
42.          */
43.   
44. // 只获取本地局域网IP即可
45.         String ip = InetAddress.getLocalHost().getHostAddress();  
46. "\\.");  
47.   
48. final String lastTwoPhaseIp = StringUtils.rightPad(ipArray[2], 3, '0')  
49. 3], 3, '0');  
50.           
51. for (int i = 0; i < 100000; i++) {  
52. new Thread(new
53.                   
54. @Override
55. public void
56. // TSS commons工具类
57.                     String tss = TSS.getTimeStampSequence();  
58. "000" + "01" + "08";  
59.                     System.out.println(id);  
60.                 }  
61.             }).start();  
62.         }  
63.     }  
64.       
65. }  
 

 
 
1. package
2.   
3. import
4.   
5. import
6. import
7. import
8. import
9. import
10. import
11. import
12. import
13. import
14.   
15. /**
16.  * 时间戳序列器<br>
17.  * 
18.  * 支持同一毫秒最多生成9999笔序列号<br>
19.  * @author sanfeng
20.  *
21.  * 想象力就是生产力
22.  */
23. public class
24.   
25. // 默认1个大小
26. private static
27. new HashMap<String, AtomicInteger>(1);  
28.       
29. private static final ReentrantLock lock = new
30.   
31. // 因为有锁,所以是变成了线程安全的,省去每次 new 的消耗,耗时降低约一半
32. private static final SimpleDateFormat sdf = new SimpleDateFormat("yyMMddHHmmssSSS");  
33.       
34. public static
35.           
36. null;  
37. null;  
38.           
39.         lock.lock();  
40. try
41.               
42. new
43.             AtomicInteger value = tssCache.get(timestamp);  
44. if(value == null) {  
45.                 tssCache.clear();  
46. int defaultStartValue = 0;  
47. new
48.                 inc = String.valueOf(defaultStartValue);  
49. else
50. 1));  
51.             }  
52. finally
53.             lock.unlock();  
54.         }  
55.           
56. return timestamp + StringUtils.leftPad(inc, 4, '0');  
57.     }  
58.   
59.       
60. public static void main(String[] args) throws
61.           
62. //      for (int i = 0; i < 1000; i++) {
63. //          new Thread(new Runnable() {
64. //              
65. //              @Override
66. //              public void run() {
67. //                  for (int j = 0; j < 10; j++) {
68. //                      System.out.println(TSS.getTimeStampSequence());
69. //                  }
70. //              }
71. //          }).start();
72. //      }
73.   
74.           
75. // 统计重复
76. new
77. new
78. new InputStreamReader(new FileInputStream("C:/Users/Administrator/Desktop/1.txt")));  
79.         String str = br.readLine();  
80. while(str != null) {  
81. if(set.contains(str)) {  
82.                 System.out.println(str);  
83. else
84.                 set.add(str);  
85.             }  
86.             str = br.readLine();  
87.         }  
88.   
89.         br.close();  
90.   
91.     }  
92. }