为什么是UUID做主键

什么是UUID

UUID是通用唯一识别码(Universally Unique Identifier)的缩写,是一种软件建构的标准。其目的,是让分布式系统中的所有元素都能有唯一的辨识信息,而不需要通过中央控制端来做辨识信息的指定。如此一来,每个人都可以创建不与其他人冲突的UUID。在这样的情况下,就不需考虑数据库创建时的名称重复问题。

简单地说,UUID是指在一台机器上生成的数字,它保证对在同一时空中的所有机器都是唯一的。在UUID的算法中,可能会用到诸如网卡MAC地址,IP,主机名,进程ID等信息以保证其独立性。

组成

  1. 当前日期和时间。UUID的第一个部分与时间有关,如果在生成一个UUID后,过几秒又生成一个UUID,则第一个部分不同,其余相同。
  2. 时钟序列。
  3. 全局唯一的IEEE机器识别号。如果有网卡,从网卡MAC地址获得,没有网卡以其他方式获得。

编码规则

UUID全局唯一标识符,定义为一个字符串主键,采用32位数字组成,编码采用16进制,定义了在时间和空间都完全唯一的系统信息。

UUID的编码规则:

  1. 1~8位采用系统时间,在系统时间上精确到毫秒级保证时间上的唯一性;
  2. 9~16位采用底层的IP地址,在服务器集群中的唯一性;
  3. 17~24位采用当前对象的HashCode值,在一个内部对象上的唯一性;
  4. 25~32位采用调用方法的一个随机数,在一个对象内的毫秒级的唯一性。

优点

  • 能够保证独立性,程序可以在不同的数据库间迁移,效果不受影响。
  • 保证生成的ID不仅是表独立的,而且是库独立的,在切分数据库时尤为重要。

缺点

  • 相对比较占内存,和 INT 相比,存储一个UUID要花费更多的空间。
  • 使用UUID后,URL显得冗长,不够友好。

Java示例

UUID来作为数据库数据表主键是非常不错的选择,保证每次生成的UUID是唯一的。

a. 生成UUID

public static void main(String[] args) {
        for(int i=0; i<10; i++){
            String uuid = UUID.randomUUID().toString().replaceAll("-", "");
            System.out.println(uuid);
        }
    }

b. 生成指定数目的UUID

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

    /**
     * 获得一个UUID 
     * @return String UUID 
     */
    public static String getUUID(){
        String uuid = UUID.randomUUID().toString();
        //去掉“-”符号 
        return uuid.replaceAll("-", "");
    }