目录
问题提出
建表时一般是 id 作为主键,并且 id 字段的数据类型为 long类型,如果是varchar类型(uuid),是否可以呢?
主键为varhcar类型演示
随机生成三个uuid
public static void main(String[] args) {
try {
for (int i = 0; i <3 ; i++) {
String aa = UUID.randomUUID().toString();
System.out.println(aa);
System.out.println(aa.hashCode());
}
}catch (Exception e){
e.printStackTrace();
}
}
输出结果如下
7fe7db3d-fe29-45c2-8612-91821978fb5e
9ae9c364-c9cd-4520-ba0a-38ef84762207
3fd22fc1-723c-404b-a038-5409c5d6e29d
创建表并插入数据
CREATE TABLE `tb_test` (
`id` varchar(100) NOT NULL COMMENT '主键',
`content` varchar(255) DEFAULT NULL COMMENT '内容',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
插入数据,顺序执行如下DDL语句,执行间隔几秒
INSERT INTO `tb_test` VALUES ('7fe7db3d-fe29-45c2-8612-91821978fb5e','第1条测试数据',NOW());
INSERT INTO `tb_test` VALUES ('9ae9c364-c9cd-4520-ba0a-38ef84762207','第2条测试数据',NOW());
INSERT INTO `tb_test` VALUES ('3fd22fc1-723c-404b-a038-5409c5d6e29d','第3条测试数据',NOW());
表数据如下:
数据分析
从上图中可以看到,数据的排序是有问题的.出现问题的原因是表数据排序的顺序是uuid正序排序
原因分析
1 索引的本质是数据结构,主键本身就是索引,InnoDB使用B+Tree作为索引结构,索引中的值,是主键的值,而不是数据的内存地址。B-Tree通常意味着所有的值都是按顺序存储的.
导致问题
表数据的存储是按照主键的值来排序的,这就导致一个问题,就是每次插入都要进行重新排序操作.引起不必要的内存开销
思考:如果不使用主键会怎么样?
1 清除上述表数据
2 删除主键
3 按照顺序执行并依次间隔几秒插入数据
4 得到如下数据顺序(明面上看是按照插入时间排序)
原因解释:
如果表数据引擎是innoDB,表数据文件本身就是按B+Tree组织的一个索引结构,如果没有显式指定,则MySQL系统会自动选择一个可以唯一标识数据记录的列作为主键,如果不存在这种列,则MySQL自动为InnoDB表生成一个隐含字段作为主键,这个字段长度为6个字节,类型为长整形。