mysql 自增id和UUID做主键性能分析,及最优方案

UUID

UUID 是 通用唯一识别码(Universally Unique Identifier)的缩写,是一种软件建构的标准,亦为开放软件基金会组织在分布式计算环境领域的一部分。其目的,是让分布式系统中的所有元素,都能有唯一的辨识信息,而不需要通过中央控制端来做辨识信息的指定。如此一来,每个人都可以创建不与其它人冲突的UUID。在这样的情况下,就不需考虑数据库创建时的名称重复问题。目前最广泛应用的UUID,是微软公司全局唯一标识符GUID),而其他重要的应用,则有Linux ext2/ext3文件系统、LUKS加密分区、GNOME、KDE、Mac OS X等等。另外我们也可以在e2fsprogs包中的UUID库找到实现。

Java

import java.util.UUID;

public class guid {

/**

* @param args

*/

public static void main(String[] args) {

// TODO Auto-generated method stub

UUID uuid = UUID.randomUUID();

System.out.println(".{"+uuid.toString()+"}");

}

}

组成

UUID是指在一台机器上生成的数字,它保证对在同一时空中的所有机器都是唯一的。通常平台会提供生成的API。按照开放软件基金会(OSF)制定的标准计算,用到了以太网卡地址、纳秒级时间、芯片ID码和许多可能的数字

UUID由以下几部分的组合:

(1)当前日期和时间,UUID的第一个部分与时间有关,如果你在生成一个UUID之后,过几秒又生成一个UUID,则第一个部分不同,其余相同。

(2)时钟序列。

(3)全局唯一的IEEE机器识别号,如果有网卡,从网卡MAC地址获得,没有网卡以其他方式获得。

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-xxxx-xxxxxxxxxxxx (8-4-4-4-12),可以从cflib 下载CreateGUID() UDF进行转换。

1.为什么要使用uuid做主键

(1).其实在innodb存储引擎下,自增长的id做主键性能已经达到了最佳。不论是存储和读取速度都是最快的,而且占的存储空间也是最小。

(2).但是在我们实际到项目中会碰到问题,历史数据表的主键id会与数据表的id重复,两张自增id做主键的表合并时,id一定会有冲突,但如果各自的id还关联了其他表,这就很不好操作。

(3).如果使用UUID,生成的ID不仅是表独立的,而且是库独立的。对以后的数据操作很有好处,可以说一劳永逸。

2.UUID优缺点

缺点: 1. 影响插入速度, 并且造成硬盘使用率低 
2. uuid之间比较大小相对数字慢不少, 影响查询速度。 
3. uuid占空间大, 如果你建的索引越多, 影响越严重

优点:出现数据拆分、合并存储的时候,能达到全局的唯一性

3.最优方案

(1).InnoDB引擎表是基于B+树的索引组织表。

(2).B+树:B+树是为磁盘或其他直接存取辅助设备而设计的一种平衡查找树,在B+树中,所有记录节点都是按键值的大小顺序存放在同一层的叶节点中,各叶节点指针进行连接。

(3).InnoDB主索引:叶节点包含了完整的数据记录。这种索引叫做聚集索引。InnoDB 的索引能提供一种非常快速的主键查找性能。不过,它的辅助索引也会包含主键列,所以,如果主键定义的比较大,其他索引也将很大。如果想在表上定义 、很多索引,则争取尽量把主键定义得小一些。InnoDB 不会压缩索引

(4).聚集索引这种实现方式使得按主键的搜索十分高效,但是辅助索引搜索需要检索两遍索引:首先检索辅助索引获得主键,然后用主键到主索引中检索获得记录。

综合上述可得:

(1).如果InnoDB表的数据写入顺序能和B+树索引的叶子节点顺序一致的话,这时候存取效率是最高的。为了存储和查询性能应该使用自增长id做主键。

(2).对于InnoDB的主索引,数据会按照主键进行排序,由于UUID的无序性,InnoDB会产生巨大的IO压力,此时不适合使用UUID做物理主键,可以把它作为逻辑主键,物理主键依然使用自增ID。为了全局的唯一性,应该用uuid做索引关联其他表或做外键。

4.如果非要使用uuid做主键,下面是小建议:

如果是主从即M-S模式,最好是不使用mysql自带函数uuid来生成唯一主键,因为主表生成的uuid要再关联从表时,需要再去数据库查出这个uuid,需要多进行一次数据库交互,而且在这个时间差里面主表很有可能还有数据生成,这样就很容易导致关联的uuid出错。如果真要使用uuid,可以在Java中生成后,直接存储到DB里,这时主从的uuid就是一样的了!

猜你喜欢

转载自my.oschina.net/wuweixiang/blog/1796599
今日推荐