因为产品要兼容多个数据库,所以想在表结构设计中不采取主键自增长。不想通过数据库查询,直接在程序中手动设置自增长的ID。如果使用时间函数到能生成唯一的key,但是这个key 太长了,大家有什么好的主键生成器方法呢? 

解决方案 »

  1.   

    多长算长,把时间转为lang型的可以吗
      

  2.   

    是长了点儿,但是没什么不方便吧?
    UUID应该是比较好的选择了。
      

  3.   

    时间能不作为主键,因为在性能高的时候,1 秒钟可以插入成千上万的数据。如果不能用自增的话,看看该数据库是否支持 Sequence,如果不支持的话,建议使用 UUID
      

  4.   

    另外,需要指出的是如果要兼容多种数据库而不设自增的话,那基本上是白搭,因为不同的数据库,连数据类型都是不一样的,比如 SQLServer、MySQL 用的是 varchar,而 Oracle 用的是 varchar2。因此仅仅是为了兼容数据库而不使用自增或者序列的话,那这个理由是很牵强的!
      

  5.   

    如果程序自己生成,用单例模式,每次返回一个主键。当时的做法很简单,主键定义是12位的,最大值为FFFFF
    FFFFFFF,用数字+字母的方式。也就是自己设计一个编码,最大值为12个F,小写字母最大为12个小写f,数字最大为12个9.
      

  6.   

    最近刚研究jdbc 想问lz你怎么在数据库中查询你建立的数据库。谢谢
      

  7.   

    说兼容多个数据库,仅仅是让主键ID兼容?还真不明白lz实质上想要表达什么意思.
      

  8.   

    非常感谢大家的说明!嗯,我采用了Hibernate的UUID的原理进行自定义生成主键了!感觉还可以!不错。有需要研究的可以参考一下这个例子。
    import java.net.*; 
    class UUIDHexGenerator { private String sep = ""; 
    private static final int IP; 
    private static short counter = (short) 0; 
    private static final int JVM = (int) (System.currentTimeMillis() >>>8); //取得jvm 启动时的当前毫秒数。无符号右移8位private static UUIDHexGenerator uuidgen = new UUIDHexGenerator(); static { 
    int ipadd; 
    try { 
    ipadd = toInt(InetAddress.getLocalHost().getAddress()); 
    } catch (Exception e) { 
    ipadd = 0; 

    IP = ipadd; //获取客户端的ip。
    } public static UUIDHexGenerator getInstance() { 
    return uuidgen; 

    // 字节转化成int型
    public static int toInt(byte[] bytes) { 
    int result = 0; 
    for (int i = 0; i < 4; i++) { 
    result = (result << 8) - Byte.MIN_VALUE + (int) bytes[i];   

    return result; 

    //整形的数字进行16进行化,然后在进行字符串转化
    protected String format(int intval) { 
    String formatted = Integer.toHexString(intval); 
    StringBuffer buf = new StringBuffer("00000000"); 
    buf.replace(8 - formatted.length(), 8, formatted); 
    return buf.toString(); 

    //短整形的数字进行16进行化,然后在进行字符串转化
    protected String format(short shortval) { 
    String formatted = Integer.toHexString(shortval); 
    StringBuffer buf = new StringBuffer("0000"); 
    buf.replace(4 - formatted.length(), 4, formatted); 
    return buf.toString(); 
    } protected int getJVM() { 
    return JVM; 

    //获取计数器数值
    protected synchronized short getCount() { 
    if (counter < 0) { 
    counter = 0; 

    return counter++; 
    } protected int getIP() { 
    return IP; 

    //获取当前时间毫秒数短整形
    protected short getHiTime() { 
    return (short) (System.currentTimeMillis() >>> 32); 

    //获取当前时间毫秒数长整型
    protected int getLoTime() { 
    return (int) System.currentTimeMillis(); 

    //获的各字符串相加组合。
    public String generate() { 
    return new StringBuffer(36) 
    .append(format(getIP())) 
    .append(sep) 
    .append(format(getJVM())) 
    .append(sep) 
    .append(format(getHiTime())) 
    .append(sep) 
    .append(format(getLoTime())) 
    .append(sep) 
    .append(format(getCount())) 
    .toString(); 
    }
      

  9.   

    获取主键只是其中的一个功能实现。我们的项目中并不采用Hibernate的架构,可能会使用ibatis。而且数据库不仅仅就局限于oracle ,mysql,sqlserver。还有一些自己开发出来的数据库。那么这些数据库就和他们有很大的不同。主键这块只是其中要考虑的一部分而以。