读书人

Java中UUID的代替方法?Oracle中系列的

发布时间: 2013-11-11 14:02:17 作者: rapoo

Java中UUID的代替方法?Oracle中系列的代替方法??
这是昨天参加复试的时候,技术问的:
一、
您有么有一种办法来代替UUID,就是说保证全球无重复!
Ps:不用说用 时间 + 随机字符,就是这么说的,技术说那也可能有重复的!
不用说 Base64或Base58,这个也是基于UUID的
现在说的是你自己创造的"UUID"
二、
Oracle中有Sequence,那么您如何在不用Sequence的情况下,做出类似Sequence的效果呢?比方说我当前的最大Id是5,那么下一个应该就是6,但是我1秒可能有上百万的数据存入,您如何实现呢 Java Oracle Sequence UUID
[解决办法]
一、除了你说的2种我想不出来,坐等答案。
二、可以自己写Sequence生成器。

我项目中用的:


import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.HashMap;
import java.util.Map;

/**
*
* <b>Note</b>: Java实现的Sequence工具
*/
public class SequenceUtil {

/**
* 单例模式
*/
private static SequenceUtil instance = new SequenceUtil();

/**
* 存放序列的MAP
*/
private Map<String, KeyInfo> keyMap = new HashMap<String, KeyInfo>(20);
private static final int POOL_SIZE = 1;

/**
* 防止外部实例化
*/
private SequenceUtil() {
}

/**
* 单例模式,获取单例
*
* @return SequenceUtils的单例对象
*/
public static SequenceUtil getInstance() {
return instance;
}

/**
* 获取下一个sequence值
*
* @param keyName
* Sequence名称
* @return 下一个Sequence键值
*/
public synchronized int getNextKeyValue(String keyName) {
KeyInfo keyInfo = null;
Integer keyObject = null;
try {
if (keyMap.containsKey(keyName)) {
keyInfo = keyMap.get(keyName);
} else {
keyInfo = new KeyInfo(keyName, POOL_SIZE);
keyMap.put(keyName, keyInfo);
}
keyObject = keyInfo.getNextKey();
} catch (SQLException e) {
e.printStackTrace();


}
return keyObject;
}
}

class KeyInfo {

/**
* 当前Sequence载体的最大值
*/
private int maxKey;

/**
* 当前Sequence的最小值
*/
private int minKey;

/**
* 下一个Sequence值
*/
private int nextKey;

/**
* Sequence缓存值
*/
private int poolSize;

/**
* Sequence的名称
*/
private String keyName;

/**
* 更新存放Sequence表的语句
*/
private static final String sql_update = "UPDATE intpub_Sequence SET KEYVALUE = KEYVALUE + ? WHERE KEYNAME = ?";

/**
* 查询Sequence表中的当前值
*/
private static final String sql_query = "SELECT KEYVALUE FROM intpub_Sequence WHERE KEYNAME = ?";

public KeyInfo(String keyName, int poolSize) throws SQLException {
this.poolSize = poolSize;
this.keyName = keyName;
retrieveFromDB();
}

public String getKeyName() {
return keyName;
}

public int getMaxKey() {
return maxKey;
}

public int getMinKey() {
return minKey;
}

public int getPoolSize() {
return poolSize;
}

/**
* 获取下一个Sequence值
*
* @return 下一个Sequence值
* @throws SQLException
*/
public synchronized int getNextKey() throws SQLException {
if (nextKey > maxKey) {
retrieveFromDB();
}
return nextKey++;
}

/**
* 执行Sequence表初始化和更新工作
*


* @throws SQLException
*/
private void retrieveFromDB() throws SQLException {

Connection conn = ConnectionPool.getInstance().getConnection();
// 查询数据库
PreparedStatement pstmt_query = conn.prepareStatement(sql_query);
pstmt_query.setString(1, keyName);
ResultSet rs = pstmt_query.executeQuery();
if (rs.next()) {
maxKey = rs.getInt(1) + poolSize;
minKey = maxKey - poolSize + 1;
nextKey = minKey;
rs.close();
pstmt_query.close();
} else {
String init_sql = "INSERT INTO intpub_Sequence(KEYNAME,KEYVALUE) VALUES('"
+ keyName + "',10000 + " + poolSize + ")";
Statement stmt = conn.createStatement();
stmt.executeUpdate(init_sql);
maxKey = 10000 + poolSize;
minKey = maxKey - poolSize + 1;
nextKey = minKey;
stmt.close();
return;
}

// 更新数据库
conn.setAutoCommit(false);
PreparedStatement pstmt_up = conn.prepareStatement(sql_update);
pstmt_up.setLong(1, poolSize);
pstmt_up.setString(2, keyName);
pstmt_up.executeUpdate();
pstmt_up.close();
conn.commit();

rs.close();
pstmt_query.close();
conn.close();
}

}


[解决办法]
推荐一下,看看第一题的答案!
[解决办法]
使用MONGODB的ObjectID算法吧,目前为止我遇到的最优雅的ID生成策略....
[解决办法]
引用:
Quote: 引用:

使用MONGODB的ObjectID算法吧,目前为止我遇到的最优雅的ID生成策略....



能否解释一下,我在用mongodb,但是这个id生成原理没有去研究过

为了和你解释我又回去翻了一下书,怕解释错了误导你。。
MongDB的id采用12个双字节(24个字符)来处理
0123
[解决办法]
456
[解决办法]
78
[解决办法]
91011
[解决办法]

时间戳 机器 PID 计数器
这在排序和分片上,都非常好处理,字符排序算法一般先看长度,其次从第一个字符比大小。
通过这样的设计能够很好的是这个随机码完成排序,由能通过计数器做分片,保证数据分布均匀

读书人网 >Java相关

热点推荐