数据库主键为什么要用递增的序列?
顺序的ID占用的空间比随机ID占用的空间小。
原因是数据库主键和索引索引使用B+树的数据结构进行存储,顺序ID数据存储在最后一个节点的最后的位置,前面的节点数据都是满的。随机ID存储时可能会出现节点分裂,导致节点多了,但是每个节点的数据量少了,存储到文件系统中时,无论节点中数据是不是满的都会占用一页的空间。所以所导致空间占用较大。
作为主键的要求
- 顺序
- 唯一
- 能短则短,减少空间占用
自增的ID可以满足大部分业务场景,但是在一些特殊场景中并不合适,只举部分例子
- 分布式系统中
- 分库分表的数据库设计
- 存在一些安全问题,对于一些敏感信息容易被推测。
UUID为什么不适合做主键?
UUID值由本机Mac地址和时间戳等因素决定,UUID出现重复概率极几乎可以忽略不计。
如果需求是只保证唯一性,那么UUID也是可以使用的,但是按照上面的分布式id的要求, UUID其实是不能做成分布式id的,原因如下:
- 首先分布式id一般都会作为主键,但是mysql官方推荐主键要尽量越短越好,UUID每一个都很长,所以不是很推荐
- 既然分布式id是主键,然后主键是包含索引的,然后mysql的索引是通过b+树来实现的,每一次新的UUID数据的插入,为了查询的优化,都会对索引底层的b+树进行修改,因为UUID数据是无序的,所以每一次UUID数据的插入都会对主键地城的b+树进行很大的修改,这一点很不好
- 信息不安全:基于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);
}
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。