mysql数据库引擎为 “InnoDB” 时,为何不能使用uuid(或订单号)来作为主键

目录

问题提出

主键为varhcar类型演示

随机生成三个uuid

创建表并插入数据

数据分析

原因分析

导致问题

思考:如果不使用主键会怎么样?


问题提出

    建表时一般是 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个字节,类型为长整形。

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值