数据库主键为什么要用递增的序列?UUID为什么不适合做主键?

Posted 阿壮Jonsson

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据库主键为什么要用递增的序列?UUID为什么不适合做主键?相关的知识,希望对你有一定的参考价值。

数据库主键为什么要用递增的序列?

顺序的ID占用的空间比随机ID占用的空间小。
原因是数据库主键和索引索引使用B+树的数据结构进行存储,顺序ID数据存储在最后一个节点的最后的位置,前面的节点数据都是满的。随机ID存储时可能会出现节点分裂,导致节点多了,但是每个节点的数据量少了,存储到文件系统中时,无论节点中数据是不是满的都会占用一页的空间。所以所导致空间占用较大。

作为主键的要求

  1. 顺序
  2. 唯一
  3. 能短则短,减少空间占用

自增的ID可以满足大部分业务场景,但是在一些特殊场景中并不合适,只举部分例子

  1. 分布式系统中
  2. 分库分表的数据库设计
  3. 存在一些安全问题,对于一些敏感信息容易被推测。

UUID为什么不适合做主键?

UUID值由本机Mac地址和时间戳等因素决定,UUID出现重复概率极几乎可以忽略不计。

如果需求是只保证唯一性,那么UUID也是可以使用的,但是按照上面的分布式id的要求, UUID其实是不能做成分布式id的,原因如下:

  1. 首先分布式id一般都会作为主键,但是mysql官方推荐主键要尽量越短越好,UUID每一个都很长,所以不是很推荐
  2. 既然分布式id是主键,然后主键是包含索引的,然后mysql的索引是通过b+树来实现的,每一次新的UUID数据的插入,为了查询的优化,都会对索引底层的b+树进行修改,因为UUID数据是无序的,所以每一次UUID数据的插入都会对主键地城的b+树进行很大的修改,这一点很不好
  3. 信息不安全:基于MAC地址生成UUID的算法可能会造成MAC地址泄露,这个漏洞曾被用于寻找梅丽莎病毒的制作者位置。

Java中的UUID

package com.one.util;
import java.util.UUID;
public class Test {
    public static void main(String[] args) {
        String uuid= UUID.randomUUID().toString().replace("-", "").toLowerCase();
        System.out.println("UUID的值是:"+uuid);
    }
}

以上是关于数据库主键为什么要用递增的序列?UUID为什么不适合做主键?的主要内容,如果未能解决你的问题,请参考以下文章

Mysql什么时候建索引什么时候不适合建索引

为啥不能用 uuid 做 MySQL 的主键!?

使用雪花id或uuid作为Mysql主键,被老板怼了一顿!

序列生成的主键似乎不适用于 select 语句

聊聊用 UUID/GUID 作为主键那些坑

innodb 存储引擎为啥要用一个自增的主键